public async Task Remove(UserReleaseRole userReleaseRole, Guid deletedById)
 {
     userReleaseRole.Deleted     = DateTime.UtcNow;
     userReleaseRole.DeletedById = deletedById;
     _contentDbContext.Update(userReleaseRole);
     await _contentDbContext.SaveChangesAsync();
 }
Ejemplo n.º 2
0
        public async Task <Either <ActionResult, Unit> > AddUserReleaseRole(Guid userId,
                                                                            UserReleaseRoleRequest userReleaseRole)
        {
            return(await _userService
                   .CheckCanManageAllUsers()
                   .OnSuccess(async() =>
            {
                return await _persistenceHelper
                .CheckEntityExists <Release>(
                    userReleaseRole.ReleaseId,
                    q => q.Include(r => r.Publication)
                    )
                .OnSuccess(release =>
                {
                    return ValidateUserReleaseRoleCanBeAdded(userId, userReleaseRole)
                    .OnSuccessVoid(async() =>
                    {
                        await ValidateUserReleaseRoleCanBeAdded(userId, userReleaseRole);

                        var newReleaseRole = new UserReleaseRole
                        {
                            ReleaseId = userReleaseRole.ReleaseId,
                            Role = userReleaseRole.ReleaseRole,
                            UserId = userId
                        };

                        await _contentDbContext.AddAsync(newReleaseRole);
                        await _contentDbContext.SaveChangesAsync();

                        SendNewReleaseRoleEmail(userId, release, newReleaseRole.Role);
                    });
                });
            }));
        }
        public async void HasRoleOnAnyChildReleaseAuthorizationHandler_NoReleasesOnThisPublicationForThisUser()
        {
            var releaseOnAnotherPublication = new Release
            {
                Id            = Guid.NewGuid(),
                PublicationId = Guid.NewGuid()
            };

            var releaseOnThisPublication = new Release
            {
                Id            = Guid.NewGuid(),
                PublicationId = _publication.Id
            };

            var releaseRoleForDifferentPublication = new UserReleaseRole
            {
                UserId  = _userId,
                Release = releaseOnAnotherPublication
            };

            var releaseRoleForDifferentUser = new UserReleaseRole
            {
                UserId  = Guid.NewGuid(),
                Release = releaseOnThisPublication
            };

            await AssertHasRoleOnAnyChildReleaseHandlesOk(
                false,
                releaseRoleForDifferentPublication,
                releaseRoleForDifferentUser);
        }
        public async Task ListReleasesForUser_ReleaseRole_Approved()
        {
            var userId           = Guid.NewGuid();
            var userReleaseRole1 = new UserReleaseRole
            {
                UserId  = userId,
                Release = new Release
                {
                    ApprovalStatus     = ReleaseApprovalStatus.Approved,
                    TimePeriodCoverage = TimeIdentifier.AcademicYear,
                    ReleaseName        = "2001",
                    Publication        = new Publication
                    {
                        Title   = "Test publication 1",
                        Slug    = "test-publication-1",
                        Contact = new Contact(),
                    },
                },
                Role = ReleaseRole.Lead,
            };
            var userReleaseRole2 = new UserReleaseRole
            {
                UserId  = userId,
                Release = new Release
                {
                    ApprovalStatus     = ReleaseApprovalStatus.Approved,
                    TimePeriodCoverage = TimeIdentifier.AcademicYear,
                    ReleaseName        = "2001",
                    Publication        = new Publication
                    {
                        Title   = "Test publication 2",
                        Slug    = "test-publication-2",
                        Contact = new Contact(),
                    },
                },
                Role = ReleaseRole.PrereleaseViewer,
            };

            var contentDbContextId = Guid.NewGuid().ToString();

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                await contentDbContext.AddRangeAsync(userReleaseRole1, userReleaseRole2);

                await contentDbContext.SaveChangesAsync();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var releaseRepository = BuildReleaseRepository(contentDbContext);
                var result            =
                    await releaseRepository.ListReleasesForUser(userId,
                                                                ReleaseApprovalStatus.Approved);

                Assert.Single(result);
                Assert.Equal(userReleaseRole1.ReleaseId, result[0].Id);
            }
        }
 private static void AssertAmendedReleaseRoleCorrect(UserReleaseRole previous, UserReleaseRole amended,
                                                     Release amendment)
 {
     Assert.NotEqual(previous.Id, amended.Id);
     Assert.Equal(amendment, amended.Release);
     Assert.Equal(amendment.Id, amended.ReleaseId);
     Assert.Equal(previous.UserId, amended.UserId);
     Assert.Equal(previous.Role, amended.Role);
 }
