public async Task ReduceVisibility_OtherUserHasView_NoUserHasInDeck_OnlyAuthor() { var db = DbHelper.GetEmptyTestDB(); var cardCreator = await UserHelper.CreateInDbAsync(db); var languageId = await CardLanguagHelper.CreateAsync(db); var otherUser = await UserHelper.CreateInDbAsync(db); var card = await CardHelper.CreateAsync(db, cardCreator, language : languageId, userWithViewIds : new[] { cardCreator, otherUser }); using (var dbContext = new MemCheckDbContext(db)) { CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, cardCreator, card.Id); CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, otherUser, card.Id); } using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForVisibilityChange(card, cardCreator.AsArray()); await new UpdateCard(dbContext.AsCallContext()).RunAsync(r); } using (var dbContext = new MemCheckDbContext(db)) { CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, cardCreator, card.Id); Assert.ThrowsException <InvalidOperationException>(() => CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, otherUser, card.Id)); } }
public async Task CheckValidityAsync(CallContext context) { QueryValidationHelper.CheckNotReservedGuid(CurrentUserId); QueryValidationHelper.CheckNotReservedGuid(CardId); await QueryValidationHelper.CheckCardExistsAsync(context.DbContext, CardId); CardVisibilityHelper.CheckUserIsAllowedToViewCards(context.DbContext, CurrentUserId, CardId); }
protected override async Task <ResultWithMetrologyProperties <ResultModel> > DoRunAsync(Request request) { var card = await DbContext.Cards .AsNoTracking() .Include(card => card.VersionCreator) .Include(card => card.Images) .ThenInclude(img => img.Image) .Include(card => card.CardLanguage) .Include(card => card.TagsInCards) .ThenInclude(tagInCard => tagInCard.Tag) .Include(card => card.UsersWithView) .ThenInclude(userWithView => userWithView.User) .Where(card => card.Id == request.CardId) .AsSingleQuery() .SingleAsync(); var userRating = await DbContext.UserCardRatings.SingleOrDefaultAsync(c => c.CardId == card.Id && c.UserId == request.CurrentUserId); int userRatingValue = userRating == null ? 0 : userRating.Rating; var ownersOfDecksWithThisCard = DbContext.CardsInDecks .AsNoTracking() .Where(cardInDeck => cardInDeck.CardId == request.CardId) .Select(cardInDeck => cardInDeck.Deck.Owner.UserName) .Distinct(); var result = new ResultModel( card.FrontSide, card.BackSide, card.AdditionalInfo, card.CardLanguage.Id, card.CardLanguage.Name, card.TagsInCards.Select(tagInCard => new ResultTagModel(tagInCard.TagId, tagInCard.Tag.Name)), card.UsersWithView.Select(userWithView => new ResultUserModel(userWithView.UserId, userWithView.User.UserName)), card.InitialCreationUtcDate, card.VersionUtcDate, card.VersionCreator.UserName, card.VersionDescription, ownersOfDecksWithThisCard, card.Images.Select(img => new ResultImageModel(img)), userRatingValue, card.AverageRating, card.RatingCount ); return(new ResultWithMetrologyProperties <ResultModel>(result, ("CardId", request.CardId.ToString()), ("CardIsPublic", CardVisibilityHelper.CardIsPublic(card.UsersWithView).ToString()), ("CardIsPrivateToSingleUser", CardVisibilityHelper.CardIsPrivateToSingleUser(request.CurrentUserId, card.UsersWithView).ToString()), ("CardAverageRating", card.AverageRating.ToString()), ("CardUserRating", userRatingValue.ToString()), ("AgeOfCurrentVersionInDays", (DateTime.UtcNow - card.VersionUtcDate).TotalDays.ToString()), ("AgeOfCardInDays", (DateTime.UtcNow - card.InitialCreationUtcDate).TotalDays.ToString()), ("CardLanguage", card.CardLanguage.Name))); }
public async Task ReduceVisibility_OtherUserHasInDeck_OtherAuthor() { var db = DbHelper.GetEmptyTestDB(); var cardCreator = await UserHelper.CreateInDbAsync(db); var languageId = await CardLanguagHelper.CreateAsync(db); var card = await CardHelper.CreateAsync(db, cardCreator, language : languageId, userWithViewIds : Array.Empty <Guid>()); var userWithCardInDeck = await UserHelper.CreateInDbAsync(db); var deck = await DeckHelper.CreateAsync(db, userWithCardInDeck); await DeckHelper.AddCardAsync(db, deck, card.Id, 0); var otherUser = await UserHelper.CreateInDbAsync(db); using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForFrontSideChange(card, RandomHelper.String(), otherUser); await new UpdateCard(dbContext.AsCallContext()).RunAsync(r); } using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForVisibilityChange(card, cardCreator.AsArray()); await Assert.ThrowsExceptionAsync <RequestInputException>(async() => await new UpdateCard(dbContext.AsCallContext()).RunAsync(r)); } using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForVisibilityChange(card, otherUser.AsArray(), otherUser); await Assert.ThrowsExceptionAsync <RequestInputException>(async() => await new UpdateCard(dbContext.AsCallContext()).RunAsync(r)); } using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForVisibilityChange(card, new[] { userWithCardInDeck }, userWithCardInDeck); await Assert.ThrowsExceptionAsync <RequestInputException>(async() => await new UpdateCard(dbContext.AsCallContext()).RunAsync(r)); } using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForVisibilityChange(card, new[] { cardCreator, otherUser, userWithCardInDeck }); await new UpdateCard(dbContext.AsCallContext()).RunAsync(r); } using (var dbContext = new MemCheckDbContext(db)) { CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, cardCreator, card.Id); CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, otherUser, card.Id); CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, userWithCardInDeck, card.Id); } }
public async Task CheckValidityAsync(CallContext callContext) { if (QueryValidationHelper.IsReservedGuid(UserId)) { throw new InvalidOperationException("Invalid user ID"); } await QueryValidationHelper.CheckUserIsOwnerOfDeckAsync(callContext.DbContext, UserId, DeckId); CardVisibilityHelper.CheckUserIsAllowedToViewCards(callContext.DbContext, UserId, CardIds); }
public async Task CheckValidityAsync(CallContext callContext) { QueryValidationHelper.CheckNotReservedGuid(UserId); if (CardIds.Any(cardId => QueryValidationHelper.IsReservedGuid(cardId))) { throw new RequestInputException($"Invalid card id"); } foreach (var cardId in CardIds) { CardVisibilityHelper.CheckUserIsAllowedToViewCards(callContext.DbContext, UserId, cardId); } await Task.CompletedTask; }
public async Task CheckValidityAsync(CallContext callContext) { if (QueryValidationHelper.IsReservedGuid(UserId)) { throw new InvalidOperationException("Invalid user ID"); } var user = await callContext.DbContext.Users.SingleAsync(u => u.Id == UserId); var cardVersion = await callContext.DbContext.CardPreviousVersions.Include(v => v.UsersWithView).SingleAsync(v => v.Id == VersionId); if (!CardVisibilityHelper.CardIsVisibleToUser(UserId, cardVersion.UsersWithView.Select(uwv => uwv.AllowedUserId))) { throw new InvalidOperationException("Original not visible to user"); } }
public async Task CheckValidityAsync(CallContext callContext) { await QueryValidationHelper.CheckUserExistsAsync(callContext.DbContext, UserId); if (CardIds.Any(cardId => QueryValidationHelper.IsReservedGuid(cardId))) { throw new RequestInputException($"Invalid card id"); } CardVisibilityHelper.CheckUserIsAllowedToViewCards(callContext.DbContext, UserId, CardIds.ToArray()); foreach (var cardId in CardIds) { await CheckUsersWithCardInADeckAsync(cardId, callContext.DbContext, callContext.Localized); await CheckCardVersionsCreatorsAsync(cardId, callContext.DbContext, callContext.Localized); } }
public async Task CheckValidityAsync(CallContext callContext) { //We allow viewing the history of a card as soon as the user can access the current version of the card. Of course the differ will refuse to give details to a user not allowed QueryValidationHelper.CheckNotReservedGuid(UserId); QueryValidationHelper.CheckNotReservedGuid(CardId); var user = await callContext.DbContext.Users.SingleAsync(u => u.Id == UserId); var card = await callContext.DbContext.Cards.Include(v => v.UsersWithView).SingleAsync(v => v.Id == CardId); if (!CardVisibilityHelper.CardIsVisibleToUser(UserId, card.UsersWithView)) { throw new InvalidOperationException("Current not visible to user"); } }
public async Task ReduceVisibility_NoUserHasInDeck_OtherAuthor() { var db = DbHelper.GetEmptyTestDB(); var cardCreatorName = RandomHelper.String(); var cardCreator = await UserHelper.CreateInDbAsync(db, userName : cardCreatorName); var languageId = await CardLanguagHelper.CreateAsync(db); var card = await CardHelper.CreateAsync(db, cardCreator, language : languageId, userWithViewIds : Array.Empty <Guid>()); var newVersionCreatorName = RandomHelper.String(); var newVersionCreator = await UserHelper.CreateInDbAsync(db, userName : newVersionCreatorName); using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForFrontSideChange(card, RandomHelper.String(), newVersionCreator); await new UpdateCard(dbContext.AsCallContext()).RunAsync(r); } using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForVisibilityChange(card, cardCreator.AsArray(), cardCreator); var e = await Assert.ThrowsExceptionAsync <RequestInputException>(async() => await new UpdateCard(dbContext.AsCallContext()).RunAsync(r)); Assert.IsTrue(e.Message.Contains(newVersionCreatorName)); } using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForVisibilityChange(card, new[] { newVersionCreator }, newVersionCreator); var e = await Assert.ThrowsExceptionAsync <RequestInputException>(async() => await new UpdateCard(dbContext.AsCallContext()).RunAsync(r)); Assert.IsTrue(e.Message.Contains(cardCreatorName)); } using (var dbContext = new MemCheckDbContext(db)) { var r = UpdateCardHelper.RequestForVisibilityChange(card, new[] { cardCreator, newVersionCreator }); await new UpdateCard(dbContext.AsCallContext()).RunAsync(r); } using (var dbContext = new MemCheckDbContext(db)) { CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, cardCreator, card.Id); CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, newVersionCreator, card.Id); } }
public async Task <ImmutableArray <CardVersion> > RunAsync(Guid userId) { var chrono = Stopwatch.StartNew(); var cardVersions = await callContext.DbContext.Cards .Include(card => card.VersionCreator) .Include(card => card.UsersWithView) .Join(callContext.DbContext.CardNotifications.Where(cardNotif => cardNotif.UserId == userId), card => card.Id, cardNotif => cardNotif.CardId, (card, cardNotif) => new { card, cardNotif }) .Where(cardAndNotif => cardAndNotif.card.VersionUtcDate > cardAndNotif.cardNotif.LastNotificationUtcDate) .ToListAsync(); performanceIndicators.Add($"{GetType().Name} took {chrono.Elapsed} to list user's registered cards with new versions"); chrono.Restart(); var result = cardVersions.Select(cardToReport => new CardVersion( cardToReport.card.Id, cardToReport.card.FrontSide, cardToReport.card.VersionCreator.UserName, cardToReport.card.VersionUtcDate, cardToReport.card.VersionDescription, CardVisibilityHelper.CardIsVisibleToUser(userId, cardToReport.card.UsersWithView), GetCardVersionOn(cardToReport.card.Id, cardToReport.cardNotif.LastNotificationUtcDate) ) ).ToImmutableArray(); performanceIndicators.Add($"{GetType().Name} took {chrono.Elapsed} to create the result list with getting card version on last notif"); chrono.Restart(); foreach (var cardVersion in cardVersions) { cardVersion.cardNotif.LastNotificationUtcDate = runningUtcDate; } await callContext.DbContext.SaveChangesAsync(); performanceIndicators.Add($"{GetType().Name} took {chrono.Elapsed} to update user's registered cards last notif date"); callContext.TelemetryClient.TrackEvent("UserCardVersionsNotifier", ("ResultCount", result.Length.ToString())); return(result); }
public async Task CheckValidityAsync(CallContext callContext) { if (!CardIds.Any()) { throw new RequestInputException("No card to add label to"); } if (QueryValidationHelper.IsReservedGuid(VersionCreator.Id)) { throw new RequestInputException("Invalid user id"); } if (QueryValidationHelper.IsReservedGuid(TagId)) { throw new RequestInputException("Reserved tag id"); } foreach (var cardId in CardIds) { CardVisibilityHelper.CheckUserIsAllowedToViewCards(callContext.DbContext, VersionCreator.Id, cardId); } if (!await callContext.DbContext.Tags.Where(tag => tag.Id == TagId).AnyAsync()) { throw new RequestInputException("Invalid tag id"); } }
public static void AssertSameUserWithViewSet(IEnumerable <UserWithViewOnCard> cardAllowedUsers, IEnumerable <UserWithViewOnCardPreviousVersion> cardPreviousVersionAllowedUsers) { Assert.IsTrue(CardVisibilityHelper.CardsHaveSameUsersWithView(cardAllowedUsers, cardPreviousVersionAllowedUsers)); }
public async Task UpdateAllFields() { var db = DbHelper.GetEmptyTestDB(); var cardCreator = await UserHelper.CreateInDbAsync(db); var languageId = await CardLanguagHelper.CreateAsync(db); var originalCard = await CardHelper.CreateAsync(db, cardCreator, language : languageId, userWithViewIds : Array.Empty <Guid>()); var newVersionCreator = await UserHelper.CreateInDbAsync(db); var frontSide = RandomHelper.String(); var backSide = RandomHelper.String(); var additionalInfo = RandomHelper.String(); var versionDescription = RandomHelper.String(); var newLanguageId = await CardLanguagHelper.CreateAsync(db); var imageOnFrontSideId = await ImageHelper.CreateAsync(db, cardCreator); var imageOnBackSide1Id = await ImageHelper.CreateAsync(db, cardCreator); var imageOnBackSide2Id = await ImageHelper.CreateAsync(db, cardCreator); var imageOnAdditionalInfoId = await ImageHelper.CreateAsync(db, cardCreator); var tagId = await TagHelper.CreateAsync(db); using (var dbContext = new MemCheckDbContext(db)) { var request = new UpdateCard.Request( originalCard.Id, newVersionCreator, frontSide, new Guid[] { imageOnFrontSideId }, backSide, new Guid[] { imageOnBackSide1Id, imageOnBackSide2Id }, additionalInfo, new Guid[] { imageOnAdditionalInfoId }, languageId, new Guid[] { tagId }, new Guid[] { cardCreator, newVersionCreator }, versionDescription); await new UpdateCard(dbContext.AsCallContext()).RunAsync(request); } using (var dbContext = new MemCheckDbContext(db)) { var updatedCard = dbContext.Cards .Include(c => c.VersionCreator) .Include(c => c.CardLanguage) .Include(c => c.UsersWithView) .Include(c => c.Images) .Include(c => c.TagsInCards) .Single(c => c.Id == originalCard.Id); Assert.AreEqual(newVersionCreator, updatedCard.VersionCreator.Id); Assert.AreEqual(frontSide, updatedCard.FrontSide); Assert.AreEqual(backSide, updatedCard.BackSide); Assert.AreEqual(additionalInfo, updatedCard.AdditionalInfo); Assert.AreEqual(versionDescription, updatedCard.VersionDescription); Assert.AreEqual(languageId, updatedCard.CardLanguage.Id); Assert.AreEqual(ImageInCard.FrontSide, updatedCard.Images.Single(i => i.ImageId == imageOnFrontSideId).CardSide); Assert.AreEqual(ImageInCard.BackSide, updatedCard.Images.Single(i => i.ImageId == imageOnBackSide1Id).CardSide); Assert.AreEqual(ImageInCard.BackSide, updatedCard.Images.Single(i => i.ImageId == imageOnBackSide2Id).CardSide); Assert.AreEqual(ImageInCard.AdditionalInfo, updatedCard.Images.Single(i => i.ImageId == imageOnAdditionalInfoId).CardSide); Assert.IsTrue(updatedCard.TagsInCards.Any(t => t.TagId == tagId)); } using (var dbContext = new MemCheckDbContext(db)) { CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, cardCreator, originalCard.Id); CardVisibilityHelper.CheckUserIsAllowedToViewCards(dbContext, newVersionCreator, originalCard.Id); } }
protected override async Task <ResultWithMetrologyProperties <Result> > DoRunAsync(Request request) { var current = await DbContext.Cards .Include(c => c.CardLanguage) .Include(c => c.TagsInCards) .ThenInclude(t => t.Tag) .Include(c => c.Images) .ThenInclude(i => i.Image) .SingleAsync(c => c.Id == request.CurrentCardId); var original = await DbContext.CardPreviousVersions .Include(c => c.CardLanguage) .Include(c => c.Tags) .ThenInclude(t => t.Tag) .Include(c => c.Images) .ThenInclude(i => i.Image) .SingleAsync(c => c.Id == request.OriginalVersionId); var result = new Result(current.VersionCreator.UserName, original.VersionCreator.UserName, current.VersionUtcDate, original.VersionUtcDate, current.VersionDescription, original.VersionDescription); if (current.FrontSide != original.FrontSide) { result = result with { FrontSide = new(current.FrontSide, original.FrontSide) } } ; if (current.BackSide != original.BackSide) { result = result with { BackSide = new(current.BackSide, original.BackSide) } } ; if (current.AdditionalInfo != original.AdditionalInfo) { result = result with { AdditionalInfo = new(current.AdditionalInfo, original.AdditionalInfo) } } ; if (current.CardLanguage != original.CardLanguage) { result = result with { Language = new(current.CardLanguage.Name, original.CardLanguage.Name) } } ; if (!Enumerable.SequenceEqual(current.TagsInCards.Select(t => t.Tag.Name).OrderBy(tagName => tagName), original.Tags.Select(t => t.Tag.Name).OrderBy(tagName => tagName))) { var currentTags = string.Join(",", current.TagsInCards.Select(t => t.Tag.Name).OrderBy(tagName => tagName)); var originalTags = string.Join(",", original.Tags.Select(t => t.Tag.Name).OrderBy(tagName => tagName)); result = result with { Tags = new(currentTags, originalTags) }; } if (!CardVisibilityHelper.CardsHaveSameUsersWithView(current.UsersWithView, original.UsersWithView)) { var currentUsers = string.Join(",", current.UsersWithView.Select(u => u.User.UserName).OrderBy(userName => userName)); var originalUserIds = original.UsersWithView.Select(u => u.AllowedUserId).ToHashSet(); var originalUserNames = DbContext.Users.Where(u => originalUserIds.Contains(u.Id)).Select(u => u.UserName); var originalUsers = string.Join(",", originalUserNames.OrderBy(userName => userName)); result = result with { UsersWithView = new(currentUsers, originalUsers) }; } if (!ComparisonHelper.SameSetOfGuid(current.Images.Where(i => i.CardSide == ImageInCard.FrontSide).Select(i => i.ImageId), original.Images.Where(i => i.CardSide == ImageInCard.FrontSide).Select(i => i.ImageId))) { var currentImages = string.Join(",", current.Images.Where(i => i.CardSide == ImageInCard.FrontSide).Select(i => i.Image.Name).OrderBy(imageName => imageName)); var originalImages = string.Join(",", original.Images.Where(i => i.CardSide == ImageInCard.FrontSide).Select(i => i.Image.Name).OrderBy(imageName => imageName)); result = result with { ImagesOnFrontSide = new(currentImages, originalImages) }; } if (!ComparisonHelper.SameSetOfGuid(current.Images.Where(i => i.CardSide == ImageInCard.BackSide).Select(i => i.ImageId), original.Images.Where(i => i.CardSide == ImageInCard.BackSide).Select(i => i.ImageId))) { var currentImages = string.Join(",", current.Images.Where(i => i.CardSide == ImageInCard.BackSide).Select(i => i.Image.Name).OrderBy(imageName => imageName)); var originalImages = string.Join(",", original.Images.Where(i => i.CardSide == ImageInCard.BackSide).Select(i => i.Image.Name).OrderBy(imageName => imageName)); result = result with { ImagesOnBackSide = new(currentImages, originalImages) }; } if (!ComparisonHelper.SameSetOfGuid(current.Images.Where(i => i.CardSide == ImageInCard.AdditionalInfo).Select(i => i.ImageId), original.Images.Where(i => i.CardSide == ImageInCard.AdditionalInfo).Select(i => i.ImageId))) { var currentImages = string.Join(",", current.Images.Where(i => i.CardSide == ImageInCard.AdditionalInfo).Select(i => i.Image.Name).OrderBy(imageName => imageName)); var originalImages = string.Join(",", original.Images.Where(i => i.CardSide == ImageInCard.AdditionalInfo).Select(i => i.Image.Name).OrderBy(imageName => imageName)); result = result with { ImagesOnAdditionalSide = new(currentImages, originalImages) }; } return(new ResultWithMetrologyProperties <Result>(result, ("CurrentCardId", request.CurrentCardId.ToString()), ("OriginalVersionId", request.OriginalVersionId.ToString()))); }