Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix applications update #1192

Merged
merged 3 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions OutOfSchool/OutOfSchool.DataAccess/Models/Application.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using OutOfSchool.Common.Enums;
using OutOfSchool.Services.Enums;

namespace OutOfSchool.Services.Models;
Expand Down Expand Up @@ -30,4 +32,7 @@ public class Application : IKeyedEntity<Guid>
public virtual Child Child { get; set; }

public virtual Parent Parent { get; set; }

[NotMapped]
public static readonly ApplicationStatus[] ValidApplicationStatuses = { ApplicationStatus.Approved, ApplicationStatus.StudyingForYears, ApplicationStatus.Completed};
}
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,126 @@ public async Task UpdateApplication_WhenThereIsNoApplicationWithId_ShouldReturnN
Assert.IsFalse((await service.Update(application, Guid.NewGuid())).Succeeded);
}

[Test]
public async Task UpdateApplication_WhenThereIsAlreadyApprovedWorkshop_ShouldReturnNotSucceeded()
{
// Arrange
var id = new Guid("08da8609-a211-4d74-82c0-dc89ea1fb2a7");
var entity = WithApplication(id);
var changedEntity = WithApplication(id, ApplicationStatus.Approved);
var userId = Guid.NewGuid().ToString();
var workshop = WithWorkshop(new Guid("08da85ea-5b3c-4991-8416-2673d9421ca9"));

applicationRepositoryMock.Setup(a => a.Update(It.IsAny<Application>(), It.IsAny<Action<Application>>()))
.ReturnsAsync(changedEntity);

applicationRepositoryMock.Setup(a => a.GetById(It.IsAny<Guid>())).ReturnsAsync(entity);
applicationRepositoryMock.Setup(a => a.Count(x =>
x.WorkshopId == workshop.Id &&
Application.ValidApplicationStatuses.Contains(x.Status)))
.ReturnsAsync(1);
workshopRepositoryMock.Setup(a => a.GetById(It.IsAny<Guid>())).ReturnsAsync(workshop);
mapper.Setup(m => m.Map<ApplicationDto>(It.IsAny<Application>())).Returns(new ApplicationDto()
{Id = id, Status = ApplicationStatus.Approved});

var expected = new ApplicationDto() {Id = id, Status = ApplicationStatus.Approved};
var update = new ApplicationUpdate
{
Id = id,
Status = ApplicationStatus.Approved,
WorkshopId = new Guid("0083633f-4e5b-4c09-a89d-52d8a9b89cdb"),
ParentId = new Guid("cce7dcbf-991b-4c8e-ba30-4e3cc9e952f3"),
};

workshopServiceCombinerMock.Setup(c =>
c.GetById(It.Is<Guid>(i => i == update.WorkshopId)))
.ReturnsAsync(new WorkshopDTO()
{
Id = update.WorkshopId,
AvailableSeats = 0,
Status = WorkshopStatus.Open,
});

workshopRepositoryMock.Setup(w => w.GetByFilter(It.IsAny<Expression<Func<Workshop, bool>>>(), It.IsAny<string>()))
.ReturnsAsync(new List<Workshop>()
{
new Workshop()
{
Id = update.WorkshopId,
},
});

workshopRepositoryMock.Setup(w => w.GetAvailableSeats(It.IsAny<Guid>())).ReturnsAsync(uint.MaxValue);

currentUserServiceMock.Setup(c => c.UserRole).Returns("provider");
currentUserServiceMock.Setup(c => c.UserSubRole).Returns("");

applicationRepositoryMock.Setup(a => a.Count(It.IsAny<Expression<Func<Application, bool>>>())).ReturnsAsync(int.MaxValue);

// Act and Assert
Assert.False((await service.Update(update, Guid.NewGuid())).Succeeded);
}

