| #region Models to DTO | #region Models to DTO | ||||
| CreateMap<Comment, CommentViewDto>(); | CreateMap<Comment, CommentViewDto>(); | ||||
| #endregion | #endregion | ||||
| #region DTO to Model | |||||
| CreateMap<CommentCreateDto, Comment>(); | |||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| { | { | ||||
| #region Model to DTO | #region Model to DTO | ||||
| CreateMap<Technology, TechnologyResponseDto>(); | CreateMap<Technology, TechnologyResponseDto>(); | ||||
| CreateMap<TechnologyApplicant, TechnologyResponseDto>(); | |||||
| //CreateMap<TechnologyApplicant, TechnologyResponseDto>(); -- ermin | |||||
| CreateMap<TechnologyApplicant, TechnologyViewDto>(); | |||||
| #endregion | #endregion | ||||
| } | } | ||||
| } | } |
| public async Task<List<ApplicantViewDto>> GetAll() | public async Task<List<ApplicantViewDto>> GetAll() | ||||
| { | { | ||||
| var applicants = await _context.Applicants.ToListAsync(); | |||||
| var applicants = await _context.Applicants.Include(c => c.Ads).ToListAsync(); | |||||
| return _mapper.Map<List<ApplicantViewDto>>(applicants); | return _mapper.Map<List<ApplicantViewDto>>(applicants); | ||||
| } | } | ||||
| public async Task<ApplicantViewDto> GetById(int id) | public async Task<ApplicantViewDto> GetById(int id) | ||||
| { | { | ||||
| var applicant = await _context.Applicants | var applicant = await _context.Applicants | ||||
| .Include(x => x.Ads) | |||||
| .ThenInclude(x => x.Technologies) | |||||
| .Include(x => x.TechnologyApplicants) | .Include(x => x.TechnologyApplicants) | ||||
| .ThenInclude(x => x.Technology) | |||||
| .Include(x => x.Comments) | .Include(x => x.Comments) | ||||
| .ThenInclude(t => t.User) | .ThenInclude(t => t.User) | ||||
| .FirstOrDefaultAsync(a => a.ApplicantId == id); | |||||
| .FirstOrDefaultAsync(x => x.ApplicantId == id); | |||||
| if (applicant is null) | if (applicant is null) | ||||
| throw new EntityNotFoundException("Applicant not found"); | throw new EntityNotFoundException("Applicant not found"); |
| using Diligent.WebAPI.Contracts.DTOs.Comment; | |||||
| namespace Diligent.WebAPI.Business.Services | |||||
| { | |||||
| public class CommentService : ICommentService | |||||
| { | |||||
| private readonly DatabaseContext _context; | |||||
| private readonly IMapper _mapper; | |||||
| public CommentService(DatabaseContext context, IMapper mapper) | |||||
| { | |||||
| _context = context; | |||||
| _mapper = mapper; | |||||
| } | |||||
| public async Task CreateComment(CommentCreateDto commentCreateDto) | |||||
| { | |||||
| var comment = _mapper.Map<Comment>(commentCreateDto); | |||||
| comment.DateOfSending = DateTime.Now; | |||||
| await _context.Comments.AddAsync(comment); | |||||
| await _context.SaveChangesAsync(); | |||||
| } | |||||
| } | |||||
| } |
| using Diligent.WebAPI.Contracts.DTOs.Comment; | |||||
| namespace Diligent.WebAPI.Business.Services.Interfaces | |||||
| { | |||||
| public interface ICommentService | |||||
| { | |||||
| Task CreateComment(CommentCreateDto commentCreateDto); | |||||
| } | |||||
| } |
| public interface ITechnologyService | public interface ITechnologyService | ||||
| { | { | ||||
| Task<List<TechnologyResponseDto>> GetAllAsync(); | Task<List<TechnologyResponseDto>> GetAllAsync(); | ||||
| Task<List<TechnologyApplicantViewDto>> GetAllAsync2(); | |||||
| Task<TechnologyResponseDto> GetByIdAsync(int id); | Task<TechnologyResponseDto> GetByIdAsync(int id); | ||||
| Task<TechnologyApplicantViewDto> GetByIdAsync2(int id); | |||||
| } | } | ||||
| } | } |
| public async Task<List<TechnologyResponseDto>> GetAllAsync() => | public async Task<List<TechnologyResponseDto>> GetAllAsync() => | ||||
| _mapper.Map<List<TechnologyResponseDto>>(await _context.Technologies.ToListAsync()); | _mapper.Map<List<TechnologyResponseDto>>(await _context.Technologies.ToListAsync()); | ||||
| public async Task<List<TechnologyApplicantViewDto>> GetAllAsync2() => | |||||
| _mapper.Map<List<TechnologyApplicantViewDto>>(await _context.Technologies.ToListAsync()); | |||||
| public async Task<TechnologyResponseDto> GetByIdAsync(int id) | public async Task<TechnologyResponseDto> GetByIdAsync(int id) | ||||
| { | { | ||||
| var technology = await _context.Technologies.FindAsync(id); | var technology = await _context.Technologies.FindAsync(id); | ||||
| return _mapper.Map<TechnologyResponseDto>(technology); | return _mapper.Map<TechnologyResponseDto>(technology); | ||||
| } | } | ||||
| public async Task<TechnologyApplicantViewDto> GetByIdAsync2(int id) | |||||
| { | |||||
| var technology = await _context.Technologies.FindAsync(id); | |||||
| if (technology is null) | |||||
| throw new EntityNotFoundException("Technology not found"); | |||||
| return _mapper.Map<TechnologyApplicantViewDto>(technology); | |||||
| } | |||||
| } | } | ||||
| } | } |
| private int CalculateTotalApplicants() | private int CalculateTotalApplicants() | ||||
| { | { | ||||
| return Applicants.Count(); | |||||
| return Applicants.Count; | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| using Diligent.WebAPI.Contracts.DTOs.Comment; | |||||
| using Diligent.WebAPI.Contracts.DTOs.Ad; | |||||
| using Diligent.WebAPI.Contracts.DTOs.Comment; | |||||
| using Diligent.WebAPI.Contracts.DTOs.Technology; | using Diligent.WebAPI.Contracts.DTOs.Technology; | ||||
| namespace Diligent.WebAPI.Contracts.DTOs.Applicant | namespace Diligent.WebAPI.Contracts.DTOs.Applicant | ||||
| public string BitBucketLink { get; set; } | public string BitBucketLink { get; set; } | ||||
| public int Experience { get; set; } | public int Experience { get; set; } | ||||
| public string ApplicationChannel { get; set; } | public string ApplicationChannel { get; set; } | ||||
| public List<TechnologyResponseDto> TechnologyApplicants { get; set; } = new(); | |||||
| public List<TechnologyViewDto> TechnologyApplicants { get; set; } = new(); | |||||
| public List<CommentViewDto> Comments { get; set; } | public List<CommentViewDto> Comments { get; set; } | ||||
| public List<AdResponseDto> Ads { get; set; } | |||||
| } | } | ||||
| } | } |
| namespace Diligent.WebAPI.Contracts.DTOs.Comment | |||||
| { | |||||
| public class CommentCreateDto | |||||
| { | |||||
| public string Content { get; set; } | |||||
| public int UserId { get; set; } | |||||
| public int ApplicantId { get; set; } | |||||
| } | |||||
| } |
| { | { | ||||
| public class CommentViewDto | public class CommentViewDto | ||||
| { | { | ||||
| public int Id { get; set; } | |||||
| public string Content { get; set; } | public string Content { get; set; } | ||||
| public DateTime DateOfSending { get; set; } | public DateTime DateOfSending { get; set; } | ||||
| public UserResponseDTO User { get; set; } | public UserResponseDTO User { get; set; } |
| namespace Diligent.WebAPI.Contracts.DTOs.Technology | |||||
| { | |||||
| public class TechnologyApplicantViewDto | |||||
| { | |||||
| public TechnologyResponseDto Technology { get; set; } | |||||
| } | |||||
| } |
| public class TechnologyResponseDto | public class TechnologyResponseDto | ||||
| { | { | ||||
| public int TechnologyId { get; set; } | public int TechnologyId { get; set; } | ||||
| public string Name { get; set; } | public string Name { get; set; } | ||||
| } | } | ||||
| } | } |
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Threading.Tasks; | |||||
| namespace Diligent.WebAPI.Contracts.DTOs.Technology | |||||
| { | |||||
| public class TechnologyViewDto | |||||
| { | |||||
| public TechnologyResponseDto Technology { get; set; } | |||||
| } | |||||
| } |
| _applicantService = applicantService; | _applicantService = applicantService; | ||||
| } | } | ||||
| [Authorize] | |||||
| //[Authorize] | |||||
| [HttpGet] | [HttpGet] | ||||
| public async Task<IActionResult> GetAll() | public async Task<IActionResult> GetAll() | ||||
| { | { | ||||
| return Ok(await _applicantService.GetAll()); | return Ok(await _applicantService.GetAll()); | ||||
| } | } | ||||
| [Authorize] | |||||
| //[Authorize] | |||||
| [HttpGet("{id}")] | [HttpGet("{id}")] | ||||
| public async Task<IActionResult> GetById(int id) | public async Task<IActionResult> GetById(int id) | ||||
| { | { |
| using Diligent.WebAPI.Contracts.DTOs.Comment; | |||||
| namespace Diligent.WebAPI.Host.Controllers.V1 | |||||
| { | |||||
| [ApiVersion("1.0")] | |||||
| [Route("v{version:apiVersion}/comments")] | |||||
| [ApiController] | |||||
| public class CommentsController : ControllerBase | |||||
| { | |||||
| private readonly ICommentService _commentService; | |||||
| public CommentsController(ICommentService commentService) | |||||
| { | |||||
| _commentService = commentService; | |||||
| } | |||||
| [Authorize] | |||||
| [HttpPost] | |||||
| public async Task<IActionResult> AddComment(CommentCreateDto commentCreateDto) | |||||
| { | |||||
| await _commentService.CreateComment(commentCreateDto); | |||||
| return StatusCode((int)HttpStatusCode.Created); | |||||
| } | |||||
| } | |||||
| } |
| services.AddScoped<IAuthenticationService, AuthenticationService>(); | services.AddScoped<IAuthenticationService, AuthenticationService>(); | ||||
| services.AddScoped<IAdService, AdService>(); | services.AddScoped<IAdService, AdService>(); | ||||
| services.AddScoped<ITechnologyService, TechnologyService>(); | services.AddScoped<ITechnologyService, TechnologyService>(); | ||||
| services.AddScoped<ICommentService, CommentService>(); | |||||
| } | } | ||||
| /// <summary> | /// <summary> |
| namespace Diligent.WebAPI.Tests | namespace Diligent.WebAPI.Tests | ||||
| { | { | ||||
| public static class Helpers | |||||
| public static class Helpers<T> where T : class | |||||
| { | { | ||||
| public static async Task<DatabaseContext> GetDatabaseContext(List<Applicant> applicants) | |||||
| public static async Task<DatabaseContext> GetDatabaseContext(List<T> applicants) | |||||
| { | { | ||||
| var options = new DbContextOptionsBuilder<DatabaseContext>() | var options = new DbContextOptionsBuilder<DatabaseContext>() | ||||
| .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) | .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) | ||||
| databaseContext.Database.EnsureCreated(); | databaseContext.Database.EnsureCreated(); | ||||
| if (!await databaseContext.Applicants.AnyAsync()) | if (!await databaseContext.Applicants.AnyAsync()) | ||||
| { | { | ||||
| await databaseContext.Applicants.AddRangeAsync(applicants); | |||||
| await databaseContext.Set<T>().AddRangeAsync(applicants); | |||||
| await databaseContext.SaveChangesAsync(); | await databaseContext.SaveChangesAsync(); | ||||
| } | } | ||||
| return databaseContext; | return databaseContext; |
| [Fact] | [Fact] | ||||
| public async Task GetAll_ShouldReturnListOfApplicants_Always() | public async Task GetAll_ShouldReturnListOfApplicants_Always() | ||||
| { | { | ||||
| var databaseContext = await Helpers.GetDatabaseContext(_applicants); | |||||
| var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants); | |||||
| ApplicantService applicantService = new(databaseContext, _mapper); | ApplicantService applicantService = new(databaseContext, _mapper); | ||||
| var result = await applicantService.GetAll(); | var result = await applicantService.GetAll(); | ||||
| [Fact] | [Fact] | ||||
| public async Task GetById_ShouldReturnApplicant_WhenApplicantExist() | public async Task GetById_ShouldReturnApplicant_WhenApplicantExist() | ||||
| { | { | ||||
| var databaseContext = await Helpers.GetDatabaseContext(_applicants); | |||||
| var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants); | |||||
| ApplicantService applicantService = new(databaseContext, _mapper); | ApplicantService applicantService = new(databaseContext, _mapper); | ||||
| var result = await applicantService.GetById(1); | var result = await applicantService.GetById(1); | ||||
| [Fact] | [Fact] | ||||
| public async Task GetById_ShouldThrowEntityNotFooundException_WhenApplicantDontExist() | public async Task GetById_ShouldThrowEntityNotFooundException_WhenApplicantDontExist() | ||||
| { | { | ||||
| var databaseContext = await Helpers.GetDatabaseContext(_applicants); | |||||
| var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants); | |||||
| ApplicantService applicantService = new(databaseContext, _mapper); | ApplicantService applicantService = new(databaseContext, _mapper); | ||||
| await Assert.ThrowsAsync<EntityNotFoundException>(async () => await applicantService.GetById(1000)); | await Assert.ThrowsAsync<EntityNotFoundException>(async () => await applicantService.GetById(1000)); | ||||
| [Fact] | [Fact] | ||||
| public async Task CreateApplicant_ShouldAddEntityIntoDatabase_Always() | public async Task CreateApplicant_ShouldAddEntityIntoDatabase_Always() | ||||
| { | { | ||||
| var databaseContext = await Helpers.GetDatabaseContext(_applicants); | |||||
| var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants); | |||||
| ApplicantService applicantService = new(databaseContext, _mapper); | ApplicantService applicantService = new(databaseContext, _mapper); | ||||
| ApplicantCreateDto applicantCreateDto = new() | ApplicantCreateDto applicantCreateDto = new() | ||||
| [Fact] | [Fact] | ||||
| public async Task DeleteApplicant_ShouldDeleteApplicant_WhenApplicantExist() | public async Task DeleteApplicant_ShouldDeleteApplicant_WhenApplicantExist() | ||||
| { | { | ||||
| var databaseContext = await Helpers.GetDatabaseContext(_applicants); | |||||
| var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants); | |||||
| ApplicantService applicantService = new(databaseContext, _mapper); | ApplicantService applicantService = new(databaseContext, _mapper); | ||||
| await applicantService.DeleteApplicant(1); | await applicantService.DeleteApplicant(1); | ||||
| [Fact] | [Fact] | ||||
| public async Task DeleteApplicant_ShouldThrowEntityNotFooundException_WhenApplicantDontExist() | public async Task DeleteApplicant_ShouldThrowEntityNotFooundException_WhenApplicantDontExist() | ||||
| { | { | ||||
| var databaseContext = await Helpers.GetDatabaseContext(_applicants); | |||||
| var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants); | |||||
| ApplicantService applicantService = new(databaseContext, _mapper); | ApplicantService applicantService = new(databaseContext, _mapper); | ||||
| await Assert.ThrowsAsync<EntityNotFoundException>(async () => await applicantService.DeleteApplicant(1000)); | await Assert.ThrowsAsync<EntityNotFoundException>(async () => await applicantService.DeleteApplicant(1000)); | ||||
| [Fact] | [Fact] | ||||
| public async Task UpdateApplicant_ShouldUpdateApplicant_WhenApplicantExist() | public async Task UpdateApplicant_ShouldUpdateApplicant_WhenApplicantExist() | ||||
| { | { | ||||
| var databaseContext = await Helpers.GetDatabaseContext(_applicants); | |||||
| var databaseContext = await Helpers<Applicant>.GetDatabaseContext(_applicants); | |||||
| ApplicantService applicantService = new(databaseContext, _mapper); | ApplicantService applicantService = new(databaseContext, _mapper); | ||||
| ApplicantUpdateDto applicantUpdateDto = new() | ApplicantUpdateDto applicantUpdateDto = new() |