浏览代码

UI when "table view" is disabled

feature/1522_UI_when_table_view_is_disabled-be
Dzenis Hadzifejzovic 3 年前
父节点
当前提交
323b0ab012
共有 22 个文件被更改,包括 523 次插入119 次删除
  1. 61
    0
      Diligent.WebAPI.Business/Extensions/ApplicantExtensions.cs
  2. 16
    0
      Diligent.WebAPI.Business/Extensions/HttpExtensions.cs
  3. 1
    0
      Diligent.WebAPI.Business/MappingProfiles/AdMappingProfile.cs
  4. 1
    0
      Diligent.WebAPI.Business/MappingProfiles/ApplicantMappingProfile.cs
  5. 52
    18
      Diligent.WebAPI.Business/Services/ApplicantService.cs
  6. 2
    1
      Diligent.WebAPI.Business/Services/Interfaces/IApplicantService.cs
  7. 12
    0
      Diligent.WebAPI.Contracts/DTOs/Ad/AdApplicantsViewDto.cs
  8. 15
    0
      Diligent.WebAPI.Contracts/DTOs/Applicant/AdApplicantViewDto.cs
  9. 5
    1
      Diligent.WebAPI.Contracts/DTOs/Applicant/ApplicantCreateDto.cs
  10. 14
    0
      Diligent.WebAPI.Contracts/DTOs/Applicant/ApplicantFilterDto.cs
  11. 1
    0
      Diligent.WebAPI.Contracts/DTOs/Applicant/ApplicantViewDto.cs
  12. 8
    0
      Diligent.WebAPI.Contracts/Models/Pagination.cs
  13. 1
    0
      Diligent.WebAPI.Data/Configurations/ApplicantConfiguration.cs
  14. 6
    0
      Diligent.WebAPI.Data/Entities/Applicant.cs
  15. 15
    15
      Diligent.WebAPI.Data/Migrations/DatabaseContextModelSnapshot.cs
  16. 22
    10
      Diligent.WebAPI.Host/Controllers/V1/ApplicantsController.cs
  17. 1
    0
      Diligent.WebAPI.Host/Extensions/HostConfigurationExtension.cs
  18. 24
    17
      Diligent.WebAPI.Tests/Controllers/ApplicantsControllerTests.cs
  19. 17
    0
      Diligent.WebAPI.Tests/Controllers/CommentsControllerTests.cs
  20. 118
    0
      Diligent.WebAPI.Tests/MockData.cs
  21. 81
    57
      Diligent.WebAPI.Tests/Services/ApplicantServiceTests.cs
  22. 50
    0
      Diligent.WebAPI.Tests/Services/CommentServiceTests.cs

+ 61
- 0
Diligent.WebAPI.Business/Extensions/ApplicantExtensions.cs 查看文件

@@ -0,0 +1,61 @@
using static Diligent.WebAPI.Data.Entities.Applicant;

namespace Diligent.WebAPI.Business.Extensions
{
public static class ApplicantExtensions
{
public static IQueryable<Applicant> FilterByExperience(this IQueryable<Applicant> query, int minExperience, int maxExperience)
{
if (minExperience == 0 && maxExperience == 0 || minExperience > maxExperience) return query;
return query.Where(x => x.Experience >= minExperience && x.Experience < maxExperience);
}


public static IQueryable<Applicant> FilterByEmploymentType(this IQueryable<Applicant> query, string? employmentType)
{
if (employmentType == null) return query;
return query.Where(x => x.TypeOfEmployment == Enum.Parse<TypesOfEmployment>(employmentType));
}

public static IQueryable<Applicant> FilterByDateOfApplication(this IQueryable<Applicant> query, DateTime? minDateOfApplication, DateTime? maxDateOfApplication)
{
if (minDateOfApplication == null) return query;
if (minDateOfApplication > maxDateOfApplication) return query;
if (maxDateOfApplication == null) return query.Where(x => x.DateOfApplication >= minDateOfApplication && x.DateOfApplication <= DateTime.Now);
return query.Where(x => x.DateOfApplication >= minDateOfApplication && x.DateOfApplication < maxDateOfApplication);
}

public static List<Applicant> FilterByTechnologies(this List<Applicant> query, string[]? technologies)
{
if (technologies is null)
{
return query;
}

List<Applicant> filteredApplicants = new();

for (int i = 0; i < query.Count; i++)
{
for (int j = 0; j < query[i].TechnologyApplicants.Count; j++)
{
bool s = false;
for (int n = 0; n < technologies.Length; n++)
{
if (query[i].TechnologyApplicants[j].Technology.Name.ToLower() == technologies[n].ToLower())
{
s = true;
break;
}
}
if (s)
{
filteredApplicants.Add(query[i]);
break;
}
}
}

return filteredApplicants;
}
}
}

