public async Task OrderingOfNeverLearnt()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user, algorithmId : DefaultHeapingAlgorithm.ID);

            var randomDate     = RandomHelper.Date();
            var cardAddedLater = await CardHelper.CreateAsync(db, user);

            await DeckHelper.AddNeverLearntCardAsync(db, deck, cardAddedLater.Id, randomDate.AddDays(1));

            for (int i = 0; i < 9; i++)
            {
                var card = await CardHelper.CreateAsync(db, user);

                await DeckHelper.AddNeverLearntCardAsync(db, deck, card.Id, randomDate);
            }

            using var dbContext = new MemCheckDbContext(db);
            var request         = new GetUnknownCardsToLearn.Request(user, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), 3);
            var downloadedCards = (await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request)).Cards.Select(c => c.CardId).ToImmutableHashSet();

            Assert.IsFalse(downloadedCards.Contains(cardAddedLater.Id));
        }
        public async Task TwoCardsWithLanguages()
        {
            var db     = DbHelper.GetEmptyTestDB();
            var french = await CardLanguagHelper.CreateAsync(db, "Français");

            var otherLanguage = await CardLanguagHelper.CreateAsync(db, RandomHelper.String());

            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user);

            var frenchCreatedCard = await CardHelper.CreateAsync(db, user, language : french);

            var otherLanguageCard = await CardHelper.CreateAsync(db, user, language : otherLanguage);

            await DeckHelper.AddNeverLearntCardAsync(db, deck, frenchCreatedCard.Id);

            await DeckHelper.AddNeverLearntCardAsync(db, deck, otherLanguageCard.Id);

            using var dbContext = new MemCheckDbContext(db);
            var request = new GetUnknownCardsToLearn.Request(user, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), 10);
            var cards   = await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request);

            Assert.IsTrue(cards.Cards.Single(card => card.CardId == frenchCreatedCard.Id).IsInFrench);
            Assert.IsFalse(cards.Cards.Single(card => card.CardId == otherLanguageCard.Id).IsInFrench);
        }
        public async Task ComplexCaseWithLessCardsThanRequested()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user, algorithmId : DeveloperHeapingAlgorithm.ID);

            const int cardCount = 10;

            for (int i = 0; i < cardCount / 2; i++)
            {
                await DeckHelper.AddNeverLearntCardAsync(db, deck, await CardHelper.CreateIdAsync(db, user));

                await DeckHelper.AddCardAsync(db, deck, await CardHelper.CreateIdAsync(db, user), 0);
            }
            using var dbContext = new MemCheckDbContext(db);
            var request = new GetUnknownCardsToLearn.Request(user, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), cardCount * 2);
            var cards   = (await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request)).Cards.ToImmutableArray();

            Assert.AreEqual(cardCount, cards.Length);
            for (int i = 1; i < cardCount / 2; i++)
            {
                Assert.AreEqual(CardInDeck.NeverLearntLastLearnTime, cards[i].LastLearnUtcTime);
            }
            for (int i = cardCount / 2; i < cards.Length; i++)
            {
                Assert.IsTrue(cards[i].LastLearnUtcTime >= cards[i - 1].LastLearnUtcTime);
            }
        }
        public async Task UnknownCardsLearnt_CheckOrder()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user, algorithmId : DeveloperHeapingAlgorithm.ID);

            const int cardCount = 100;

            for (int i = 0; i < cardCount; i++)
            {
                var card = await CardHelper.CreateAsync(db, user);

                await DeckHelper.AddCardAsync(db, deck, card.Id, 0);
            }
            using var dbContext = new MemCheckDbContext(db);
            var request = new GetUnknownCardsToLearn.Request(user, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), cardCount);
            var cards   = (await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request)).Cards.ToImmutableArray();

            Assert.AreEqual(cardCount, cards.Length);
            for (int i = 1; i < cards.Length; i++)
            {
                Assert.IsTrue(cards[i].LastLearnUtcTime >= cards[i - 1].LastLearnUtcTime);
            }
        }
        public async Task CardsNeverLearnt_NotTheSameOrderOnSuccessiveRuns()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user, algorithmId : DefaultHeapingAlgorithm.ID);

            const int cardCount = 100;

            for (int i = 0; i < cardCount; i++)
            {
                var card = await CardHelper.CreateAsync(db, user);

                await DeckHelper.AddNeverLearntCardAsync(db, deck, card.Id);
            }
            using var dbContext = new MemCheckDbContext(db);
            var request       = new GetUnknownCardsToLearn.Request(user, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), cardCount);
            var firstRunCards = (await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request)).Cards.Select(c => c.CardId).ToImmutableArray();

            Assert.AreEqual(cardCount, firstRunCards.Length);
            var secondRunCards = (await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request)).Cards.Select(c => c.CardId).ToImmutableArray();

            Assert.AreEqual(cardCount, secondRunCards.Length);
            var thirdRunCards = (await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request)).Cards.Select(c => c.CardId).ToImmutableArray();

            Assert.AreEqual(cardCount, thirdRunCards.Length);
            Assert.IsFalse(firstRunCards.SequenceEqual(secondRunCards));
            Assert.IsFalse(firstRunCards.SequenceEqual(thirdRunCards));
            Assert.IsFalse(secondRunCards.SequenceEqual(thirdRunCards));
        }
        public async Task DeckDoesNotExist()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            using var dbContext = new MemCheckDbContext(db);
            var request = new GetUnknownCardsToLearn.Request(user, Guid.NewGuid(), Array.Empty <Guid>(), Array.Empty <Guid>(), 10);
            await Assert.ThrowsExceptionAsync <InvalidOperationException>(async() => await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request));
        }
        public async Task UserNotLoggedIn()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user);

            using var dbContext = new MemCheckDbContext(db);
            var request = new GetUnknownCardsToLearn.Request(Guid.Empty, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), 10);
            await Assert.ThrowsExceptionAsync <RequestInputException>(async() => await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request));
        }
        public async Task OneNeverLearnt()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user, algorithmId : DefaultHeapingAlgorithm.ID);

            var card = await CardHelper.CreateAsync(db, user);

            await DeckHelper.AddNeverLearntCardAsync(db, deck, card.Id);

            using var dbContext = new MemCheckDbContext(db);
            var request = new GetUnknownCardsToLearn.Request(user, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), 10);
            var cards   = await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request);

            Assert.AreEqual(1, cards.Cards.Count());
        }
        public async Task OneCardToRepeat()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user, algorithmId : DefaultHeapingAlgorithm.ID);

            var card = await CardHelper.CreateAsync(db, user);

            await DeckHelper.AddCardAsync(db, deck, card.Id, 1, RandomHelper.Date());

            using var dbContext = new MemCheckDbContext(db);
            var request = new GetUnknownCardsToLearn.Request(user, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), 10);
            var cards   = await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request);

            Assert.IsFalse(cards.Cards.Any());
        }
        public async Task OneCardInFrench()
        {
            var db     = DbHelper.GetEmptyTestDB();
            var french = await CardLanguagHelper.CreateAsync(db, "Français");

            var user = await UserHelper.CreateInDbAsync(db);

            var deck = await DeckHelper.CreateAsync(db, user);

            var card = await CardHelper.CreateAsync(db, user, language : french);

            await DeckHelper.AddNeverLearntCardAsync(db, deck, card.Id);

            using var dbContext = new MemCheckDbContext(db);
            var request = new GetUnknownCardsToLearn.Request(user, deck, Array.Empty <Guid>(), Array.Empty <Guid>(), 10);
            var cards   = await new GetUnknownCardsToLearn(dbContext.AsCallContext()).RunAsync(request);

            Assert.IsTrue(cards.Cards.Single().IsInFrench);
        }