Ejemplo n.º 6
0
        public void RemoveUserReleaseRole()
        {
            PolicyCheckBuilder()
            .ExpectCheck(SecurityPolicies.CanManageUsersOnSystem)
            .AssertSuccess(async userService =>
            {
                var contentDbContextId = Guid.NewGuid().ToString();
                var publication        = new Publication
                {
                    Id    = Guid.NewGuid(),
                    Title = "Test Publication"
                };
                var release = new Release
                {
                    Id = Guid.NewGuid(),
                    TimePeriodCoverage = TimeIdentifier.CalendarYear,
                    ReleaseName        = "2000",
                    PublicationId      = publication.Id,
                    Publication        = publication
                };
                var user = new User
                {
                    Id        = Guid.NewGuid(),
                    FirstName = "TestFirstName",
                    LastName  = "TestLastName",
                    Email     = "*****@*****.**"
                };
                var userReleaseRole = new UserReleaseRole
                {
                    Id        = Guid.NewGuid(),
                    User      = user,
                    UserId    = user.Id,
                    Release   = release,
                    ReleaseId = release.Id,
                    Role      = ReleaseRole.Viewer,
                };
                await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
                {
                    await contentDbContext.AddAsync(userReleaseRole);
                    await contentDbContext.SaveChangesAsync();
                }

                await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
                {
                    var persistenceHelper = MockPersistenceHelper <ContentDbContext>();
                    SetupCall(persistenceHelper, userReleaseRole.Id, userReleaseRole);
                    var userManagementService = BuildUserManagementService(
                        contentDbContext: contentDbContext,
                        userService: userService.Object,
                        persistenceHelper: persistenceHelper.Object
                        );
                    return(await userManagementService.RemoveUserReleaseRole(userReleaseRole.Id));
                }
            });
        }
        public async void HasRoleOnAnyChildRelease_NoReleasesForThisTopicAndUser()
        {
            using (var context = DbUtils.InMemoryApplicationDbContext())
            {
                var userId = Guid.NewGuid();
                var topic  = new Topic
                {
                    ThemeId = Guid.NewGuid()
                };

                var releaseRoleForDifferentTopic = new UserReleaseRole
                {
                    UserId  = userId,
                    Release = new Release
                    {
                        Publication = new Publication
                        {
                            Topic = new Topic
                            {
                                ThemeId = Guid.NewGuid()
                            }
                        }
                    }
                };
                var releaseRoleForDifferentUser = new UserReleaseRole
                {
                    UserId  = Guid.NewGuid(),
                    Release = new Release
                    {
                        Publication = new Publication
                        {
                            Topic = topic
                        }
                    }
                };

                context.UserReleaseRoles.AddRange(releaseRoleForDifferentTopic, releaseRoleForDifferentUser);
                context.SaveChanges();

                var handler = new ViewSpecificTopicAuthorizationHandler(context);

                var authContext = new AuthorizationHandlerContext(
                    new IAuthorizationRequirement[] { new ViewSpecificTopicRequirement() },
                    CreateClaimsPrincipal(userId),
                    topic
                    );

                await handler.HandleAsync(authContext);

                Assert.False(authContext.HasSucceeded);
            }
        }
        public async void HasRoleOnAnyChildReleaseAuthorizationHandler_HasRoleOnAReleaseOfThisPublication()
        {
            var releaseOnThisPublication = new Release
            {
                Id            = Guid.NewGuid(),
                PublicationId = _publication.Id
            };

            var roleOnThisPublication = new UserReleaseRole
            {
                UserId  = _userId,
                Release = releaseOnThisPublication
            };

            await AssertHasRoleOnAnyChildReleaseHandlesOk(true, roleOnThisPublication);
        }
        public async Task <UserReleaseRole> Create(Guid userId, Guid releaseId, ReleaseRole role, Guid createdById)
        {
            var userReleaseRole = new UserReleaseRole
            {
                UserId      = userId,
                ReleaseId   = releaseId,
                Role        = role,
                Created     = DateTime.UtcNow,
                CreatedById = createdById,
            };

            var created =
                (await _contentDbContext.UserReleaseRoles.AddAsync(userReleaseRole)).Entity;
            await _contentDbContext.SaveChangesAsync();

            return(created);
        }
        public async void HasRoleOnAnyChildPublicationAuthorizationHandler_NoReleasesOnThisThemeForThisUser()
        {
            var releaseOnAnotherTheme = new Release
            {
                Id          = Guid.NewGuid(),
                Publication = new Publication
                {
                    Topic = new Topic
                    {
                        ThemeId = Guid.NewGuid()
                    }
                }
            };

            var releaseOnThisTheme = new Release
            {
                Id          = Guid.NewGuid(),
                Publication = new Publication
                {
                    Topic = new Topic
                    {
                        ThemeId = _theme.Id
                    }
                }
            };

            var releaseRoleForDifferentTheme = new UserReleaseRole
            {
                UserId  = _userId,
                Release = releaseOnAnotherTheme
            };

            var releaseRoleForDifferentUser = new UserReleaseRole
            {
                UserId  = Guid.NewGuid(),
                Release = releaseOnThisTheme
            };

            await AssertHasRoleOnAnyChildReleaseHandlesOk(
                false,
                releaseRoleForDifferentTheme,
                releaseRoleForDifferentUser);
        }
        public async void HasRoleOnAnyChildReleaseAuthorizationHandler_HasRoleOnAReleaseOfThisTheme()
        {
            var releaseOnThisTheme = new Release
            {
                Id          = Guid.NewGuid(),
                Publication = new Publication
                {
                    Topic = new Topic
                    {
                        ThemeId = _theme.Id
                    }
                }
            };

            var roleOnThisTheme = new UserReleaseRole
            {
                UserId  = _userId,
                Release = releaseOnThisTheme
            };

            await AssertHasRoleOnAnyChildReleaseHandlesOk(true, roleOnThisTheme);
        }
        public async Task RemoveUserReleaseRole()
        {
            var release     = new Release();
            var publication = new Publication
            {
                Id       = Guid.NewGuid(),
                Releases = new List <Release>
                {
                    release,
                }
            };
            var userReleaseRole = new UserReleaseRole
            {
                Release = release,
                Role    = Contributor,
            };

            await PolicyCheckBuilder <SecurityPolicies>()
            .SetupResourceCheckToFailWithMatcher <Tuple <Publication, ReleaseRole> >(
                tuple => tuple.Item1.Id == publication.Id && tuple.Item2 == Contributor,
                CanUpdateSpecificReleaseRole)
            .AssertForbidden(async userService =>
            {
                var contentDbContextId = Guid.NewGuid().ToString();
                await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
                {
                    await contentDbContext.AddRangeAsync(publication, userReleaseRole);
                    await contentDbContext.SaveChangesAsync();
                }

                await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
                {
                    var service = SetupUserRoleService(contentDbContext: contentDbContext,
                                                       userService: userService.Object);
                    return(await service.RemoveUserReleaseRole(userReleaseRole.Id));
                }
            });
        }
        public async Task InviteContributor_ExistingUser()
        {
            var user = new User
            {
                Email = "*****@*****.**",
            };

            var release1 = new Release()
            {
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
                ReleaseName        = "2000",
            };
            var release2 = new Release()
            {
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
                ReleaseName        = "2001",
            };
            var publication = new Publication
            {
                Title    = "Publication title",
                Releases = ListOf(release1, release2)
            };

            var existingUserReleaseRole = new UserReleaseRole
            {
                User        = user,
                Release     = release1,
                Role        = Contributor,
                Created     = new DateTime(2000, 1, 1),
                CreatedById = Guid.NewGuid(),
            };

            var contentDbContextId = Guid.NewGuid().ToString();

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                await contentDbContext.AddRangeAsync(user, publication, existingUserReleaseRole);

                await contentDbContext.SaveChangesAsync();
            }

            var emailService           = new Mock <IEmailService>(Strict);
            var expectedTemplateValues = GetExpectedContributorInviteTemplateValues(
                publication.Title, "* Academic Year 2001/02");

            emailService.Setup(mock => mock.SendEmail(
                                   "*****@*****.**",
                                   NotifyContributorTemplateId,
                                   expectedTemplateValues
                                   ))
            .Returns(Unit.Instance);

            var usersAndRolesDbContextId = Guid.NewGuid().ToString();

            await using (var usersAndRolesDbContext = InMemoryUserAndRolesDbContext(usersAndRolesDbContextId))
                await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
                {
                    var service = SetupReleaseInviteService(
                        contentDbContext: contentDbContext,
                        usersAndRolesDbContext: usersAndRolesDbContext,
                        emailService: emailService.Object);

                    var result = await service.InviteContributor(
                        email : "*****@*****.**",
                        publicationId : publication.Id,
                        releaseIds : ListOf(release1.Id, release2.Id));

                    emailService.Verify(
                        s => s.SendEmail(
                            "*****@*****.**",
                            NotifyContributorTemplateId,
                            expectedTemplateValues
                            ), Times.Once
                        );

                    VerifyAllMocks(emailService);

                    result.AssertRight();
                }

            await using (var usersAndRolesDbContext = InMemoryUserAndRolesDbContext(usersAndRolesDbContextId))
            {
                var userInvites = await usersAndRolesDbContext.UserInvites
                                  .AsQueryable()
                                  .ToListAsync();

                Assert.Empty(userInvites); // user already exists, so don't create a user invite
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var userReleaseRoles = await contentDbContext.UserReleaseRoles
                                       .AsQueryable()
                                       .ToListAsync();

                Assert.Equal(2, userReleaseRoles.Count); // as user already exists, create missing UserReleaseRoles

                Assert.Equal(existingUserReleaseRole.UserId, userReleaseRoles[0].UserId);
                Assert.Equal(existingUserReleaseRole.ReleaseId, userReleaseRoles[0].ReleaseId);
                Assert.Equal(existingUserReleaseRole.Role, userReleaseRoles[0].Role);
                Assert.Equal(existingUserReleaseRole.Created, userReleaseRoles[0].Created);
                Assert.Equal(existingUserReleaseRole.CreatedById, userReleaseRoles[0].CreatedById);

                Assert.Equal(user.Id, userReleaseRoles[1].UserId);
                Assert.Equal(release2.Id, userReleaseRoles[1].ReleaseId);
                Assert.Equal(Contributor, userReleaseRoles[1].Role);
                Assert.Equal(_createdById, userReleaseRoles[1].CreatedById);
                Assert.InRange(DateTime.UtcNow.Subtract(userReleaseRoles[1].Created !.Value).Milliseconds, 0, 1500);

                var userReleaseInvites = await contentDbContext.UserReleaseInvites
                                         .AsQueryable()
                                         .ToListAsync();

                Assert.Single(userReleaseInvites); // only create release invite for missing UserReleaseRole

                Assert.Equal("*****@*****.**", userReleaseInvites[0].Email);
                Assert.Equal(release2.Id, userReleaseInvites[0].ReleaseId);
                Assert.Equal(Contributor, userReleaseInvites[0].Role);
                Assert.Equal(_createdById, userReleaseInvites[0].CreatedById);
                Assert.True(userReleaseInvites[0].Accepted);
                Assert.True(userReleaseInvites[0].EmailSent);
                Assert.InRange(DateTime.UtcNow.Subtract(userReleaseInvites[0].Created).Milliseconds, 0, 1500);
            }
        }
