Esempio n. 1
0
        public async Task ComplexCase()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

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

            await CardSubscriptionHelper.CreateAsync(db, user, registeredCard1.Id);

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

            await CardSubscriptionHelper.CreateAsync(db, user, registeredCard2.Id);

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

            await CardSubscriptionHelper.CreateAsync(db, user, deletedCard.Id);

            using (var dbContext = new MemCheckDbContext(db))
                await new DeleteCards(dbContext.AsCallContext()).RunAsync(new DeleteCards.Request(user, deletedCard.Id.AsArray()));

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

            using (var dbContext = new MemCheckDbContext(db))
            {
                var result = new CardRegistrationsLoader(dbContext).RunForCardIds(user, new[] { registeredCard1.Id, registeredCard2.Id, deletedCard.Id, nonRegisteredCard.Id });
                Assert.AreEqual(4, result.Count);
                Assert.IsTrue(result[registeredCard1.Id]);
                Assert.IsTrue(result[registeredCard2.Id]);
                Assert.IsTrue(result[deletedCard.Id]);
                Assert.IsFalse(result[nonRegisteredCard.Id]);
            }
        }
Esempio n. 2
0
        private async Task <IEnumerable <ResultCard> > RunForHeapAsync(Request request, HeapingAlgorithm heapingAlgorithm, ImmutableDictionary <Guid, string> userNames, ImmutableDictionary <Guid, string> imageNames, ImmutableDictionary <Guid, string> tagNames, DateTime now, int heap, int maxCount)
        {
            var cardsOfHeap = DbContext.CardsInDecks.AsNoTracking()
                              .Include(cardInDeck => cardInDeck.Card)
                              .Where(cardInDeck => cardInDeck.DeckId == request.DeckId && cardInDeck.CurrentHeap == heap)
                              .Where(cardInDeck => !request.ExcludedCardIds.Contains(cardInDeck.CardId))
                              .Where(cardInDeck => !cardInDeck.Card.TagsInCards.Any(tag => request.ExcludedTagIds.Contains(tag.TagId)))
                              .Where(cardInDeck => cardInDeck.ExpiryUtcTime <= now)
                              .OrderBy(cardInDeck => cardInDeck.ExpiryUtcTime)
                              .Take(maxCount)
                              .AsSingleQuery()
                              .Select(cardInDeck => new
            {
                cardInDeck.CardId,
                cardInDeck.CurrentHeap,
                cardInDeck.LastLearnUtcTime,
                cardInDeck.AddToDeckUtcTime,
                cardInDeck.BiggestHeapReached,
                cardInDeck.NbTimesInNotLearnedHeap,
                cardInDeck.Card.FrontSide,
                cardInDeck.Card.BackSide,
                cardInDeck.Card.AdditionalInfo,
                cardInDeck.Card.VersionUtcDate,
                VersionCreator      = cardInDeck.Card.VersionCreator.Id,
                tagIds              = cardInDeck.Card.TagsInCards.Select(tag => tag.TagId),
                userWithViewIds     = cardInDeck.Card.UsersWithView.Select(u => u.UserId),
                imageIdAndCardSides = cardInDeck.Card.Images.Select(img => new { img.ImageId, img.CardSide }),
                cardInDeck.Card.AverageRating,
                cardInDeck.Card.RatingCount,
                LanguageName = cardInDeck.Card.CardLanguage.Name
            }).ToImmutableArray();

            var notifications = new CardRegistrationsLoader(DbContext).RunForCardIds(request.CurrentUserId, cardsOfHeap.Select(c => c.CardId));

            //The following line could be improved with a joint. Not sure this would perform better, to be checked
            var userRatings = await DbContext.UserCardRatings.Where(r => r.UserId == request.CurrentUserId).Select(r => new { r.CardId, r.Rating }).ToDictionaryAsync(r => r.CardId, r => r.Rating);

            var thisHeapResult = cardsOfHeap.Select(oldestCard => new ResultCard(oldestCard.CardId, oldestCard.CurrentHeap, oldestCard.LastLearnUtcTime, oldestCard.AddToDeckUtcTime,
                                                                                 oldestCard.BiggestHeapReached, oldestCard.NbTimesInNotLearnedHeap,
                                                                                 oldestCard.FrontSide, oldestCard.BackSide, oldestCard.AdditionalInfo,
                                                                                 oldestCard.VersionUtcDate,
                                                                                 userNames[oldestCard.VersionCreator],
                                                                                 oldestCard.tagIds.Select(tagId => tagNames[tagId]),
                                                                                 oldestCard.userWithViewIds.Select(userWithView => userNames[userWithView]),
                                                                                 oldestCard.imageIdAndCardSides.Select(imageIdAndCardSide => new ResultImageModel(imageIdAndCardSide.ImageId, imageNames[imageIdAndCardSide.ImageId], imageIdAndCardSide.CardSide)),
                                                                                 heapingAlgorithm,
                                                                                 userRatings.ContainsKey(oldestCard.CardId) ? userRatings[oldestCard.CardId] : 0,
                                                                                 oldestCard.AverageRating,
                                                                                 oldestCard.RatingCount,
                                                                                 notifications[oldestCard.CardId],
                                                                                 oldestCard.LanguageName == "Français" //Questionable hardcoding
                                                                                 )
                                                    ).OrderBy(r => r.LastLearnUtcTime);

            return(thisHeapResult);
        }
Esempio n. 3
0
        public async Task CardDoesNotExist()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

            using var dbContext = new MemCheckDbContext(db);
            var cardId = Guid.NewGuid();
            var result = new CardRegistrationsLoader(dbContext).RunForCardIds(user, cardId.AsArray());

            Assert.AreEqual(1, result.Count);
            Assert.IsFalse(result[cardId]);
        }