+ 16
- 0
Diligent.WebAPI.Business/Extensions/HttpExtensions.cs 查看文件

@@ -0,0 +1,16 @@
using System.Text.Json;
using Microsoft.AspNetCore.Http;

namespace Diligent.WebAPI.Business.Extensions
{
public static class HttpExtensions
{
//extension method for setting header in response
public static void AddHeader(this HttpResponse response, string headerName, int number)
{
var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; //we want to store content inside header of response in CamelCase format
response.Headers.Add("Pagination", System.Text.Json.JsonSerializer.Serialize(number, options));
response.Headers.Add("Access-Control-Expose-Headers", headerName); //giving permission for accessing Pagination header to our client
}
}
}

+ 1
- 0
Diligent.WebAPI.Business/MappingProfiles/AdMappingProfile.cs 查看文件

@@ -13,6 +13,7 @@ namespace Diligent.WebAPI.Business.MappingProfiles
#region Model to DTO
CreateMap<Ad, AdResponseDto>();
CreateMap<Ad, AdDetailsResponseDto>();
CreateMap<Ad, AdApplicantsViewDto>();
#endregion
}
}

+ 1
- 0
Diligent.WebAPI.Business/MappingProfiles/ApplicantMappingProfile.cs 查看文件

@@ -8,6 +8,7 @@ namespace Diligent.WebAPI.Business.MappingProfiles
{
#region Models to DTOs
CreateMap<Applicant, ApplicantViewDto>();
CreateMap<Applicant, AdApplicantViewDto>();
#endregion

#region DTOs to Models

+ 52
- 18
Diligent.WebAPI.Business/Services/ApplicantService.cs 查看文件

@@ -1,4 +1,5 @@
using Diligent.WebAPI.Contracts.DTOs.Applicant;
using Diligent.WebAPI.Business.Extensions;
using Microsoft.AspNetCore.Http;

namespace Diligent.WebAPI.Business.Services
{
@@ -6,17 +7,40 @@ namespace Diligent.WebAPI.Business.Services
{
private readonly DatabaseContext _context;
private readonly IMapper _mapper;
private readonly IHttpContextAccessor _httpContextAccessor;

public ApplicantService(DatabaseContext context,IMapper mapper)
public ApplicantService(DatabaseContext context, IMapper mapper, IHttpContextAccessor httpContextAccessor)
{
_context = context;
_mapper = mapper;
_httpContextAccessor = httpContextAccessor;
}

public async Task<List<ApplicantViewDto>> GetAll()
public async Task<List<ApplicantViewDto>> GetFilteredApplicants(ApplicantFilterDto applicantFilterDto)
{
var applicants = await _context.Applicants.Include(c => c.Ads).ToListAsync();
return _mapper.Map<List<ApplicantViewDto>>(applicants);

int applicantsToSkip = (applicantFilterDto.CurrentPage - 1) * applicantFilterDto.PageSize;

var context = _httpContextAccessor.HttpContext;

var allApplicants = _context.Applicants
.Include(c => c.Ads)
.Include(x => x.TechnologyApplicants)
.ThenInclude(x => x.Technology);

context.Response.AddHeader("Pagination", allApplicants.ToList().Count);

var filteredApplicants = await allApplicants
.FilterByExperience(applicantFilterDto.MinExperience, applicantFilterDto.MaxExperience)
.FilterByEmploymentType(applicantFilterDto.EmploymentType)
.FilterByDateOfApplication(applicantFilterDto.MinDateOfApplication, applicantFilterDto.MaxDateOfApplication)
.Skip(applicantsToSkip)
.Take(applicantFilterDto.PageSize)
.ToListAsync();

filteredApplicants = filteredApplicants.FilterByTechnologies(applicantFilterDto.Technologies);

return _mapper.Map<List<ApplicantViewDto>>(filteredApplicants);
}

public async Task<ApplicantViewDto> GetById(int id)
@@ -35,18 +59,6 @@ namespace Diligent.WebAPI.Business.Services

return _mapper.Map<ApplicantViewDto>(applicant);
}
public async Task<ApplicantViewDto> GetApplicantWithSelectionProcessesById(int id)
{
var applicant = await _context.Applicants
.Include(a => a.SelectionProcesses).ThenInclude(sp => sp.SelectionLevel)
.Include(a => a.SelectionProcesses).ThenInclude(sp => sp.Scheduler)
.FirstOrDefaultAsync(a => a.ApplicantId == id);

if (applicant is null)
throw new EntityNotFoundException("Applicant not found");

return _mapper.Map<ApplicantViewDto>(applicant);
}
public async Task CreateApplicant(ApplicantCreateDto applicantCreateDto)
{
var applicant = _mapper.Map<Applicant>(applicantCreateDto);
@@ -59,7 +71,7 @@ namespace Diligent.WebAPI.Business.Services
{
var applicant = await _context.Applicants.FindAsync(id);

if(applicant is null)
if (applicant is null)
throw new EntityNotFoundException("Applicant not found");

_context.Applicants.Remove(applicant);
@@ -77,5 +89,27 @@ namespace Diligent.WebAPI.Business.Services
_context.Entry(applicant).State = EntityState.Modified;
await _context.SaveChangesAsync();
}

public async Task<List<AdApplicantsViewDto>> GetAllAdsApplicants()
{
var adsApplicants = await _context.Ads
.Include(a => a.Applicants)
.ThenInclude(a => a.TechnologyApplicants).ThenInclude(a => a.Technology).ToListAsync();

return _mapper.Map<List<AdApplicantsViewDto>>(adsApplicants);
}

public async Task<ApplicantViewDto> GetApplicantWithSelectionProcessesById(int id)
{
var applicant = await _context.Applicants
.Include(a => a.SelectionProcesses).ThenInclude(sp => sp.SelectionLevel)
.Include(a => a.SelectionProcesses).ThenInclude(sp => sp.Scheduler)
.FirstOrDefaultAsync(a => a.ApplicantId == id);

if (applicant is null)
throw new EntityNotFoundException("Applicant not found");

return _mapper.Map<ApplicantViewDto>(applicant);
}
}
}

+ 2
- 1
Diligent.WebAPI.Business/Services/Interfaces/IApplicantService.cs 查看文件

@@ -3,7 +3,8 @@ namespace Diligent.WebAPI.Business.Services.Interfaces
{
public interface IApplicantService
{
Task<List<ApplicantViewDto>> GetAll();
Task<List<ApplicantViewDto>> GetFilteredApplicants(ApplicantFilterDto applicantFilterDto);
Task<List<AdApplicantsViewDto>> GetAllAdsApplicants();
Task<ApplicantViewDto> GetById(int id);
Task<ApplicantViewDto> GetApplicantWithSelectionProcessesById(int id);
Task CreateApplicant(ApplicantCreateDto applicantCreateDto);

+ 12
- 0
Diligent.WebAPI.Contracts/DTOs/Ad/AdApplicantsViewDto.cs 查看文件

@@ -0,0 +1,12 @@
using Diligent.WebAPI.Contracts.DTOs.Applicant;

namespace Diligent.WebAPI.Contracts.DTOs.Ad
{
public class AdApplicantsViewDto
{
public int Id { get; set; }
public string Title { get; set; }
public List<AdApplicantViewDto> Applicants { get; set; }
public int NubmerOfApplicants { get { return Applicants.Count; } }
}
}

+ 15
- 0
Diligent.WebAPI.Contracts/DTOs/Applicant/AdApplicantViewDto.cs 查看文件

@@ -0,0 +1,15 @@
using Diligent.WebAPI.Contracts.DTOs.Technology;

namespace Diligent.WebAPI.Contracts.DTOs.Applicant
{
public class AdApplicantViewDto
{
public int ApplicantId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfApplication { get; set; }
public string CV { get; set; }
public int Experience { get; set; }
public List<TechnologyViewDto> TechnologyApplicants { get; set; } = new();
}
}

+ 5
- 1
Diligent.WebAPI.Contracts/DTOs/Applicant/ApplicantCreateDto.cs 查看文件

@@ -1,4 +1,6 @@
namespace Diligent.WebAPI.Contracts.DTOs.Applicant
using Diligent.WebAPI.Contracts.DTOs.SelectionProcess;

namespace Diligent.WebAPI.Contracts.DTOs.Applicant
{
public class ApplicantCreateDto
{
@@ -13,5 +15,7 @@
public string BitBucketLink { get; set; }
public int Experience { get; set; }
public string ApplicationChannel { get; set; }
public string TypeOfEmployment { get; set; }
public List<SelectionProcessCreateDto> SelectionProcesses { get; set; }
}
}

+ 14
- 0
Diligent.WebAPI.Contracts/DTOs/Applicant/ApplicantFilterDto.cs 查看文件

@@ -0,0 +1,14 @@
namespace Diligent.WebAPI.Contracts.DTOs.Applicant
{
public class ApplicantFilterDto
{
public int MinExperience { get; set; }
public int MaxExperience { get; set; }
public string[]? Technologies { get; set; }
public string? EmploymentType { get; set; }
public DateTime? MinDateOfApplication { get; set; }
public DateTime? MaxDateOfApplication { get; set; }
public int PageSize { get; set; }
public int CurrentPage { get; set; }
}
}

+ 1
- 0
Diligent.WebAPI.Contracts/DTOs/Applicant/ApplicantViewDto.cs 查看文件

@@ -20,6 +20,7 @@ namespace Diligent.WebAPI.Contracts.DTOs.Applicant
public string BitBucketLink { get; set; }
public int Experience { get; set; }
public string ApplicationChannel { get; set; }
public string TypeOfEmployment { get; set; }
public List<TechnologyViewDto> TechnologyApplicants { get; set; } = new();
public List<CommentViewDto> Comments { get; set; }
public List<AdResponseDto> Ads { get; set; }

+ 8
- 0
Diligent.WebAPI.Contracts/Models/Pagination.cs 查看文件

@@ -0,0 +1,8 @@
namespace Diligent.WebAPI.Contracts.Models
{
public class Pagination
{
public int CurrentPage { get; set; }
public int PageSize { get; set; }
}
}

+ 1
- 0
Diligent.WebAPI.Data/Configurations/ApplicantConfiguration.cs 查看文件

@@ -17,6 +17,7 @@ namespace Diligent.WebAPI.Data.Configurations
builder.Property(c => c.GithubLink).IsRequired(false);
builder.Property(c => c.BitBucketLink).IsRequired(false);
builder.Property(c => c.ApplicationChannel).IsRequired(false);
builder.Property(c => c.TypeOfEmployment).IsRequired(true).HasConversion<string>();
}
}
}