Ejemplo n.º 14
0
        public void GetUser()
        {
            PolicyCheckBuilder()
            .ExpectCheck(SecurityPolicies.CanManageUsersOnSystem)
            .AssertSuccess(async userService =>
            {
                var userAndRolesContextId = Guid.NewGuid().ToString();
                var applicationUser       = new ApplicationUser
                {
                    Id        = Guid.NewGuid().ToString(),
                    FirstName = "TestFirstName",
                    LastName  = "TestLastName"
                };
                var role = new IdentityRole
                {
                    Id = Guid.NewGuid().ToString()
                };
                var userRole = new IdentityUserRole <string>
                {
                    UserId = applicationUser.Id,
                    RoleId = role.Id
                };
                await using (var userAndRolesDbContext = InMemoryUserAndRolesDbContext(userAndRolesContextId))
                {
                    await userAndRolesDbContext.AddAsync(applicationUser);
                    await userAndRolesDbContext.AddAsync(role);
                    await userAndRolesDbContext.AddAsync(userRole);
                    await userAndRolesDbContext.SaveChangesAsync();
                }

                var contentDbContextId = Guid.NewGuid().ToString();
                var publication        = new Publication
                {
                    Id    = Guid.NewGuid(),
                    Title = "Test Publication"
                };
                var release = new Release
                {
                    Id = Guid.NewGuid(),
                    TimePeriodCoverage = TimeIdentifier.CalendarYear,
                    ReleaseName        = "2000",
                    PublicationId      = publication.Id,
                    Publication        = publication
                };
                var user = new User
                {
                    Id        = Guid.Parse(role.Id),
                    FirstName = applicationUser.FirstName,
                    LastName  = applicationUser.LastName,
                    Email     = "*****@*****.**"
                };
                var userReleaseRole = new UserReleaseRole
                {
                    Id        = Guid.NewGuid(),
                    User      = user,
                    UserId    = user.Id,
                    Release   = release,
                    ReleaseId = release.Id,
                    Role      = ReleaseRole.Lead,
                };
                await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
                {
                    await contentDbContext.AddAsync(publication);
                    await contentDbContext.AddAsync(release);
                    await contentDbContext.AddAsync(userReleaseRole);
                    await contentDbContext.SaveChangesAsync();
                }

                await using (var userAndRolesDbContext =
                                 InMemoryUserAndRolesDbContext(userAndRolesContextId))
                    await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
                    {
                        var userManagementService =
                            BuildUserManagementService(
                                userAndRolesDbContext,
                                userService.Object,
                                contentDbContext);
                        return(await userManagementService.GetUser(applicationUser.Id));
                    }
            }
                           );
        }
        public async Task InviteContributor_UserAlreadyHasReleaseRoles()
        {
            var user = new User
            {
                Email = "*****@*****.**",
            };

            var release1 = new Release()
            {
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
                ReleaseName        = "2000",
            };
            var release2 = new Release()
            {
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
                ReleaseName        = "2001",
            };
            var publication = new Publication
            {
                Title    = "Publication title",
                Releases = ListOf(release1, release2)
            };

            var userRelease1Role = new UserReleaseRole()
            {
                User        = user,
                Release     = release1,
                Role        = Contributor,
                Created     = new DateTime(2000, 1, 1),
                CreatedById = Guid.NewGuid(),
            };
            var userRelease2Role = new UserReleaseRole()
            {
                User        = user,
                Release     = release2,
                Role        = Contributor,
                Created     = new DateTime(2001, 1, 1),
                CreatedById = Guid.NewGuid(),
            };

            var contentDbContextId = Guid.NewGuid().ToString();

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                await contentDbContext.AddRangeAsync(user, publication,
                                                     userRelease1Role, userRelease2Role);

                await contentDbContext.SaveChangesAsync();
            }

            var usersAndRolesDbContextId = Guid.NewGuid().ToString();

            await using (var usersAndRolesDbContext = InMemoryUserAndRolesDbContext(usersAndRolesDbContextId))
                await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
                {
                    var service = SetupReleaseInviteService(
                        contentDbContext: contentDbContext,
                        usersAndRolesDbContext: usersAndRolesDbContext);

                    var result = await service.InviteContributor(
                        email : "*****@*****.**",
                        publicationId : publication.Id,
                        releaseIds : ListOf(release1.Id, release2.Id));

                    result.AssertBadRequest(UserAlreadyHasReleaseRoles);
                }

            await using (var usersAndRolesDbContext = InMemoryUserAndRolesDbContext(usersAndRolesDbContextId))
            {
                var userInvites = await usersAndRolesDbContext.UserInvites
                                  .AsQueryable()
                                  .ToListAsync();

                Assert.Empty(userInvites); // user already exists, so don't create a user invite
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var userReleaseRoles = await contentDbContext.UserReleaseRoles
                                       .AsQueryable()
                                       .ToListAsync();

                Assert.Equal(2, userReleaseRoles.Count);
                Assert.Equal(userRelease1Role.Id, userReleaseRoles[0].Id);
                Assert.Equal(userRelease2Role.Id, userReleaseRoles[1].Id);

                var userReleaseInvites = await contentDbContext.UserReleaseInvites
                                         .AsQueryable()
                                         .ToListAsync();

                Assert.Empty(userReleaseInvites); // only create release invite for missing UserReleaseRole
            }
        }
