private static void AssertAmendedContentSectionCorrect(Release amendment, ReleaseContentSection amended,
                                                               ReleaseContentSection previous)
        {
            Assert.Equal(amendment, amended.Release);
            Assert.Equal(amendment.Id, amended.ReleaseId);
            Assert.True(amended.ContentSectionId != Guid.Empty);
            Assert.NotEqual(previous.ContentSectionId, amended.ContentSectionId);

            var previousSection = previous.ContentSection;
            var amendedSection  = amended.ContentSection;

            Assert.NotEqual(previousSection.Id, amendedSection.Id);
            Assert.Equal(previousSection.Caption, amendedSection.Caption);
            Assert.Equal(previousSection.Heading, amendedSection.Heading);
            Assert.Equal(previousSection.Order, amendedSection.Order);
            Assert.Equal(previousSection.Type, amendedSection.Type);
            Assert.Equal(previousSection.Content.Count, amendedSection.Content.Count);

            amendedSection.Content.ForEach(amendedBlock =>
            {
                var previousBlock = previousSection.Content.Find(b => b.Order == amendedBlock.Order);
                AssertAmendedContentBlockCorrect(previousBlock, amendedBlock, amendedSection);
            });
        }
        public async Task GetChecklist_FullyValid()
        {
            var publication = new Publication();

            var methodologyVersion = new MethodologyVersion
            {
                Status = Approved
            };

            var originalRelease = new Release
            {
                Publication = publication,
                Version     = 0,
                Created     = DateTime.UtcNow.AddMonths(-2),
            };
            var release = new Release
            {
                Publication          = publication,
                PreviousVersion      = originalRelease,
                Version              = 1,
                Created              = DateTime.UtcNow.AddMonths(-1),
                DataGuidance         = "Test guidance",
                PreReleaseAccessList = "Test access list",
                NextReleaseDate      = new PartialDate
                {
                    Month = "12",
                    Year  = "2021"
                },
                Updates = new List <Update>
                {
                    new()
                    {
                        Reason = "Test reason 2",
                        // To avoid checklist error, this amendment requires an Update
                        // created after release.Created
                        Created = DateTime.UtcNow,
                    }
                },
            };

            var releaseContentSection1 = new ReleaseContentSection
            {
                Release        = release,
                ContentSection = new ContentSection
                {
                    Type    = ContentSectionType.Generic,
                    Content = new List <ContentBlock>
                    {
                        new HtmlBlock
                        {
                            Body = "<p>test</p>"
                        }
                    }
                }
            };

            var releaseContentSection2 = new ReleaseContentSection
            {
                Release        = release,
                ContentSection = new ContentSection
                {
                    Type    = ContentSectionType.Generic,
                    Content = new List <ContentBlock>
                    {
                        new DataBlock()
                    }
                }
            };

            var releaseContentSection3 = new ReleaseContentSection
            {
                Release        = release,
                ContentSection = new ContentSection
                {
                    Type    = ContentSectionType.Headlines,
                    Content = new List <ContentBlock>
                    {
                        new HtmlBlock
                        {
                            Body = ""
                        }
                    }
                }
            };

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

            await using (var context = InMemoryContentDbContext(contextId))
            {
                await context.AddRangeAsync(
                    releaseContentSection1,
                    releaseContentSection2,
                    releaseContentSection3,
                    originalRelease);

                await context.SaveChangesAsync();
            }

            var dataBlockService             = new Mock <IDataBlockService>(MockBehavior.Strict);
            var footnoteRepository           = new Mock <IFootnoteRepository>();
            var dataGuidanceService          = new Mock <IDataGuidanceService>(MockBehavior.Strict);
            var methodologyVersionRepository = new Mock <IMethodologyVersionRepository>(MockBehavior.Strict);
            var releaseDataFileRepository    = new Mock <IReleaseDataFileRepository>(MockBehavior.Strict);

            await using (var context = InMemoryContentDbContext(contextId))
            {
                var subject = new Subject
                {
                    Id = Guid.NewGuid()
                };

                methodologyVersionRepository
                .Setup(mock => mock.GetLatestVersionByPublication(release.PublicationId))
                .ReturnsAsync(ListOf(methodologyVersion));

                releaseDataFileRepository
                .Setup(r => r.ListDataFiles(release.Id))
                .ReturnsAsync(
                    new List <File>
                {
                    new File
                    {
                        Id        = Guid.NewGuid(),
                        Filename  = "test-file-1.csv",
                        Type      = FileType.Data,
                        SubjectId = subject.Id,
                    },
                }
                    );

                releaseDataFileRepository
                .Setup(r => r.ListReplacementDataFiles(release.Id))
                .ReturnsAsync(new List <File>());

                dataGuidanceService
                .Setup(s => s.Validate(release.Id))
                .ReturnsAsync(Unit.Instance);

                footnoteRepository
                .Setup(r => r.GetSubjectsWithNoFootnotes(release.Id))
                .ReturnsAsync(new List <Subject>());

                dataBlockService
                .Setup(s => s.List(release.Id))
                .ReturnsAsync(
                    new List <DataBlockSummaryViewModel>
                {
                    new DataBlockSummaryViewModel
                    {
                        HighlightName = "Test highlight name"
                    },
                }
                    );

                var service = BuildReleaseChecklistService(
                    context,
                    dataGuidanceService: dataGuidanceService.Object,
                    releaseDataFileRepository: releaseDataFileRepository.Object,
                    methodologyVersionRepository: methodologyVersionRepository.Object,
                    footnoteRepository: footnoteRepository.Object,
                    dataBlockService: dataBlockService.Object
                    );
                var result = await service.GetChecklist(release.Id);

                var checklist = result.AssertRight();

                Assert.Empty(checklist.Errors);
                Assert.Empty(checklist.Warnings);
                Assert.True(checklist.Valid);
            }

            MockUtils.VerifyAllMocks(dataBlockService,
                                     footnoteRepository,
                                     dataGuidanceService,
                                     methodologyVersionRepository,
                                     releaseDataFileRepository);
        }
        public async Task GetChecklist_AllErrors()
        {
            var publication = new Publication();

            var originalRelease = new Release
            {
                Publication = publication,
                Version     = 0,
                Created     = DateTime.UtcNow.AddMonths(-2),
                Updates     = new List <Update>
                {
                    new()
                    {
                        Reason  = "Original release note",
                        Created = DateTime.UtcNow.AddMonths(-2).AddDays(1),
                    }
                },
            };
            var release = new Release
            {
                Publication     = publication,
                PreviousVersion = originalRelease,
                Version         = 1,
                Created         = DateTime.UtcNow.AddMonths(-1),
                Updates         = new List <Update>
                {
                    new()
                    {
                        Reason  = "Original release note",
                        Created = DateTime.UtcNow.AddMonths(-2).AddDays(1),
                    }
                },
            };

            var releaseContentSection1 = new ReleaseContentSection
            {
                Release        = release,
                ContentSection = new ContentSection
                {
                    Type    = ContentSectionType.Generic,
                    Content = new List <ContentBlock>()
                }
            };

            var releaseContentSection2 = new ReleaseContentSection
            {
                Release        = release,
                ContentSection = new ContentSection
                {
                    Type    = ContentSectionType.Generic,
                    Content = new List <ContentBlock>
                    {
                        new HtmlBlock
                        {
                            Body = "<p>Test</p>"
                        },
                        new DataBlock(),
                        new HtmlBlock
                        {
                            Body = ""
                        }
                    }
                }
            };

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

            await using (var context = InMemoryContentDbContext(contextId))
            {
                await context.AddRangeAsync(
                    releaseContentSection1,
                    releaseContentSection2,
                    originalRelease);

                await context.SaveChangesAsync();
            }

            var dataImportService            = new Mock <IDataImportService>(MockBehavior.Strict);
            var dataGuidanceService          = new Mock <IDataGuidanceService>(MockBehavior.Strict);
            var methodologyVersionRepository = new Mock <IMethodologyVersionRepository>(MockBehavior.Strict);
            var releaseDataFileRepository    = new Mock <IReleaseDataFileRepository>(MockBehavior.Strict);

            await using (var context = InMemoryContentDbContext(contextId))
            {
                methodologyVersionRepository
                .Setup(mock => mock.GetLatestVersionByPublication(release.PublicationId))
                .ReturnsAsync(new List <MethodologyVersion>());

                releaseDataFileRepository
                .Setup(r => r.ListDataFiles(release.Id))
                .ReturnsAsync(new List <File>());

                releaseDataFileRepository
                .Setup(r => r.ListReplacementDataFiles(release.Id))
                .ReturnsAsync(
                    new List <File>
                {
                    new File()
                }
                    );

                dataImportService
                .Setup(s => s.HasIncompleteImports(release.Id))
                .ReturnsAsync(true);

                dataGuidanceService
                .Setup(s => s.Validate(release.Id))
                .ReturnsAsync(ValidationActionResult(PublicDataGuidanceRequired));

                var service = BuildReleaseChecklistService(
                    context,
                    releaseDataFileRepository: releaseDataFileRepository.Object,
                    dataImportService: dataImportService.Object,
                    dataGuidanceService: dataGuidanceService.Object,
                    methodologyVersionRepository: methodologyVersionRepository.Object
                    );

                var result = await service.GetChecklist(release.Id);

                var checklist = result.AssertRight();

                Assert.False(checklist.Valid);

                Assert.Equal(6, checklist.Errors.Count);

                Assert.Equal(DataFileImportsMustBeCompleted, checklist.Errors[0].Code);
                Assert.Equal(DataFileReplacementsMustBeCompleted, checklist.Errors[1].Code);
                Assert.Equal(PublicDataGuidanceRequired, checklist.Errors[2].Code);
                Assert.Equal(ReleaseNoteRequired, checklist.Errors[3].Code);
                Assert.Equal(EmptyContentSectionExists, checklist.Errors[4].Code);
                Assert.Equal(GenericSectionsContainEmptyHtmlBlock, checklist.Errors[5].Code);
            }

            MockUtils.VerifyAllMocks(dataImportService,
                                     dataGuidanceService,
                                     methodologyVersionRepository,
                                     releaseDataFileRepository);
        }