+ 6
- 0
Diligent.WebAPI.Data/Entities/Applicant.cs 查看文件

@@ -2,6 +2,11 @@
{
public class Applicant
{
public enum TypesOfEmployment
{
Posao,
Intership
};
public int ApplicantId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
@@ -15,6 +20,7 @@
public string BitBucketLink { get; set; }
public int Experience { get; set; }
public string ApplicationChannel { get; set; }
public TypesOfEmployment TypeOfEmployment { get; set; }
public List<TechnologyApplicant> TechnologyApplicants { get; set; }
public List<Comment> Comments { get; set; }
public List<Ad> Ads { get; set; }

+ 15
- 15
Diligent.WebAPI.Data/Migrations/DatabaseContextModelSnapshot.cs 查看文件

@@ -34,7 +34,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("ApplicantsApplicantId");

b.ToTable("AdApplicant");
b.ToTable("AdApplicant", (string)null);
});

modelBuilder.Entity("AdTechnology", b =>
@@ -49,7 +49,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("TechnologiesTechnologyId");

b.ToTable("AdTechnology");
b.ToTable("AdTechnology", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Ad", b =>
@@ -95,7 +95,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("Id");

b.ToTable("Ads");
b.ToTable("Ads", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Applicant", b =>
@@ -155,7 +155,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("ApplicantId");

b.ToTable("Applicants");
b.ToTable("Applicants", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.AppRole", b =>
@@ -216,7 +216,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("UserId");

b.ToTable("Comments");
b.ToTable("Comments", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsuranceCompany", b =>
@@ -270,7 +270,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("Id");

b.ToTable("InsuranceCompanies");
b.ToTable("InsuranceCompanies", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.InsurancePolicy", b =>
@@ -310,7 +310,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("InsurerId");

b.ToTable("InsurancePolicies");
b.ToTable("InsurancePolicies", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Insurer", b =>
@@ -372,7 +372,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("InsuranceCompanyId");

b.ToTable("Insurers");
b.ToTable("Insurers", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.RefreshToken", b =>
@@ -410,7 +410,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("UserId");

b.ToTable("RefreshTokens");
b.ToTable("RefreshTokens", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.SelectionLevel", b =>
@@ -427,7 +427,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("Id");

b.ToTable("SelectionLevels");
b.ToTable("SelectionLevels", (string)null);

b.HasData(
new
@@ -491,7 +491,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("SelectionLevelId");

b.ToTable("SelectionProcesses");
b.ToTable("SelectionProcesses", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.Technology", b =>
@@ -513,7 +513,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("TechnologyId");

b.ToTable("Technologies");
b.ToTable("Technologies", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.TechnologyApplicant", b =>
@@ -536,7 +536,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("TechnologyId");

b.ToTable("ApplicantTechnologies");
b.ToTable("ApplicantTechnologies", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.User", b =>
@@ -656,7 +656,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasKey("Id");

b.ToTable("WebhookDefinitions");
b.ToTable("WebhookDefinitions", (string)null);
});

modelBuilder.Entity("Diligent.WebAPI.Data.Entities.WebhookSubscription", b =>
@@ -690,7 +690,7 @@ namespace Diligent.WebAPI.Data.Migrations

b.HasIndex("WebhookDefinitionId");

b.ToTable("WebhookSubscriptions");
b.ToTable("WebhookSubscriptions", (string)null);
});

modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>

+ 22
- 10
Diligent.WebAPI.Host/Controllers/V1/ApplicantsController.cs 查看文件

@@ -1,9 +1,11 @@
namespace Diligent.WebAPI.Host.Controllers.V1
using Diligent.WebAPI.Contracts.DTOs.Applicant;

namespace Diligent.WebAPI.Host.Controllers.V1
{
[ApiVersion("1.0")]
[Route("v{version:apiVersion}/applicants")]
[ApiController]
public class ApplicantsController:ControllerBase
public class ApplicantsController : ControllerBase
{
private readonly IApplicantService _applicantService;

@@ -12,18 +14,27 @@
_applicantService = applicantService;
}

//[Authorize]
[HttpGet]
public async Task<IActionResult> GetAll()
{
return Ok(await _applicantService.GetAll());
}
public async Task<IActionResult> GetFilteredApplicants([FromQuery] ApplicantFilterDto applicantFilterDto) =>
Ok(await _applicantService.GetFilteredApplicants(applicantFilterDto));

//[Authorize]
[Authorize]
[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
public async Task<IActionResult> GetById(int id) =>
Ok(await _applicantService.GetById(id));


[Authorize]
[HttpGet("adsApplicants")]
public async Task<IActionResult> GetAllAdsApplicants() =>
Ok(await _applicantService.GetAllAdsApplicants());

[Authorize]
[HttpDelete]
public async Task<IActionResult> DeleteApplicant(int id)
{
return Ok(await _applicantService.GetById(id));
await _applicantService.DeleteApplicant(id);
return Ok();
}

[HttpGet("processes/{id}")]
@@ -31,5 +42,6 @@
{
return Ok(await _applicantService.GetApplicantWithSelectionProcessesById(id));
}

}
}

+ 1
- 0
Diligent.WebAPI.Host/Extensions/HostConfigurationExtension.cs 查看文件

@@ -15,6 +15,7 @@
builder.ConfigureSwagger();

IServiceCollection services = builder.Services;
services.AddHttpContextAccessor();
services.AddControllers();
services.AddEndpointsApiExplorer();
}

+ 24
- 17
Diligent.WebAPI.Tests/Controllers/ApplicantsControllerTests.cs 查看文件

@@ -36,56 +36,63 @@ namespace Diligent.WebAPI.Tests.Controllers
}

[Fact]
public async Task GetById_ShouldReturn_200OK_WhenApplicantExist()
public async Task GetProcesses_ShouldReturn_200OK_WhenApplicantExists()
{
_applicantService.GetById(Arg.Any<int>()).Returns(_applicant);
_applicantService.GetApplicantWithSelectionProcessesById(Arg.Any<int>()).Returns(_applicant);
ApplicantsController applicantsController = new(_applicantService);

var result = await applicantsController.GetById(1);
var result = await applicantsController.GetProcesses(1);

(result as OkObjectResult).StatusCode.Should().Be(200);
}

[Fact]
public async Task GetProcesses_ShouldReturn_200OK_WhenApplicantExists()
public async Task GetProcesses_ShouldThrowEntityNotFooundException_WhenApplicantDoesnotExist()
{
_applicantService.GetApplicantWithSelectionProcessesById(Arg.Any<int>()).Returns(_applicant);
_applicantService.When(x => x.GetApplicantWithSelectionProcessesById(Arg.Any<int>())).Do(x => { throw new EntityNotFoundException(); });
ApplicantsController applicantsController = new(_applicantService);

var result = await applicantsController.GetProcesses(1);

(result as OkObjectResult).StatusCode.Should().Be(200);
await Assert.ThrowsAsync<EntityNotFoundException>(() => applicantsController.GetProcesses(1000));
}

[Fact]
public async Task GetById_ShouldThrowEntityNotFooundException_WhenApplicantDontExist()
public async Task GetById_ShouldReturn_200OK_WhenApplicantExist()
{
_applicantService.When(x => x.GetById(Arg.Any<int>())).Do(x => { throw new EntityNotFoundException(); });
_applicantService.GetById(Arg.Any<int>()).Returns(_applicant);
ApplicantsController applicantsController = new(_applicantService);

await Assert.ThrowsAsync<EntityNotFoundException>(() => applicantsController.GetById(1000));
var result = await applicantsController.GetById(1);

(result as OkObjectResult).StatusCode.Should().Be(200);
}

[Fact]
public async Task GetProcesses_ShouldThrowEntityNotFooundException_WhenApplicantDoesnotExist()
public async Task GetById_ShouldThrowEntityNotFooundException_WhenApplicantDontExist()
{
_applicantService.When(x => x.GetApplicantWithSelectionProcessesById(Arg.Any<int>())).Do(x => { throw new EntityNotFoundException(); });
_applicantService.When(x => x.GetById(Arg.Any<int>())).Do(x => { throw new EntityNotFoundException(); });
ApplicantsController applicantsController = new(_applicantService);

await Assert.ThrowsAsync<EntityNotFoundException>(() => applicantsController.GetProcesses(1000));
await Assert.ThrowsAsync<EntityNotFoundException>(() => applicantsController.GetById(1000));
}

[Fact]
public async Task GetAll_ShouldReturn_200OK_Always()
public async Task GetFilteredApplicants_ShouldReturn_200OK_Always()
{
var applicants = new List<ApplicantViewDto>
{
_applicant
};
_applicantService.GetAll().Returns(applicants);

var filterDto = new ApplicantFilterDto
{
CurrentPage = 1,
PageSize = 4
};

_applicantService.GetFilteredApplicants(filterDto).Returns(applicants);
ApplicantsController applicantsController = new(_applicantService);

var result = await applicantsController.GetAll();
var result = await applicantsController.GetFilteredApplicants(filterDto);

(result as OkObjectResult).StatusCode.Should().Be(200);
}

+ 17
- 0
Diligent.WebAPI.Tests/Controllers/CommentsControllerTests.cs 查看文件

@@ -0,0 +1,17 @@
namespace Diligent.WebAPI.Tests.Controllers
{
public class CommentsControllerTests
{
private ICommentService _commentService = Substitute.For<ICommentService>();
public CommentsControllerTests()
{

}

//[Fact]
//public async AddComment_ShouldReturn_200_Created_Always()
//{
// _commentService.Add
//}
}
}

+ 118
- 0
Diligent.WebAPI.Tests/MockData.cs 查看文件

@@ -0,0 +1,118 @@
using Diligent.WebAPI.Data.Entities;

namespace Diligent.WebAPI.Tests
{
public static class MockData
{
public static List<Applicant> GetListOfApplicants()
{
var applicant = new Applicant
{
ApplicantId = 1,
ApplicationChannel = "Instagram",
BitBucketLink = null,
CV = "link",
DateOfApplication = DateTime.Now,
Email = "some@mail.com",
Experience = 1,
FirstName = "Dzenis",
LastName = "Hadzifejzovic",
GithubLink = null,
LinkedlnLink = null,
PhoneNumber = "432424",
Position = ".NET Developer",
TypeOfEmployment = Applicant.TypesOfEmployment.Intership,
SelectionProcesses = new List<SelectionProcess>
{
new SelectionProcess{ Id = 1, Status = "", Name = ""},
new SelectionProcess{ Id = 2, Status = "", Name = ""},
new SelectionProcess{ Id = 3, Status = "", Name = ""}
}
};
var applicants = new List<Applicant>
{
applicant
};

return applicants;
}

public static List<SelectionProcess> GetListOfSelectionProcess()
{
var selectionProcess = new SelectionProcess
{
Applicant = GetListOfApplicants()[0],
Date = DateTime.Now,
Link = "dasda",
Name = "adsda",
SelectionLevelId = 1,
Status = "completed"
};

var selectionProcesses = new List<SelectionProcess>
{
selectionProcess
};

return selectionProcesses;
;
}
public static List<Ad> GetListOfAds()
{
var ad = new Ad
{
Applicants = GetListOfApplicants(),
CreatedAt = DateTime.Now,
ExpiredAt = DateTime.Now.AddDays(5),
MinimumExperience = 1,
Title = ".NET Intern",
KeyResponsibilities = "dasdadas",
Offer = "dsadsada",
Requirements = "dsadsadas"
};

var ads = new List<Ad>
{
ad
};

return ads;
}

public static List<User> GetListOfUsers()
{
var user = new User
{
FirstName = "Dzenis",
Email = "dzenis@gmail.com",
LastName = "Hadzifejzovic",
UserName = "dzenis12"
};

var users = new List<User>
{
user
};

return users;
}

public static List<Comment> GetListOfComments()
{
var comment = new Comment
{
Applicant = GetListOfApplicants()[0],
Content = "dsadsad",
DateOfSending = DateTime.Now,
User = GetListOfUsers()[0],
};

var comments = new List<Comment>
{
comment
};

return comments;
}
}
}

+ 81
- 57
Diligent.WebAPI.Tests/Services/ApplicantServiceTests.cs 查看文件

@@ -1,97 +1,80 @@
using AutoMapper;
using Diligent.WebAPI.Business.Extensions;
using Diligent.WebAPI.Business.MappingProfiles;
using Diligent.WebAPI.Business.Services;
using Diligent.WebAPI.Contracts.DTOs.Ad;
using Diligent.WebAPI.Contracts.DTOs.Applicant;
using Diligent.WebAPI.Contracts.DTOs.SelectionProcess;
using Diligent.WebAPI.Contracts.Exceptions;
using Diligent.WebAPI.Data.Entities;
using Microsoft.AspNetCore.Http;
using static Diligent.WebAPI.Data.Entities.Applicant;

namespace Diligent.WebAPI.Tests.Services
{
public class ApplicantServiceTests
{
private readonly IMapper _mapper;
private readonly IHttpContextAccessor _httpContextAccessor = Substitute.For<IHttpContextAccessor>();
private readonly HttpContext _httpContext;
private readonly List<Applicant> _applicants;
private readonly Applicant _applicant;
private readonly List<Ad> _ads;
private readonly List<SelectionProcess> _selectionProcesses;
public ApplicantServiceTests()
{
_applicant = new Applicant
{
ApplicantId = 1,
ApplicationChannel = "Instagram",
BitBucketLink = null,
CV = "link",
DateOfApplication = DateTime.Now,
Email = "some@mail.com",
Experience = 1,
FirstName = "Dzenis",
LastName = "Hadzifejzovic",
GithubLink = null,
LinkedlnLink = null,
PhoneNumber = "432424",
Position = ".NET Developer",
SelectionProcesses = new List<SelectionProcess>
{
new SelectionProcess{ Id = 1, Status = "", Name = ""},
new SelectionProcess{ Id = 2, Status = "", Name = ""},
new SelectionProcess{ Id = 3, Status = "", Name = ""}
}
};
_applicants = new List<Applicant>
{
_applicant
};
_applicants = MockData.GetListOfApplicants();

_ads = MockData.GetListOfAds();

// configure mapper
var configuration = new MapperConfiguration(cfg => cfg.AddProfiles(
new List<Profile>
{
new ApplicantMappingProfile(),
new SelectionProcessMappingProfile(),
new AdMappingProfile(),
new SelectionProcessMappingProfile()
}));
_mapper = new Mapper(configuration);
_httpContext = new DefaultHttpContext();
}

[Fact]
public async Task GetAll_ShouldReturnListOfApplicants_Always()
public async Task GetFilteredApplicants_ShouldReturnListOfApplicants_Always()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper);

var result = await applicantService.GetAll();
_httpContextAccessor.HttpContext.Returns(_httpContext);

result.Should().BeEquivalentTo(_mapper.Map<List<ApplicantViewDto>>(_applicants));
}
ApplicantService applicantService = new(databaseContext, _mapper, _httpContextAccessor);

[Fact]
public async Task GetById_ShouldReturnApplicant_WhenApplicantExist()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper);
var filterDto = new ApplicantFilterDto
{
CurrentPage = 1,
PageSize = 4
};

var result = await applicantService.GetById(1);
var result = await applicantService.GetFilteredApplicants(filterDto);

result.Should().BeEquivalentTo(_mapper.Map<ApplicantViewDto>(_applicant));
Assert.Equal(_httpContext.Response.Headers["Pagination"], result.Count.ToString());
result.Should().BeEquivalentTo(_mapper.Map<List<ApplicantViewDto>>(_applicants));
}

[Fact]
public async Task GetApplicantWithSelectionProcessesById_ShouldReturnApplicant_WhenApplicantExists()
public async Task GetById_ShouldReturnApplicant_WhenApplicantExist()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper);
ApplicantService applicantService = new(databaseContext, _mapper, _httpContextAccessor);

var result = await applicantService.GetApplicantWithSelectionProcessesById(1);
var processes = result.SelectionProcesses;
var result = await applicantService.GetById(1);

processes.Should().HaveCount(3);
result.Should().BeEquivalentTo(_mapper.Map<ApplicantViewDto>(_applicant));
result.Should().BeEquivalentTo(_mapper.Map<ApplicantViewDto>(_applicants[0]));
}

[Fact]
public async Task GetById_ShouldThrowEntityNotFooundException_WhenApplicantDontExist()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper);
ApplicantService applicantService = new(databaseContext, _mapper, _httpContextAccessor);

await Assert.ThrowsAsync<EntityNotFoundException>(async () => await applicantService.GetById(1000));
}
@@ -100,7 +83,7 @@ namespace Diligent.WebAPI.Tests.Services
public async Task CreateApplicant_ShouldAddEntityIntoDatabase_Always()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper);
ApplicantService applicantService = new(databaseContext, _mapper, _httpContextAccessor);

ApplicantCreateDto applicantCreateDto = new()
{
@@ -114,24 +97,39 @@ namespace Diligent.WebAPI.Tests.Services
GithubLink = null,
LinkedlnLink = null,
PhoneNumber = "432424",
Position = ".NET Developer"
Position = ".NET Developer",
TypeOfEmployment = TypesOfEmployment.Intership.ToString(),
SelectionProcesses = _mapper.Map<List<SelectionProcessCreateDto>>(_selectionProcesses)
};

await applicantService.CreateApplicant(applicantCreateDto);

var applicants = await applicantService.GetAll();
var filterDto = new ApplicantFilterDto
{
CurrentPage = 1,
PageSize = 4
};

var result = await applicantService.GetFilteredApplicants(filterDto);

Assert.Equal(2, applicants.Count);
Assert.Equal(2, result.Count);
}