Ejemplo n.º 16
0
        public async Task RemoveAllUserContributorPermissionForPublication()
        {
            var publication = new Publication();
            var release1    = new Release
            {
                Publication        = publication,
                ReleaseName        = "2000",
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
            };
            var release2Original = new Release
            {
                Publication        = publication,
                ReleaseName        = "2001",
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
            };
            var release2Amendment = new Release
            {
                Publication        = publication,
                ReleaseName        = "2001",
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
                PreviousVersion    = release2Original,
            };
            var user1 = new User
            {
                FirstName = "User1",
                LastName  = "One",
                Email     = "*****@*****.**",
            };
            var user1ReleaseRole1 = new UserReleaseRole
            {
                User    = user1,
                Release = release1,
                Role    = Contributor,
            };

            var user2 = new User
            {
                FirstName = "User2",
                LastName  = "Two",
                Email     = "*****@*****.**",
            };
            var user2ReleaseRole1 = new UserReleaseRole
            {
                User    = user2,
                Release = release2Amendment,
                Role    = Contributor,
            };
            var user2ReleaseRole2 = new UserReleaseRole
            {
                User    = user2,
                Release = release1,
                Role    = Contributor,
            };

            var user3 = new User
            {
                FirstName = "User3",
                LastName  = "Three",
                Email     = "*****@*****.**",
            };
            var user3ReleaseRole1 = new UserReleaseRole
            {
                User    = user3,
                Release = release2Amendment,
                Role    = Contributor,
            };

            var user1Release1Invite = new UserReleaseInvite
            {
                Email   = user1.Email,
                Release = release1,
                Role    = Contributor,
            };
            var user2Release2Invite = new UserReleaseInvite
            {
                Email   = user2.Email,
                Release = release2Original,
                Role    = Contributor,
            };

            var contentDbContextId = Guid.NewGuid().ToString();

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                await contentDbContext.AddRangeAsync(release1, release2Original, release2Amendment,
                                                     user1ReleaseRole1, user2ReleaseRole1, user2ReleaseRole2, user3ReleaseRole1,
                                                     user1Release1Invite, user2Release2Invite);

                await contentDbContext.SaveChangesAsync();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var service = SetupReleasePermissionService(contentDbContext);

                var result =
                    await service.RemoveAllUserContributorPermissionsForPublication(publication.Id, user2.Id);

                result.AssertRight();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var userReleaseRoles = await contentDbContext.UserReleaseRoles
                                       .AsAsyncEnumerable()
                                       .Where(urr => urr.Role == Contributor)
                                       .ToListAsync();

                Assert.Equal(2, userReleaseRoles.Count);
                Assert.Equal(user1.Id, userReleaseRoles[0].UserId);
                Assert.Equal(user3.Id, userReleaseRoles[1].UserId);

                var userReleaseInvites = await contentDbContext.UserReleaseInvites
                                         .ToAsyncEnumerable()
                                         .ToListAsync();

                Assert.Single(userReleaseInvites); // user1's invite remains
                Assert.Equal(user1Release1Invite.Id, userReleaseInvites[0].Id);
            }
        }
Ejemplo n.º 17
0
        public async Task UpdateReleaseContributors_RemoveAllContributorsFromRelease()
        {
            var publication = new Publication();
            var release1    = new Release
            {
                Publication        = publication,
                ReleaseName        = "2000",
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
            };

            var user1 = new User
            {
                FirstName = "User1",
                LastName  = "One",
                Email     = "*****@*****.**",
            };
            var user1ReleaseRole1 = new UserReleaseRole
            {
                User    = user1,
                Release = release1,
                Role    = Contributor,
            };

            var user2 = new User
            {
                FirstName = "User2",
                LastName  = "Two",
                Email     = "*****@*****.**",
            };
            var user2ReleaseRole1 = new UserReleaseRole
            {
                User    = user2,
                Release = release1,
                Role    = Contributor,
            };

            var contentDbContextId = Guid.NewGuid().ToString();

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                await contentDbContext.AddRangeAsync(release1, user1ReleaseRole1, user2ReleaseRole1);

                await contentDbContext.SaveChangesAsync();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var service = SetupReleasePermissionService(contentDbContext);

                var result =
                    await service.UpdateReleaseContributors(release1.Id, new List <Guid>());

                result.AssertRight();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var userReleaseRoles = await contentDbContext.UserReleaseRoles
                                       .AsAsyncEnumerable()
                                       .Where(urr =>
                                              urr.ReleaseId == release1.Id &&
                                              urr.Role == Contributor)
                                       .ToListAsync();

                Assert.Empty(userReleaseRoles);
            }
        }
