forked from hngprojects/hng_boilerplate_csharp_web
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge dev into staging (hngprojects#377)
- Loading branch information
Showing
49 changed files
with
3,731 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: C-sharp Run Postman Tests Every 15 Minutes | ||
|
||
on: | ||
workflow_dispatch: | ||
schedule: | ||
- cron: "*/15 * * * *" # Every 15 minutes | ||
|
||
jobs: | ||
run-postman-tests: | ||
runs-on: self-hosted | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Node.js | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: "20" | ||
|
||
- name: Install Newman | ||
run: npm install -g newman | ||
|
||
- name: Run Newman tests | ||
id: newman | ||
run: | | ||
newman run status/postman/telex_postmancollection_v1.json --reporters cli,json --reporter-json-export report.json | ||
- name: Upload newman report to API | ||
run: | | ||
curl -X POST "${{ vars.API_URL }}/api/v1/api-status" \ | ||
-H "Content-Type: multipart/form-data" \ | ||
-F "[email protected]" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
src/Hng.Application.Test/Features/Squeeze/CreateSqueezeShould.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using AutoMapper; | ||
using Hng.Application.Features.Squeeze.Commands; | ||
using Hng.Application.Features.Squeeze.Dtos; | ||
using Hng.Application.Features.Squeeze.Handlers; | ||
using Hng.Application.Features.Squeeze.Mappers; | ||
using Hng.Infrastructure.Repository.Interface; | ||
using Microsoft.AspNetCore.Http; | ||
using Moq; | ||
using Xunit; | ||
|
||
namespace Hng.Application.Test.Features.Squeeze; | ||
|
||
public class CreateSqueezeShould | ||
{ | ||
private readonly Mock<IRepository<Domain.Entities.Squeeze>> _repositoryMock; | ||
private readonly CreateSqueezeCommandHandler _handler; | ||
|
||
public CreateSqueezeShould() | ||
{ | ||
var mappingProfile = new SqueezeMapperProfile(); | ||
var configuration = new MapperConfiguration(cfg => cfg.AddProfile(mappingProfile)); | ||
IMapper mapper = new Mapper(configuration); | ||
|
||
_repositoryMock = new Mock<IRepository<Domain.Entities.Squeeze>>(); | ||
_handler = new CreateSqueezeCommandHandler(_repositoryMock.Object, mapper); | ||
} | ||
|
||
[Fact] | ||
public async Task Handle_ShouldReturnCreatedSqueeze() | ||
{ | ||
var expectedId = Guid.NewGuid(); | ||
var createDto = new CreateSqueezeRequestDto() | ||
{ | ||
FirstName = "Test First Name", | ||
LastName = "Test Last Name", | ||
Email = "[email protected]", | ||
}; | ||
|
||
var squeeze = new Domain.Entities.Squeeze | ||
{ | ||
Id = expectedId, | ||
FirstName = createDto.FirstName, | ||
LastName = createDto.LastName, | ||
Email = createDto.Email, | ||
}; | ||
|
||
_repositoryMock.Setup(r => r.AddAsync(It.IsAny<Domain.Entities.Squeeze>())) | ||
.ReturnsAsync((Domain.Entities.Squeeze org) => | ||
{ | ||
org.Id = expectedId; | ||
return org; | ||
}); | ||
|
||
var command = new CreateSqueezeCommand(createDto); | ||
|
||
var result = await _handler.Handle(command, default); | ||
|
||
Assert.NotNull(result); | ||
Assert.Equal(StatusCodes.Status201Created, result.StatusCode); | ||
Assert.Equal("Squeeze Created Successfully", result.Message); | ||
Assert.NotNull(result.Data); | ||
Assert.Equal(expectedId, result.Data.Id); | ||
Assert.Equal(createDto.FirstName, result.Data.FirstName); | ||
Assert.Equal(createDto.LastName, result.Data.LastName); | ||
Assert.Equal(createDto.Email, result.Data.Email); | ||
} | ||
} |
102 changes: 102 additions & 0 deletions
102
src/Hng.Application.Test/Features/WaitLists/CreateWaitlistCommandHandlerShould.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
using AutoMapper; | ||
using Hng.Application.Features.WaitLists.Commands; | ||
using Hng.Application.Features.WaitLists.Dtos; | ||
using Hng.Application.Features.WaitLists.Handlers; | ||
using Hng.Domain.Entities; | ||
using Hng.Infrastructure.Repository.Interface; | ||
using Moq; | ||
using System.Linq.Expressions; | ||
using Xunit; | ||
|
||
namespace Hng.Application.Test.Features.WaitLists | ||
{ | ||
public class CreateWaitlistCommandHandlerShould | ||
{ | ||
private readonly Mock<IRepository<Waitlist>> _mockWaitlistRepository; | ||
private readonly Mock<IMapper> _mockMapper; | ||
private readonly CreateWaitlistCommandHandler _handler; | ||
|
||
public CreateWaitlistCommandHandlerShould() | ||
{ | ||
_mockWaitlistRepository = new Mock<IRepository<Waitlist>>(); | ||
_mockMapper = new Mock<IMapper>(); | ||
_handler = new CreateWaitlistCommandHandler( | ||
_mockWaitlistRepository.Object, | ||
_mockMapper.Object | ||
); | ||
} | ||
|
||
[Fact] | ||
public async Task Handle_ShouldCreateNewWaitlistWhenEmailDoesNotExist() | ||
{ | ||
// Arrange | ||
var waitListDto = new WaitListDto | ||
{ | ||
Name = "John Doe", | ||
Email = "[email protected]" | ||
}; | ||
|
||
var command = new CreateWaitlistCommand(waitListDto); | ||
var newWaitlist = new Waitlist | ||
{ | ||
Id = Guid.NewGuid(), | ||
Name = waitListDto.Name, | ||
Email = waitListDto.Email | ||
}; | ||
|
||
_mockWaitlistRepository.Setup(r => r.GetBySpec(It.IsAny<Expression<Func<Waitlist, bool>>>())) | ||
.ReturnsAsync((Waitlist)null); | ||
_mockMapper.Setup(m => m.Map<Waitlist>(waitListDto)) | ||
.Returns(newWaitlist); | ||
_mockWaitlistRepository.Setup(r => r.AddAsync(It.IsAny<Waitlist>())) | ||
.ReturnsAsync(newWaitlist); | ||
_mockWaitlistRepository.Setup(r => r.SaveChanges()) | ||
.Returns(Task.CompletedTask); | ||
|
||
// Act | ||
var result = await _handler.Handle(command, CancellationToken.None); | ||
|
||
// Assert | ||
Assert.NotNull(result); | ||
Assert.Equal(waitListDto.Name, result.Name); | ||
Assert.Equal(waitListDto.Email, result.Email); | ||
|
||
_mockWaitlistRepository.Verify(r => r.GetBySpec(It.IsAny<Expression<Func<Waitlist, bool>>>()), Times.Once); | ||
_mockMapper.Verify(m => m.Map<Waitlist>(waitListDto), Times.Once); | ||
_mockWaitlistRepository.Verify(r => r.AddAsync(It.IsAny<Waitlist>()), Times.Once); | ||
_mockWaitlistRepository.Verify(r => r.SaveChanges(), Times.Once); | ||
} | ||
|
||
[Fact] | ||
public async Task Handle_ShouldReturnNullWhenEmailAlreadyExists() | ||
{ | ||
// Arrange | ||
var existingEmail = "[email protected]"; | ||
var waitListDto = new WaitListDto | ||
{ | ||
Name = "John Doe", | ||
Email = existingEmail | ||
}; | ||
var command = new CreateWaitlistCommand(waitListDto); | ||
var existingWaitlist = new Waitlist | ||
{ | ||
Id = Guid.NewGuid(), | ||
Email = existingEmail | ||
}; | ||
|
||
_mockWaitlistRepository.Setup(r => r.GetBySpec(It.IsAny<Expression<Func<Waitlist, bool>>>())) | ||
.ReturnsAsync(existingWaitlist); | ||
|
||
// Act | ||
var result = await _handler.Handle(command, CancellationToken.None); | ||
|
||
// Assert | ||
Assert.Null(result); | ||
|
||
_mockWaitlistRepository.Verify(r => r.GetBySpec(It.IsAny<Expression<Func<Waitlist, bool>>>()), Times.Once); | ||
_mockMapper.Verify(m => m.Map<Waitlist>(It.IsAny<WaitListDto>()), Times.Never); | ||
_mockWaitlistRepository.Verify(r => r.AddAsync(It.IsAny<Waitlist>()), Times.Never); | ||
_mockWaitlistRepository.Verify(r => r.SaveChanges(), Times.Never); | ||
} | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
src/Hng.Application.Test/Features/WaitLists/DeleteWaitlistByIdCommandHandlerShould.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
using AutoMapper; | ||
using Hng.Application.Features.WaitLists.Commands; | ||
using Hng.Application.Features.WaitLists.Handlers; | ||
using Hng.Domain.Entities; | ||
using Hng.Infrastructure.Repository.Interface; | ||
using Moq; | ||
using Xunit; | ||
|
||
namespace Hng.Application.Test.Features.WaitLists | ||
{ | ||
public class DeleteWaitlistByIdCommandHandlerShould | ||
{ | ||
private readonly Mock<IRepository<Waitlist>> _mockWaitlistRepository; | ||
private readonly Mock<IMapper> _mockMapper; | ||
private readonly DeleteWaitlistByIdCommandHandler _handler; | ||
|
||
public DeleteWaitlistByIdCommandHandlerShould() | ||
{ | ||
_mockWaitlistRepository = new Mock<IRepository<Waitlist>>(); | ||
_mockMapper = new Mock<IMapper>(); | ||
_handler = new DeleteWaitlistByIdCommandHandler( | ||
_mockWaitlistRepository.Object, | ||
_mockMapper.Object | ||
); | ||
} | ||
|
||
[Fact] | ||
public async Task Handle_ShouldDeleteWaitlistWhenExists() | ||
{ | ||
// Arrange | ||
var waitlistId = Guid.NewGuid(); | ||
var existingWaitlist = new Waitlist { Id = waitlistId, Email = "[email protected]" }; | ||
|
||
_mockWaitlistRepository.Setup(r => r.GetAsync(waitlistId)) | ||
.ReturnsAsync(existingWaitlist); | ||
_mockWaitlistRepository.Setup(r => r.DeleteAsync(existingWaitlist)) | ||
.ReturnsAsync(existingWaitlist); | ||
_mockWaitlistRepository.Setup(r => r.SaveChanges()) | ||
.Returns(Task.CompletedTask); | ||
|
||
var command = new DeleteWaitlistByIdCommand(waitlistId); | ||
|
||
// Act | ||
var result = await _handler.Handle(command, CancellationToken.None); | ||
|
||
// Assert | ||
Assert.NotNull(result); | ||
Assert.Equal(existingWaitlist, result); | ||
|
||
_mockWaitlistRepository.Verify(r => r.GetAsync(waitlistId), Times.Once); | ||
_mockWaitlistRepository.Verify(r => r.DeleteAsync(existingWaitlist), Times.Once); | ||
_mockWaitlistRepository.Verify(r => r.SaveChanges(), Times.Once); | ||
} | ||
|
||
[Fact] | ||
public async Task Handle_ShouldReturnNullWhenWaitlistDoesNotExist() | ||
{ | ||
// Arrange | ||
var nonExistentWaitlistId = Guid.NewGuid(); | ||
|
||
_mockWaitlistRepository.Setup(r => r.GetAsync(nonExistentWaitlistId)) | ||
.ReturnsAsync((Waitlist)null); | ||
|
||
var command = new DeleteWaitlistByIdCommand(nonExistentWaitlistId); | ||
|
||
// Act | ||
var result = await _handler.Handle(command, CancellationToken.None); | ||
|
||
// Assert | ||
Assert.Null(result); | ||
|
||
_mockWaitlistRepository.Verify(r => r.GetAsync(nonExistentWaitlistId), Times.Once); | ||
_mockWaitlistRepository.Verify(r => r.DeleteAsync(It.IsAny<Waitlist>()), Times.Never); | ||
_mockWaitlistRepository.Verify(r => r.SaveChanges(), Times.Never); | ||
} | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
src/Hng.Application.Test/Features/WaitLists/GetAllWaitlistQueryHandlerShould.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using AutoMapper; | ||
using Hng.Application.Features.WaitLists.Handlers; | ||
using Hng.Application.Features.WaitLists.Queries; | ||
using Hng.Domain.Entities; | ||
using Hng.Infrastructure.Repository.Interface; | ||
using Moq; | ||
using Xunit; | ||
|
||
namespace Hng.Application.Test.Features.WaitLists | ||
{ | ||
public class GetAllWaitlistQueryHandlerShould | ||
{ | ||
private readonly Mock<IRepository<Waitlist>> _mockWaitlistRepository; | ||
private readonly Mock<IMapper> _mockMapper; | ||
private readonly GetAllWaitlistQueryHandler _handler; | ||
|
||
public GetAllWaitlistQueryHandlerShould() | ||
{ | ||
_mockWaitlistRepository = new Mock<IRepository<Waitlist>>(); | ||
_mockMapper = new Mock<IMapper>(); | ||
_handler = new GetAllWaitlistQueryHandler( | ||
_mockWaitlistRepository.Object, | ||
_mockMapper.Object | ||
); | ||
} | ||
|
||
[Fact] | ||
public async Task Handle_ShouldReturnAllWaitlists() | ||
{ | ||
// Arrange | ||
var waitlists = new List<Waitlist> | ||
{ | ||
new Waitlist { Id = Guid.NewGuid(), Email = "[email protected]" }, | ||
new Waitlist { Id = Guid.NewGuid(), Email = "[email protected]" } | ||
}; | ||
|
||
_mockWaitlistRepository.Setup(r => r.GetAllAsync()) | ||
.ReturnsAsync(waitlists); | ||
|
||
var query = new GetAllWaitlistQuery(); | ||
|
||
// Act | ||
var result = await _handler.Handle(query, CancellationToken.None); | ||
|
||
// Assert | ||
Assert.NotNull(result); | ||
Assert.Equal(2, result.Count); | ||
Assert.Equal(waitlists, result); | ||
|
||
_mockWaitlistRepository.Verify(r => r.GetAllAsync(), Times.Once); | ||
} | ||
|
||
[Fact] | ||
public async Task Handle_ShouldReturnEmptyListWhenNoWaitlists() | ||
{ | ||
// Arrange | ||
var emptyList = new List<Waitlist>(); | ||
|
||
_mockWaitlistRepository.Setup(r => r.GetAllAsync()) | ||
.ReturnsAsync(emptyList); | ||
|
||
var query = new GetAllWaitlistQuery(); | ||
|
||
// Act | ||
var result = await _handler.Handle(query, CancellationToken.None); | ||
|
||
// Assert | ||
Assert.NotNull(result); | ||
Assert.Empty(result); | ||
|
||
_mockWaitlistRepository.Verify(r => r.GetAllAsync(), Times.Once); | ||
} | ||
} | ||
} |
Oops, something went wrong.