[Fact]
public async Task DeleteApplicant_ShouldDeleteApplicant_WhenApplicantExist()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper);
ApplicantService applicantService = new(databaseContext, _mapper, _httpContextAccessor);

await applicantService.DeleteApplicant(1);
var applicants = await applicantService.GetAll();

var filterDto = new ApplicantFilterDto
{
CurrentPage = 1,
PageSize = 4
};

var applicants = await applicantService.GetFilteredApplicants(filterDto);

Assert.Empty(applicants);
}
@@ -140,7 +138,7 @@ namespace Diligent.WebAPI.Tests.Services
public async Task DeleteApplicant_ShouldThrowEntityNotFooundException_WhenApplicantDontExist()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper);
ApplicantService applicantService = new(databaseContext, _mapper, _httpContextAccessor);

await Assert.ThrowsAsync<EntityNotFoundException>(async () => await applicantService.DeleteApplicant(1000));
}
@@ -149,7 +147,7 @@ namespace Diligent.WebAPI.Tests.Services
public async Task UpdateApplicant_ShouldUpdateApplicant_WhenApplicantExist()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper);
ApplicantService applicantService = new(databaseContext, _mapper, _httpContextAccessor);

ApplicantUpdateDto applicantUpdateDto = new()
{
@@ -166,10 +164,36 @@ namespace Diligent.WebAPI.Tests.Services
Position = "React Developer"
};

