Files
step3/api/QuestionsApi.Tests/FlashcardCsvTests.cs
hz 48a8c8361d Add flashcards feature with spaced repetition scheduling
Adds a full flashcards system: FSRS-based scheduling, cloze/basic
card types, CSV import/export, media storage, and study UI, wired
into navigation and the dashboard alongside existing question flows.
2026-07-21 15:08:52 -05:00

76 lines
2.1 KiB
C#

using QuestionsApi.Services.Flashcards;
using Xunit;
namespace QuestionsApi.Tests;
public sealed class FlashcardCsvTests
{
[Fact]
public void ParseRows_HandlesQuotedMultilineFieldsAndEmbeddedCommas()
{
var csv = "stable_id,deck,type,prompt,answer,extra,tags,source_question_external_id\n"
+ "abc-1,Cardio,basic,\"What is the first line,\nsecond line?\",\"Answer, with comma\",,tag1;tag2,q-1\n";
var rows = FlashcardCsv.ParseRows(csv);
Assert.Equal(2, rows.Count);
var data = rows[1];
Assert.Equal("abc-1", data[0]);
Assert.Equal("What is the first line,\nsecond line?", data[3]);
Assert.Equal("Answer, with comma", data[4]);
Assert.Equal("tag1;tag2", data[6]);
}
[Fact]
public void ParseRows_HandlesEscapedDoubleQuotes()
{
var csv = "a,b\n\"she said \"\"hi\"\"\",plain\n";
var rows = FlashcardCsv.ParseRows(csv);
Assert.Equal("she said \"hi\"", rows[1][0]);
Assert.Equal("plain", rows[1][1]);
}
[Fact]
public void ParseRows_SupportsUnicodeContent()
{
var csv = "a,b\néè中文,\U0001F600\n";
var rows = FlashcardCsv.ParseRows(csv);
Assert.Equal("éè中文", rows[1][0]);
Assert.Equal("😀", rows[1][1]);
}
[Fact]
public void ParseRows_HandlesFileWithoutTrailingNewline()
{
var csv = "a,b\n1,2";
var rows = FlashcardCsv.ParseRows(csv);
Assert.Equal(2, rows.Count);
Assert.Equal(["1", "2"], rows[1]);
}
[Fact]
public void WriteRow_QuotesFieldsContainingSpecialCharacters()
{
var row = FlashcardCsv.WriteRow(["plain", "has,comma", "has\"quote", "has\nnewline"]);
Assert.Equal("plain,\"has,comma\",\"has\"\"quote\",\"has\nnewline\"", row);
}
[Fact]
public void WriteThenParse_RoundTrips()
{
var original = new[] { "id-1", "Deck, Name", "basic", "prompt with \"quotes\" and\nnewline", "answer", "", "a;b", "q-1" };
var line = FlashcardCsv.WriteRow(original);
var rows = FlashcardCsv.ParseRows("header\n" + line + "\n");
Assert.Equal(original, rows[1]);
}
}