[Test]
public async Task UpdateApplication_WhenThereIsNoAlreadyApprovedWorkshop_Succeeded()
{
// Arrange
var id = new Guid("08da8609-a211-4d74-82c0-dc89ea1fb2a7");
var entity = WithApplication(id);
var changedEntity = WithApplication(id, ApplicationStatus.Approved);
var userId = Guid.NewGuid().ToString();
var workshop = WithWorkshop(new Guid("08da85ea-5b3c-4991-8416-2673d9421ca9"));

applicationRepositoryMock.Setup(a => a.Update(It.IsAny<Application>(), It.IsAny<Action<Application>>()))
.ReturnsAsync(changedEntity);

applicationRepositoryMock.Setup(a => a.GetById(It.IsAny<Guid>())).ReturnsAsync(entity);
applicationRepositoryMock.Setup(a => a.Count(x =>
x.WorkshopId == workshop.Id &&
Application.ValidApplicationStatuses.Contains(x.Status)))
.ReturnsAsync(1);
workshopRepositoryMock.Setup(a => a.GetById(It.IsAny<Guid>())).ReturnsAsync(workshop);
mapper.Setup(m => m.Map<ApplicationDto>(It.IsAny<Application>())).Returns(new ApplicationDto()
{Id = id, Status = ApplicationStatus.Approved});

var expected = new ApplicationDto() {Id = id, Status = ApplicationStatus.Approved};
var update = new ApplicationUpdate
{
Id = id,
Status = ApplicationStatus.Approved,
WorkshopId = new Guid("0083633f-4e5b-4c09-a89d-52d8a9b89cdb"),
ParentId = new Guid("cce7dcbf-991b-4c8e-ba30-4e3cc9e952f3"),
};

workshopServiceCombinerMock.Setup(c =>
c.GetById(It.Is<Guid>(i => i == update.WorkshopId)))
.ReturnsAsync(new WorkshopDTO()
{
Id = update.WorkshopId,
AvailableSeats = 0,
Status = WorkshopStatus.Open,
});

workshopRepositoryMock.Setup(w => w.GetByFilter(It.IsAny<Expression<Func<Workshop, bool>>>(), It.IsAny<string>()))
.ReturnsAsync(new List<Workshop>()
{
new Workshop()
{
Id = update.WorkshopId,
},
});

workshopRepositoryMock.Setup(w => w.GetAvailableSeats(It.IsAny<Guid>())).ReturnsAsync(uint.MaxValue);

currentUserServiceMock.Setup(c => c.UserRole).Returns("provider");
currentUserServiceMock.Setup(c => c.UserSubRole).Returns("");

applicationRepositoryMock.Setup(a => a.Count(It.IsAny<Expression<Func<Application, bool>>>())).ReturnsAsync(int.MinValue);

// Act and Assert
Assert.True((await service.Update(update, Guid.NewGuid())).Succeeded);
}

[Test]
public void UpdateApplication_WhenModelIsNull_ShouldThrowArgumentException()
{
Expand Down
23 changes: 19 additions & 4 deletions OutOfSchool/OutOfSchool.WebApi/Services/ApplicationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -835,8 +835,7 @@ await currentUserService.UserHasRights(
new ParentRights(applicationDto.ParentId),
new ProviderRights(providerId),
new ProviderAdminWorkshopRights(providerId, applicationDto.WorkshopId));

var currentApplication = CheckApplicationExists(applicationDto.Id);
var currentApplication = this.CheckApplicationExists(applicationDto.Id);

if (currentApplication is null)
{
Expand All @@ -856,7 +855,7 @@ await currentUserService.UserHasRights(
return Result<ApplicationDto>.Success(mapper.Map<ApplicationDto>(currentApplication));
}

if (applicationDto.Status == ApplicationStatus.Approved)
if (Application.ValidApplicationStatuses.Contains(applicationDto.Status))
{
var providerOwnership = await workshopRepository.GetByFilter(predicate: w => w.Id == currentApplication.WorkshopId && w.Provider.Ownership != OwnershipType.State, includeProperties: "Provider");

Expand All @@ -873,6 +872,15 @@ await currentUserService.UserHasRights(
Description = "The Workshop is full.",
});
}

if (await GetApprovedWorkshopAndChild(currentApplication) >= 1)
{
return Result<ApplicationDto>.Failed(new OperationError
{
Code = "400",
Description = "There is already approved workshop.",
});
}
}
}

Expand Down Expand Up @@ -913,6 +921,13 @@ await notificationService.Create(

private async Task<int> GetAmountOfApprovedApplications(Guid workshopId)
{
return await applicationRepository.Count(x => x.WorkshopId == workshopId && x.Status == ApplicationStatus.Approved);
return await applicationRepository.Count(x => x.WorkshopId == workshopId && Application.ValidApplicationStatuses.Contains(x.Status));
}

private async Task<int> GetApprovedWorkshopAndChild(Application application)
{
return await applicationRepository.Count(a => application.ChildId == a.ChildId &&
application.WorkshopId == a.WorkshopId &&
Application.ValidApplicationStatuses.Contains(a.Status));
}
}
Loading