await applicantService.UpdateApplicant(1,applicantUpdateDto);
await applicantService.UpdateApplicant(1, applicantUpdateDto);
var applicant = await applicantService.GetById(1);

Assert.Equal(applicant.Position,applicantUpdateDto.Position);
Assert.Equal(applicant.Position, applicantUpdateDto.Position);
}

[Fact]
public async Task GetAllAdsApplicants_ShouldReturnListOfAdApplicants_Always()
{
var databaseContext = await Helpers<Ad>.GetDatabaseContext(_ads);
ApplicantService applicantService = new(databaseContext, _mapper, _httpContextAccessor);

var result = await applicantService.GetAllAdsApplicants();

result.Should().BeEquivalentTo(_mapper.Map<List<AdApplicantsViewDto>>(_ads));
}

[Fact]
public async Task GetApplicantWithSelectionProcessesById_ShouldReturnApplicant_WhenApplicantExists()
{
var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants);
ApplicantService applicantService = new(databaseContext, _mapper,_httpContextAccessor);

var result = await applicantService.GetApplicantWithSelectionProcessesById(1);
var processes = result.SelectionProcesses;

processes.Should().HaveCount(3);
result.Should().BeEquivalentTo(_mapper.Map<ApplicantViewDto>(_applicants[0]));
}


}
}