Esempio n. 4
0
        public async Task CardRegistered()
        {
            var db   = DbHelper.GetEmptyTestDB();
            var user = await UserHelper.CreateInDbAsync(db);

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

            await CardSubscriptionHelper.CreateAsync(db, user, card.Id);

            using var dbContext = new MemCheckDbContext(db);
            var result = new CardRegistrationsLoader(dbContext).RunForCardIds(user, card.Id.AsArray());

            Assert.AreEqual(1, result.Count);
            Assert.IsTrue(result[card.Id]);
        }
Esempio n. 5
0
        private async Task <IEnumerable <ResultCard> > GetUnknownCardsAsync(Guid userId, Guid deckId, IEnumerable <Guid> excludedCardIds, IEnumerable <Guid> excludedTagIds, HeapingAlgorithm heapingAlgorithm, ImmutableDictionary <Guid, string> userNames, ImmutableDictionary <Guid, string> imageNames, ImmutableDictionary <Guid, string> tagNames, int cardCount, bool neverLearnt)
        {
            var cardsOfDeck = DbContext.CardsInDecks.AsNoTracking()
                              .Include(card => card.Card).AsSingleQuery()
                              .Where(card => card.DeckId.Equals(deckId) && card.CurrentHeap == 0 && !excludedCardIds.Contains(card.CardId));

            var withoutExcludedCards = cardsOfDeck;

            foreach (var tag in excludedTagIds)   //I tried to do better with an intersect between the two sets, but that failed
            {
                withoutExcludedCards = withoutExcludedCards.Where(cardInDeck => !cardInDeck.Card.TagsInCards.Where(tagInCard => tagInCard.TagId == tag).Any());
            }

            var countToTake = neverLearnt ? cardCount * 3 : cardCount; //For cards never learnt, we take more cards for shuffling accross more

            IQueryable <CardInDeck>?finalSelection;

            if (neverLearnt)
            {
                finalSelection = withoutExcludedCards.Where(cardInDeck => cardInDeck.LastLearnUtcTime == CardInDeck.NeverLearntLastLearnTime).OrderBy(cardInDeck => cardInDeck.AddToDeckUtcTime).Take(countToTake);
            }
            else
            {
                finalSelection = withoutExcludedCards.Where(cardInDeck => cardInDeck.LastLearnUtcTime != CardInDeck.NeverLearntLastLearnTime).OrderBy(cardInDeck => cardInDeck.LastLearnUtcTime).Take(countToTake);
            }

            var withDetails = finalSelection.Select(cardInDeck => new
            {
                cardInDeck.CardId,
                cardInDeck.LastLearnUtcTime,
                cardInDeck.AddToDeckUtcTime,
                cardInDeck.BiggestHeapReached,
                cardInDeck.NbTimesInNotLearnedHeap,
                cardInDeck.Card.FrontSide,
                cardInDeck.Card.BackSide,
                cardInDeck.Card.AdditionalInfo,
                cardInDeck.Card.VersionUtcDate,
                VersionCreator      = cardInDeck.Card.VersionCreator.Id,
                tagIds              = cardInDeck.Card.TagsInCards.Select(tag => tag.TagId),
                userWithViewIds     = cardInDeck.Card.UsersWithView.Select(u => u.UserId),
                imageIdAndCardSides = cardInDeck.Card.Images.Select(img => new { img.ImageId, img.CardSide }),
                cardInDeck.Card.AverageRating,
                cardInDeck.Card.RatingCount,
                LanguageName = cardInDeck.Card.CardLanguage.Name
            });

            var listed = await withDetails.ToListAsync();

            var cardIds       = listed.Select(cardInDeck => cardInDeck.CardId);
            var notifications = new CardRegistrationsLoader(DbContext).RunForCardIds(userId, cardIds);

            //The following line could be improved with a joint. Not sure this would perform better, to be checked
            var userRatings = await DbContext.UserCardRatings.Where(r => r.UserId == userId).Select(r => new { r.CardId, r.Rating }).ToDictionaryAsync(r => r.CardId, r => r.Rating);

            var result = listed.Select(cardInDeck => new ResultCard(
                                           cardInDeck.CardId,
                                           cardInDeck.LastLearnUtcTime,
                                           cardInDeck.AddToDeckUtcTime,
                                           cardInDeck.BiggestHeapReached, cardInDeck.NbTimesInNotLearnedHeap,
                                           cardInDeck.FrontSide,
                                           cardInDeck.BackSide,
                                           cardInDeck.AdditionalInfo,
                                           cardInDeck.VersionUtcDate,
                                           userNames[cardInDeck.VersionCreator],
                                           cardInDeck.tagIds.Select(tagId => tagNames[tagId]),
                                           cardInDeck.userWithViewIds.Select(userWithView => userNames[userWithView]),
                                           cardInDeck.imageIdAndCardSides.Select(imageIdAndCardSide => new ResultImageModel(imageIdAndCardSide.ImageId, imageNames[imageIdAndCardSide.ImageId], imageIdAndCardSide.CardSide)),
                                           heapingAlgorithm,
                                           userRatings.ContainsKey(cardInDeck.CardId) ? userRatings[cardInDeck.CardId] : 0,
                                           cardInDeck.AverageRating,
                                           cardInDeck.RatingCount,
                                           notifications[cardInDeck.CardId],
                                           cardInDeck.LanguageName == "Français" //Questionable hardcoding
                                           ));

            if (neverLearnt)
            {
                return(Shuffler.Shuffle(result).Take(cardCount));
            }
            else
            {
                return(result);
            }
        }