Ejemplo n.º 18
0
        public async Task UpdateReleaseContributors()
        {
            var publication = new Publication();
            var release1    = new Release
            {
                Publication        = publication,
                ReleaseName        = "2000",
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
            };
            var user1 = new User
            {
                FirstName = "User1",
                LastName  = "One",
                Email     = "*****@*****.**",
            };
            var user1ReleaseRole1 = new UserReleaseRole
            {
                User        = user1,
                Release     = release1,
                Role        = Contributor,
                Created     = new DateTime(2000, 12, 25),
                CreatedById = Guid.NewGuid(),
            };
            var user2 = new User
            {
                FirstName = "User2",
                LastName  = "Two",
                Email     = "*****@*****.**",
            };
            var user2ReleaseRole1 = new UserReleaseRole
            {
                User    = user2,
                Release = release1,
                Role    = Contributor,
            };
            var user3 = new User();

            var contentDbContextId = Guid.NewGuid().ToString();

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                await contentDbContext.AddRangeAsync(release1, user1ReleaseRole1, user2ReleaseRole1);

                await contentDbContext.SaveChangesAsync();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var service = SetupReleasePermissionService(contentDbContext);

                var result =
                    await service.UpdateReleaseContributors(release1.Id, ListOf(user1.Id, user3.Id));

                result.AssertRight();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var userReleaseRoles = await contentDbContext.UserReleaseRoles
                                       .AsAsyncEnumerable()
                                       .Where(urr =>
                                              urr.ReleaseId == release1.Id &&
                                              urr.Role == Contributor)
                                       .ToListAsync();

                Assert.Equal(2, userReleaseRoles.Count);

                Assert.Equal(user1ReleaseRole1.Id, userReleaseRoles[0].Id);
                Assert.Equal(user1.Id, userReleaseRoles[0].UserId);
                Assert.Equal(user1ReleaseRole1.Created, userReleaseRoles[0].Created);
                Assert.Equal(user1ReleaseRole1.CreatedById, userReleaseRoles[0].CreatedById);

                // userReleaseRole[1] is newly created, so cannot check Id
                Assert.Equal(user3.Id, userReleaseRoles[1].UserId);
                Assert.InRange(DateTime.UtcNow.Subtract(userReleaseRoles[1].Created !.Value).Milliseconds,
                               0, 1500);
                Assert.Equal(_userId, userReleaseRoles[1].CreatedById);
            }
        }
