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]); } }
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); }
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]); }
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]); }
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); } }