+ 50
- 0
Diligent.WebAPI.Tests/Services/CommentServiceTests.cs 查看文件

@@ -0,0 +1,50 @@
using AutoMapper;
using Diligent.WebAPI.Business.MappingProfiles;
using Diligent.WebAPI.Business.Services;
using Diligent.WebAPI.Contracts.DTOs.Comment;
using Diligent.WebAPI.Data.Entities;
using Microsoft.EntityFrameworkCore;

namespace Diligent.WebAPI.Tests.Services
{
public class CommentServiceTests
{
private readonly IMapper _mapper;
private readonly List<Comment> _comments;
private readonly List<Applicant> _applicants;
private readonly List<User> _users;
public CommentServiceTests()
{
_applicants = MockData.GetListOfApplicants();
_comments = MockData.GetListOfComments();
_users = MockData.GetListOfUsers();

// configure mapper
var configuration = new MapperConfiguration(cfg => cfg.AddProfiles(
new List<Profile>
{
new CommentMappingProfile()
}));
_mapper = new Mapper(configuration);
}

[Fact]
public async Task CreateComment_ShouldUpdatedListOfComments_Always()
{
var databaseContext = await Helpers<Comment>.GetDatabaseContext(_comments);
CommentService applicantService = new(databaseContext, _mapper);

var commentCreateDto = new CommentCreateDto
{
ApplicantId = _applicants[0].ApplicantId,
Content = "dsadasd",
UserId = _users[0].Id
};

await applicantService.CreateComment(commentCreateDto);
var comments = await databaseContext.Comments.ToListAsync();

Assert.Equal(2, comments.Count);
}
}
}

正在加载...
取消
保存