Ejemplo n.º 19
0
        public async Task ListPublicationContributors()
        {
            var publication = new Publication();
            var release1    = new Release
            {
                Publication        = publication,
                ReleaseName        = "2000",
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
            };
            var release2Original = new Release
            {
                Publication        = publication,
                ReleaseName        = "2001",
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
            };
            var release2Amendment = new Release
            {
                Publication        = publication,
                ReleaseName        = "2001",
                TimePeriodCoverage = TimeIdentifier.AcademicYear,
                PreviousVersion    = release2Original,
            };
            var user1 = new User
            {
                FirstName = "User1",
                LastName  = "One",
                Email     = "*****@*****.**",
            };
            var user1ReleaseRole1 = new UserReleaseRole
            {
                User    = user1,
                Release = release1,
                Role    = Contributor,
            };

            var user2 = new User
            {
                FirstName = "User2",
                LastName  = "Two",
                Email     = "*****@*****.**",
            };
            var user2ReleaseRole1 = new UserReleaseRole
            {
                User    = user2,
                Release = release2Amendment,
                Role    = Contributor,
            };

            var user3 = new User();
            var user3ReleaseRoleIgnored1 = new UserReleaseRole // Ignored because different publication
            {
                User    = user3,
                Release = new Release {
                    Publication = new Publication()
                },
                Role = Contributor,
            };
            var user3ReleaseRoleIgnored2 = new UserReleaseRole // Ignored because not Contributor role
            {
                User    = user3,
                Release = release1,
                Role    = PrereleaseViewer,
            };
            var user3ReleaseRoleIgnored3 = new UserReleaseRole // Ignored because not latest version of release
            {
                User    = user3,
                Release = release2Original,
                Role    = Contributor,
                Deleted = DateTime.UtcNow,
            };

            var contentDbContextId = Guid.NewGuid().ToString();

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                await contentDbContext.AddRangeAsync(release1, release2Original, release2Amendment,
                                                     user1ReleaseRole1, user2ReleaseRole1,
                                                     user3ReleaseRoleIgnored1, user3ReleaseRoleIgnored2, user3ReleaseRoleIgnored3);

                await contentDbContext.SaveChangesAsync();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var service = SetupReleasePermissionService(contentDbContext);

                var result =
                    await service.ListPublicationContributors(publication.Id);

                var viewModel = result.AssertRight();

                Assert.Equal(2, viewModel.Count);

                Assert.Equal(user1.Id, viewModel[0].UserId);
                Assert.Equal(user1.DisplayName, viewModel[0].UserDisplayName);
                Assert.Equal(user1.Email, viewModel[0].UserEmail);

                Assert.Equal(user2.Id, viewModel[1].UserId);
                Assert.Equal(user2.DisplayName, viewModel[1].UserDisplayName);
                Assert.Equal(user2.Email, viewModel[1].UserEmail);
            }
        }
        public void CreateReleaseAmendmentAsync()
        {
            var releaseId   = Guid.NewGuid();
            var releaseType = new ReleaseType
            {
                Id    = Guid.NewGuid(),
                Title = "Official Statistics"
            };
            var publicationId            = Guid.NewGuid();
            var publishedDate            = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1));
            var createdDate              = DateTime.UtcNow.Subtract(TimeSpan.FromDays(2));
            var previousVersionReleaseId = Guid.NewGuid();
            var version     = 2;
            var createdById = Guid.NewGuid();
            var createdBy   = new User
            {
                Id = createdById
            };
            var internalReleaseNote = "Release note";
            var releaseStatus       = ReleaseStatus.Approved;
            var publishScheduled    = DateTime.Now.AddDays(1);
            var nextReleaseDate     = new PartialDate {
                Day = "1", Month = "1", Year = "2040"
            };
            var releaseName        = "2035";
            var timePeriodCoverage = TimeIdentifier.March;

            var dataBlock1 = new DataBlock
            {
                Id       = Guid.NewGuid(),
                Name     = "Data Block 1",
                Order    = 2,
                Comments = new List <Comment>
                {
                    new Comment
                    {
                        Id      = Guid.NewGuid(),
                        Content = "Comment 1 Text"
                    },
                    new Comment
                    {
                        Id      = Guid.NewGuid(),
                        Content = "Comment 2 Text"
                    }
                }
            };

            var dataBlock2 = new DataBlock
            {
                Id   = Guid.NewGuid(),
                Name = "Data Block 2"
            };

            var release = new Release
            {
                Id                  = releaseId,
                Type                = releaseType,
                TypeId              = releaseType.Id,
                PublishScheduled    = publishScheduled,
                NextReleaseDate     = nextReleaseDate,
                ReleaseName         = releaseName,
                TimePeriodCoverage  = timePeriodCoverage,
                PublicationId       = publicationId,
                Published           = publishedDate,
                Status              = releaseStatus,
                Version             = version,
                PreviousVersionId   = previousVersionReleaseId,
                Created             = createdDate,
                CreatedBy           = createdBy,
                CreatedById         = createdById,
                InternalReleaseNote = internalReleaseNote,
                RelatedInformation  = new List <Link>
                {
                    new Link
                    {
                        Id          = Guid.NewGuid(),
                        Description = "Link 1",
                        Url         = "URL 1"
                    },
                    new Link
                    {
                        Id          = Guid.NewGuid(),
                        Description = "Link 2",
                        Url         = "URL 2"
                    }
                },
                Updates = new List <Update>
                {
                    new Update
                    {
                        Id        = Guid.NewGuid(),
                        On        = DateTime.UtcNow.Subtract(TimeSpan.FromDays(4)),
                        Reason    = "Reason 1",
                        ReleaseId = releaseId
                    },
                    new Update
                    {
                        Id        = Guid.NewGuid(),
                        On        = DateTime.UtcNow.Subtract(TimeSpan.FromDays(5)),
                        Reason    = "Reason 2",
                        ReleaseId = releaseId
                    }
                },
                Content = new List <ReleaseContentSection>
                {
                    new ReleaseContentSection
                    {
                        ReleaseId      = Guid.NewGuid(),
                        ContentSection = new ContentSection
                        {
                            Id      = Guid.NewGuid(),
                            Caption = "Template caption index 0",
                            Heading = "Template heading index 0",
                            Type    = ContentSectionType.Generic,
                            Order   = 1,
                            Content = new List <ContentBlock>
                            {
                                new HtmlBlock
                                {
                                    Id       = Guid.NewGuid(),
                                    Body     = @"<div></div>",
                                    Order    = 1,
                                    Comments = new List <Comment>
                                    {
                                        new Comment
                                        {
                                            Id      = Guid.NewGuid(),
                                            Content = "Comment 1 Text"
                                        },
                                        new Comment
                                        {
                                            Id      = Guid.NewGuid(),
                                            Content = "Comment 2 Text"
                                        }
                                    }
                                },
                                dataBlock1
                            }
                        }
                    },

                    new ReleaseContentSection
                    {
                        ReleaseId      = Guid.NewGuid(),
                        ContentSection = new ContentSection
                        {
                            Id      = Guid.NewGuid(),
                            Caption = "Template caption index 1",
                            Heading = "Template heading index 1",
                            Type    = ContentSectionType.Generic,
                            Order   = 2,
                            Content = new List <ContentBlock>
                            {
                                new MarkDownBlock
                                {
                                    Id       = Guid.NewGuid(),
                                    Body     = "Text",
                                    Comments = new List <Comment>
                                    {
                                        new Comment
                                        {
                                            Id      = Guid.NewGuid(),
                                            Content = "Inset Comment 1 Text"
                                        }
                                    }
                                }
                            }
                        }
                    },

                    new ReleaseContentSection
                    {
                        ReleaseId      = Guid.NewGuid(),
                        ContentSection = new ContentSection
                        {
                            Id      = Guid.NewGuid(),
                            Caption = "Template caption index 2",
                            Heading = "Template heading index 2",
                            Type    = ContentSectionType.Headlines,
                            Order   = 1,
                            Content = new List <ContentBlock>
                            {
                                new MarkDownBlock
                                {
                                    Id       = Guid.NewGuid(),
                                    Body     = "Text",
                                    Comments = new List <Comment>
                                    {
                                        new Comment
                                        {
                                            Id      = Guid.NewGuid(),
                                            Content = "Inset Comment 1 Text"
                                        }
                                    }
                                }
                            }
                        }
                    }
                },

                ContentBlocks = new List <ReleaseContentBlock>
                {
                    new ReleaseContentBlock
                    {
                        ReleaseId      = releaseId,
                        ContentBlock   = dataBlock1,
                        ContentBlockId = dataBlock1.Id,
                    },
                    new ReleaseContentBlock
                    {
                        ReleaseId      = releaseId,
                        ContentBlock   = dataBlock2,
                        ContentBlockId = dataBlock2.Id,
                    }
                }
            };

            var approverReleaseRole = new UserReleaseRole
            {
                Id        = Guid.NewGuid(),
                UserId    = Guid.NewGuid(),
                Role      = ReleaseRole.Approver,
                Release   = release,
                ReleaseId = releaseId
            };

            var contributorReleaseRole = new UserReleaseRole
            {
                Id        = Guid.NewGuid(),
                UserId    = Guid.NewGuid(),
                Role      = ReleaseRole.Contributor,
                Release   = release,
                ReleaseId = releaseId
            };

            var userReleaseRoles = new List <UserReleaseRole>
            {
                approverReleaseRole,
                contributorReleaseRole
            };

            var dataFile1 = new File
            {
                Id        = Guid.NewGuid(),
                Filename  = "Filename 1",
                Release   = release,
                ReleaseId = releaseId,
                SubjectId = Guid.NewGuid()
            };

            var dataFile2 = new File
            {
                Id        = Guid.NewGuid(),
                Filename  = "Filename 2",
                Release   = release,
                ReleaseId = releaseId,
                SubjectId = Guid.NewGuid()
            };

            var releaseFiles = new List <ReleaseFile>
            {
                new ReleaseFile
                {
                    Id        = Guid.NewGuid(),
                    Release   = release,
                    ReleaseId = releaseId,
                    File      = dataFile1,
                    FileId    = dataFile1.Id
                },
                new ReleaseFile
                {
                    Id        = Guid.NewGuid(),
                    Release   = release,
                    ReleaseId = releaseId,
                    File      = dataFile2,
                    FileId    = dataFile2.Id
                }
            };

            var subject1 = new Subject
            {
                Id   = Guid.NewGuid(),
                Name = "Subject 1"
            };

            var subject2 = new Subject
            {
                Id   = Guid.NewGuid(),
                Name = "Subject 2"
            };

            using (var contentDbContext = InMemoryApplicationDbContext("CreateReleaseAmendment"))
            {
                contentDbContext.AddRange(new List <ReleaseType>
                {
                    releaseType
                });

                contentDbContext.Add(new Publication
                {
                    Id       = publicationId,
                    Releases = new List <Release>
                    {
                        release
                    }
                });

                contentDbContext.Add(createdBy);
                contentDbContext.Add(new User
                {
                    Id = _userId
                });
                contentDbContext.AddRange(userReleaseRoles);
                contentDbContext.AddRange(releaseFiles);

                contentDbContext.SaveChanges();
            }

            using (var statisticsDbContext = InMemoryStatisticsDbContext("CreateReleaseAmendment"))
            {
                statisticsDbContext.Release.Add(new Data.Model.Release
                {
                    Id             = release.Id,
                    PublicationId  = release.PublicationId,
                    Published      = release.Published,
                    Slug           = release.Slug,
                    Year           = release.Year,
                    TimeIdentifier = release.TimePeriodCoverage
                });

                statisticsDbContext.Subject.AddRange(subject1, subject2);

                statisticsDbContext.ReleaseSubject.AddRange(
                    new ReleaseSubject
                {
                    ReleaseId = releaseId,
                    SubjectId = subject1.Id
                },
                    new ReleaseSubject
                {
                    ReleaseId = releaseId,
                    SubjectId = subject2.Id
                }
                    );

                statisticsDbContext.SaveChanges();
            }

            var newReleaseId = Guid.Empty;

            var footnoteService = new Mock <IFootnoteService>();

            footnoteService
            .Setup(service => service.CopyFootnotes(releaseId, It.IsAny <Guid>()))
            .ReturnsAsync(new Either <ActionResult, List <Footnote> >(new List <Footnote>()));

            using (var contentDbContext = InMemoryApplicationDbContext("CreateReleaseAmendment"))
                using (var statisticsDbContext = InMemoryStatisticsDbContext("CreateReleaseAmendment"))
                {
                    var releaseService = BuildReleaseService(
                        contentDbContext,
                        statisticsDbContext,
                        footnoteService: footnoteService.Object
                        );

                    // Method under test
                    var amendmentViewModel = releaseService.CreateReleaseAmendmentAsync(releaseId).Result.Right;

                    footnoteService.Verify(
                        mock => mock.CopyFootnotes(releaseId, amendmentViewModel.Id), Times.Once);

                    footnoteService.VerifyNoOtherCalls();

                    Assert.NotEqual(release.Id, amendmentViewModel.Id);
                    Assert.NotEqual(Guid.Empty, amendmentViewModel.Id);
                    newReleaseId = amendmentViewModel.Id;
                }

            using (var contentDbContext = InMemoryApplicationDbContext("CreateReleaseAmendment"))
            {
                var amendment = contentDbContext
                                .Releases
                                .Include(r => r.PreviousVersion)
                                .Include(r => r.Type)
                                .Include(r => r.CreatedBy)
                                .Include(r => r.Publication)
                                .Include(r => r.Content)
                                .ThenInclude(c => c.ContentSection)
                                .ThenInclude(c => c.Content)
                                .ThenInclude(c => c.Comments)
                                .Include(r => r.Updates)
                                .Include(r => r.ContentBlocks)
                                .ThenInclude(r => r.ContentBlock)
                                .First(r => r.Id == newReleaseId);

                // check fields that should be set to new values for an amendment, rather than copied from its original
                // Release
                Assert.Equal(newReleaseId, amendment.Id);
                Assert.Null(amendment.PublishScheduled);
                Assert.Null(amendment.Published);
                Assert.Equal(release.Version + 1, amendment.Version);
                Assert.Equal(ReleaseStatus.Draft, amendment.Status);
                Assert.Equal(release.Id, amendment.PreviousVersion?.Id);
                Assert.Equal(release.Id, amendment.PreviousVersionId);
                Assert.Equal(_userId, amendment.CreatedBy.Id);
                Assert.Equal(_userId, amendment.CreatedById);
                Assert.InRange(DateTime.UtcNow.Subtract(amendment.Created).Milliseconds, 0, 1500);
                Assert.Null(amendment.InternalReleaseNote);

                Assert.Equal(releaseType, amendment.Type);
                Assert.Equal(releaseType.Id, amendment.TypeId);
                Assert.Equal(nextReleaseDate, amendment.NextReleaseDate);
                Assert.Equal(releaseName, amendment.ReleaseName);
                Assert.Equal(timePeriodCoverage, amendment.TimePeriodCoverage);
                Assert.Equal(publicationId, amendment.PublicationId);

                Assert.Equal(release.RelatedInformation.Count, amendment.RelatedInformation.Count);
                amendment.RelatedInformation.ForEach(amended =>
                {
                    var index    = amendment.RelatedInformation.IndexOf(amended);
                    var previous = release.RelatedInformation[index];
                    AssertAmendedLinkCorrect(amended, previous);
                });

                Assert.Equal(release.Updates.Count, amendment.Updates.Count);
                amendment.Updates.ForEach(amended =>
                {
                    var index    = amendment.Updates.IndexOf(amended);
                    var previous = release.Updates[index];
                    AssertAmendedUpdateCorrect(amended, previous, amendment);
                });

                Assert.Equal(release.Content.Count, amendment.Content.Count);
                amendment.Content.ForEach(amended =>
                {
                    var index    = amendment.Content.IndexOf(amended);
                    var previous = release.Content[index];
                    AssertAmendedContentSectionCorrect(amendment, amended, previous);
                });

                Assert.Equal(release.ContentBlocks.Count, amendment.ContentBlocks.Count);
                var amendmentContentBlock1          = amendment.ContentBlocks[0].ContentBlock;
                var amendmentContentBlock2          = amendment.ContentBlocks[1].ContentBlock;
                var amendmentContentBlock1InContent = amendment.Content[0].ContentSection.Content[0];

                // Check that the DataBlock that is included in this Release amendment's Content is successfully
                // identified as the exact same DataBlock that is attached to the Release amendment through the
                // additional "Release.ContentBlocks" relationship (which is used to determine which Data Blocks
                // belong to which Release when a Data Block has not yet been - or is removed from - the Release's
                // Content
                Assert.NotEqual(dataBlock1.Id, amendmentContentBlock1.Id);
                Assert.Equal(amendmentContentBlock1, amendmentContentBlock1InContent);

                // and check that the Data Block that is not yet included in any content is copied across OK still
                Assert.NotEqual(dataBlock2.Id, amendmentContentBlock2.Id);
                Assert.Equal((amendmentContentBlock2 as DataBlock).Name, dataBlock2.Name);

                var amendmentReleaseRoles = contentDbContext
                                            .UserReleaseRoles
                                            .Where(r => r.ReleaseId == amendment.Id)
                                            .ToList();

                Assert.Equal(userReleaseRoles.Count, amendmentReleaseRoles.Count);
                var approverAmendmentRole = amendmentReleaseRoles.First(r => r.Role == ReleaseRole.Approver);
                AssertAmendedReleaseRoleCorrect(approverReleaseRole, approverAmendmentRole, amendment);

                var contributorAmendmentRole = amendmentReleaseRoles.First(r => r.Role == ReleaseRole.Contributor);
                Assert.NotEqual(contributorReleaseRole.Id, contributorAmendmentRole.Id);
                AssertAmendedReleaseRoleCorrect(contributorReleaseRole, contributorAmendmentRole, amendment);

                var amendmentDataFiles = contentDbContext
                                         .ReleaseFiles
                                         .Include(f => f.File)
                                         .Where(f => f.ReleaseId == amendment.Id)
                                         .ToList();

                Assert.Equal(releaseFiles.Count, amendmentDataFiles.Count);

                var amendmentDataFile = amendmentDataFiles[0];
                var originalFile      = releaseFiles.First(f =>
                                                           f.File.Filename == amendmentDataFile.File.Filename);
                AssertAmendedReleaseFileCorrect(originalFile, amendmentDataFile, amendment);

                var amendmentDataFile2 = amendmentDataFiles[1];
                var originalFile2      = releaseFiles.First(f =>
                                                            f.File.Filename == amendmentDataFile2.File.Filename);
                AssertAmendedReleaseFileCorrect(originalFile2, amendmentDataFile2, amendment);

                Assert.True(amendment.Amendment);
            }

            using (var statisticsDbContext = InMemoryStatisticsDbContext("CreateReleaseAmendment"))
            {
                var releaseSubjectLinks = statisticsDbContext
                                          .ReleaseSubject
                                          .Where(r => r.ReleaseId == newReleaseId)
                                          .ToList();

                Assert.Equal(2, releaseSubjectLinks.Count);
                Assert.Contains(subject1.Id, releaseSubjectLinks.Select(r => r.SubjectId));
                Assert.Contains(subject2.Id, releaseSubjectLinks.Select(r => r.SubjectId));
            }
        }
        public async Task ListUserReleaseRolesByPublication()
        {
            var release1 = new Release
            {
                Id = Guid.NewGuid(),
            };
            var release2 = new Release
            {
                Id = Guid.NewGuid(),
            };
            var publication = new Publication
            {
                Id       = Guid.NewGuid(),
                Releases = ListOf(release1, release2),
            };

            var releaseIgnored1 = new Release // Ignored because different publication
            {
                Id            = Guid.NewGuid(),
                PublicationId = Guid.NewGuid(),
            };

            var userReleaseRole1 = new UserReleaseRole
            {
                User = new User {
                    Id = Guid.NewGuid()
                },
                Release = release1,
                Role    = Contributor,
            };
            var userReleaseRole2 = new UserReleaseRole
            {
                User = new User {
                    Id = Guid.NewGuid()
                },
                Release = release1,
                Role    = Contributor,
            };
            var userReleaseRole3 = new UserReleaseRole
            {
                User = new User {
                    Id = Guid.NewGuid()
                },
                Release = release2,
                Role    = Contributor,
            };
            var userReleaseRoleIgnored1 = new UserReleaseRole // Ignored because not Contributor role
            {
                User = new User {
                    Id = Guid.NewGuid()
                },
                Release = release1,
                Role    = Lead,
            };
            var userReleaseRoleIgnored2 = new UserReleaseRole // Ignored because Deleted set
            {
                User = new User {
                    Id = Guid.NewGuid()
                },
                Release = release1,
                Role    = Contributor,
                Deleted = DateTime.UtcNow,
            };
            var userReleaseRoleIgnored3 = new UserReleaseRole // Ignored due to release under different publication
            {
                User = new User {
                    Id = Guid.NewGuid()
                },
                Release = releaseIgnored1,
                Role    = Contributor,
            };

            var contentDbContextId = Guid.NewGuid().ToString();

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                await contentDbContext.AddRangeAsync(
                    publication,
                    userReleaseRole1, userReleaseRole2, userReleaseRole3,
                    userReleaseRoleIgnored1, userReleaseRoleIgnored2, userReleaseRoleIgnored3);

                await contentDbContext.SaveChangesAsync();
            }

            await using (var contentDbContext = InMemoryApplicationDbContext(contentDbContextId))
            {
                var service          = SetupUserReleaseRoleService(contentDbContext);
                var userReleaseRoles = await service.ListUserReleaseRolesByPublication(Contributor,
                                                                                       publication.Id);

                Assert.Equal(3, userReleaseRoles.Count);

                Assert.Equal(userReleaseRole1.Id, userReleaseRoles[0].Id);
                Assert.Equal(userReleaseRole1.UserId, userReleaseRoles[0].UserId);
                Assert.Equal(userReleaseRole1.ReleaseId, userReleaseRoles[0].ReleaseId);
                Assert.Equal(userReleaseRole1.Role, userReleaseRoles[0].Role);

                Assert.Equal(userReleaseRole2.Id, userReleaseRoles[1].Id);
                Assert.Equal(userReleaseRole2.UserId, userReleaseRoles[1].UserId);
                Assert.Equal(userReleaseRole2.ReleaseId, userReleaseRoles[1].ReleaseId);
                Assert.Equal(userReleaseRole2.Role, userReleaseRoles[1].Role);

                Assert.Equal(userReleaseRole3.Id, userReleaseRoles[2].Id);
                Assert.Equal(userReleaseRole3.UserId, userReleaseRoles[2].UserId);
                Assert.Equal(userReleaseRole3.ReleaseId, userReleaseRoles[2].ReleaseId);
                Assert.Equal(userReleaseRole3.Role, userReleaseRoles[2].Role);
            }
        }