public async void UpdateMethodologyAsync_Returns_Ok()
        {
            var request = new UpdateMethodologyRequest();

            var methodologyService = new Mock <IMethodologyService>();

            methodologyService.Setup(s => s.UpdateMethodologyAsync(It.IsAny <Guid>(), request))
            .ReturnsAsync(new Either <ActionResult, MethodologySummaryViewModel>(new MethodologySummaryViewModel()));
            var controller = new MethodologyController(methodologyService.Object);

            // Method under test
            var result = await controller.UpdateMethodologyAsync(Guid.NewGuid(), request);

            AssertOkResult(result);
        }
        public async Task UpdateAsync_SlugNotUnique()
        {
            var methodology1 = new Methodology
            {
                Id     = Guid.NewGuid(),
                Slug   = "pupil-absence-statistics-methodology",
                Status = Draft,
                Title  = "Methodology title"
            };

            var methodology2 = new Methodology
            {
                Id = Guid.NewGuid(),
                InternalReleaseNote = "Test approval",
                Published           = new DateTime(2020, 5, 25),
                Slug   = "pupil-exclusion-statistics-methodology",
                Status = Draft,
                Title  = "Pupil exclusion statistics: methodology"
            };

            var request = new UpdateMethodologyRequest
            {
                InternalReleaseNote = null,
                Status = Draft,
                Title  = "Pupil exclusion statistics: methodology"
            };

            await using (var context = DbUtils.InMemoryApplicationDbContext("UpdateSlugNotUnique"))
            {
                await context.AddRangeAsync(new List <Methodology>
                {
                    methodology1, methodology2
                });

                await context.SaveChangesAsync();
            }

            await using (var context = DbUtils.InMemoryApplicationDbContext("UpdateSlugNotUnique"))
            {
                var result = await BuildMethodologyService(
                    context,
                    Mocks())
                             .UpdateMethodologyAsync(methodology1.Id, request);

                Assert.True(result.IsLeft);
                AssertValidationProblem(result.Left, SlugNotUnique);
            }
        }
        public async Task UpdateAsync_AlreadyPublished()
        {
            var methodology = new Methodology
            {
                Id = Guid.NewGuid(),
                InternalReleaseNote = "Test approval",
                Published           = new DateTime(2020, 5, 25),
                Slug   = "pupil-absence-statistics-methodology",
                Status = Draft,
                Title  = "Pupil absence statistics: methodology"
            };

            var request = new UpdateMethodologyRequest
            {
                InternalReleaseNote = null,
                Status = Draft,
                Title  = "Pupil absence statistics (updated): methodology"
            };

            await using (var context = DbUtils.InMemoryApplicationDbContext("Update"))
            {
                context.Add(methodology);
                await context.SaveChangesAsync();
            }

            await using (var context = DbUtils.InMemoryApplicationDbContext("Update"))
            {
                var viewModel = (await BuildMethodologyService(context,
                                                               Mocks())
                                 .UpdateMethodologyAsync(methodology.Id, request)).Right;

                var model = await context.Methodologies.FindAsync(methodology.Id);

                Assert.True(model.Live);
                // Slug remains unchanged
                Assert.Equal("pupil-absence-statistics-methodology", model.Slug);
                Assert.True(model.Updated.HasValue);
                Assert.InRange(DateTime.UtcNow.Subtract(model.Updated.Value).Milliseconds, 0, 1500);

                Assert.Equal(methodology.Id, viewModel.Id);
                // TODO EES-331 is this correct?
                // Original release note is not cleared if the update is not altering it
                Assert.Equal(methodology.InternalReleaseNote, viewModel.InternalReleaseNote);
                Assert.Equal(methodology.Published, viewModel.Published);
                Assert.Equal(request.Status, viewModel.Status);
                Assert.Equal(request.Title, viewModel.Title);
            }
        }
        public async Task UpdateAsync()
        {
            var methodology = new Methodology
            {
                Id     = Guid.NewGuid(),
                Slug   = "pupil-absence-statistics-methodology",
                Status = Draft,
                Title  = "Pupil absence statistics: methodology"
            };

            var request = new UpdateMethodologyRequest
            {
                InternalReleaseNote = null,
                Status = Draft,
                Title  = "Pupil absence statistics (updated): methodology"
            };

            await using (var context = DbUtils.InMemoryApplicationDbContext("Update"))
            {
                context.Add(methodology);
                await context.SaveChangesAsync();
            }

            await using (var context = DbUtils.InMemoryApplicationDbContext("Update"))
            {
                var viewModel = (await BuildMethodologyService(context,
                                                               Mocks())
                                 .UpdateMethodologyAsync(methodology.Id, request)).Right;

                var model = await context.Methodologies.FindAsync(methodology.Id);

                Assert.False(model.Live);
                Assert.Equal("pupil-absence-statistics-updated-methodology", model.Slug);
                Assert.True(model.Updated.HasValue);
                Assert.InRange(DateTime.UtcNow.Subtract(model.Updated.Value).Milliseconds, 0, 1500);

                Assert.Equal(methodology.Id, viewModel.Id);
                Assert.Null(viewModel.InternalReleaseNote);
                Assert.Null(viewModel.Published);
                Assert.Equal(request.Status, viewModel.Status);
                Assert.Equal(request.Title, viewModel.Title);
            }
        }
        public async Task <Either <ActionResult, MethodologySummaryViewModel> > UpdateMethodologyAsync(Guid id,
                                                                                                       UpdateMethodologyRequest request)
        {
            return(await _persistenceHelper.CheckEntityExists <Methodology>(id)
                   .OnSuccess(methodology => CheckCanUpdateMethodologyStatus(methodology, request.Status))
                   .OnSuccess(_userService.CheckCanUpdateMethodology)
                   .OnSuccess(async methodology =>
            {
                if (methodology.Live)
                {
                    // Leave slug
                    return methodology;
                }
                var slug = SlugFromTitle(request.Title);
                return (await ValidateMethodologySlugUniqueForUpdate(methodology.Id, slug)).Map(_ =>
                {
                    methodology.Slug = slug;
                    return methodology;
                });
            })
                   .OnSuccess(async methodology =>
            {
                methodology.InternalReleaseNote = request.InternalReleaseNote ?? methodology.InternalReleaseNote;
                methodology.Status = request.Status;
                methodology.Title = request.Title;
                methodology.Updated = DateTime.UtcNow;

                _context.Methodologies.Update(methodology);
                await _context.SaveChangesAsync();

                if (methodology.Status == MethodologyStatus.Approved && methodology.Live)
                {
                    await _publishingService.MethodologyChanged(methodology.Id);
                }

                return await GetSummaryAsync(id);
            }));
        }