Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6886d01
added redis to project
kubapoke Apr 26, 2025
af6dbcb
added connection multiplexer, connecting to appropriate Redis address
kubapoke Apr 26, 2025
1db8acd
added redis service with basic method declarations
kubapoke Apr 26, 2025
e14337d
implemented basic RedisService methods
kubapoke Apr 26, 2025
8328b64
added json serializer options and made the RetryAsync methods static
kubapoke Apr 26, 2025
bc74f8e
Made Set methods of the Redis service return bool; added two addition…
kubapoke Apr 26, 2025
e489678
added Redis service methods for manipulating counters
kubapoke Apr 26, 2025
8e19596
private static field rename for consistency purposes
kubapoke Apr 26, 2025
e2eeac2
Merge pull request #84 from Resellio/feat/setup-redis
kubapoke Apr 26, 2025
b7cf2d2
Implement mailing using sendgrid
staszkiet Apr 27, 2025
551f975
upgraded the event pipeline so that it returns the event's guid as we…
kubapoke Apr 27, 2025
2abe050
Add abstraction
staszkiet Apr 27, 2025
887bbd4
created the framework for returning event details pipeline
kubapoke Apr 27, 2025
eb2829e
added tests for GetEventDetails
kubapoke Apr 27, 2025
cd84e3e
added a method to event repository for event retrieval by id
kubapoke Apr 27, 2025
a5b518a
added a method for getting event details in EventService
kubapoke Apr 27, 2025
7505ce9
Update README.md
staszkiet Apr 27, 2025
5dc5be0
updated EventServiceTests.cs to work with the modified class
kubapoke Apr 27, 2025
8b98a84
Update README.md
staszkiet Apr 27, 2025
9a12580
fix kubapobke review
staszkiet Apr 27, 2025
38e6bbd
added tests for GetEventDetailsAsync
kubapoke Apr 27, 2025
c13472d
added ticket service tests
kubapoke Apr 27, 2025
6dee92e
Merge pull request #85 from Resellio/feat/MailService
kubapoke Apr 27, 2025
10cb41c
Admin cntroller
staszkiet Apr 27, 2025
664d81f
Merge pull request #87 from Resellio/feat/event-pipeline
staszkiet Apr 27, 2025
de2895c
Merge pull request #86 from Resellio/feat/updateReadme
kTrzcinskii Apr 27, 2025
e17be3a
Merge pull request #88 from Resellio/feat/adminController
kTrzcinskii Apr 27, 2025
5f97187
changed event creation for better category linking - still requires a…
kubapoke Apr 27, 2025
f095d57
fixed event category linking
kubapoke Apr 27, 2025
b613c99
Merge remote-tracking branch 'origin/fix/event-creation' into fix/eve…
kubapoke Apr 27, 2025
d06458d
whitespace fixes
kubapoke Apr 27, 2025
7b1d14e
Merge pull request #89 from Resellio/fix/event-creation
kTrzcinskii Apr 27, 2025
3ecdfb7
fixed getting events
kubapoke Apr 27, 2025
33be234
Merge pull request #91 from Resellio/fix/get-events
kubapoke Apr 28, 2025
e2d30a8
Create `EventFilterApplier`
kTrzcinskii Apr 28, 2025
768650e
Fix: unnecessary import
kTrzcinskii Apr 28, 2025
9a581c1
Add filters to controller
kTrzcinskii Apr 28, 2025
1bcd40d
Fix namespace
kTrzcinskii Apr 28, 2025
a5eb7e4
Fix controller tests by passing null filters
kTrzcinskii Apr 28, 2025
f95171b
Create tests for `EventFilterApplier`
kTrzcinskii Apr 28, 2025
bfe5c40
Fix filters that use string comparison
kTrzcinskii Apr 28, 2025
79cb57b
Merge pull request #92 from Resellio/feat/finish-event-filtration
kubapoke Apr 28, 2025
234a1bf
Temporarily enable swagger on prod
kasrow12 May 1, 2025
2fddfa0
Merge pull request #101 from Resellio/feat/swagger-prod
staszkiet May 1, 2025
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
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ Both services are managed using **Docker Compose**, and are defined in the `dock
Create an `appsettings.json` file in the root of the project, following the structure
of `appsettings.example.json` found in `TickAPI/TickAPI/appsettings.example.json`.

4. Run application:
4. Install Entity Framework and set up the database

```bash
dotnet tool install --global dotnet-ef --version 9.*
dotnet ef database update
```

5. Run application:

```bash
cd TickAPI/TickAPI
Expand Down
183 changes: 183 additions & 0 deletions TickAPI/TickAPI.Tests/Admins/Controllers/AdminsControllerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Moq;
using TickAPI.Admins.Abstractions;
using TickAPI.Admins.Controllers;
using TickAPI.Admins.DTOs.Request;
using TickAPI.Admins.DTOs.Response;
using TickAPI.Admins.Models;
using TickAPI.Common.Auth.Abstractions;
using TickAPI.Common.Auth.Enums;
using TickAPI.Common.Auth.Responses;
using TickAPI.Common.Claims.Abstractions;
using TickAPI.Common.Results.Generic;
using TickAPI.Customers.DTOs.Request;
using Xunit;

namespace TickAPI.Tests.Admins.Controllers;

public class AdminsControllerTests
{
private readonly Mock<IGoogleAuthService> _mockGoogleAuthService;
private readonly Mock<IJwtService> _mockJwtService;
private readonly Mock<IAdminService> _mockAdminService;
private readonly Mock<IClaimsService> _mockClaimsService;
private readonly AdminsController _controller;

public AdminsControllerTests()
{
_mockGoogleAuthService = new Mock<IGoogleAuthService>();
_mockJwtService = new Mock<IJwtService>();
_mockAdminService = new Mock<IAdminService>();
_mockClaimsService = new Mock<IClaimsService>();

_controller = new AdminsController(
_mockGoogleAuthService.Object,
_mockJwtService.Object,
_mockAdminService.Object,
_mockClaimsService.Object
);
}

[Fact]
public async Task GoogleLogin_WithValidAccessToken_ReturnsJwtToken()
{
// Arrange
const string email = "existing@test.com";
const string accessToken = "valid-google-token";
const string jwtToken = "valid-jwt-token";

_mockGoogleAuthService
.Setup(x => x.GetUserDataFromAccessToken(accessToken))
.ReturnsAsync(Result<GoogleUserData>.Success(new GoogleUserData(email, "First", "Last")));

_mockAdminService
.Setup(x => x.GetAdminByEmailAsync(email))
.ReturnsAsync(Result<Admin>.Success(new Admin{Email = email}));

_mockJwtService
.Setup(x => x.GenerateJwtToken(email, UserRole.Admin))
.Returns(Result<string>.Success(jwtToken));

// Act
var result = await _controller.GoogleLogin(new GoogleAdminLoginDto(accessToken));

// Assert
var actionResult = Assert.IsType<ActionResult<GoogleAdminLoginResponseDto>>(result);
var okResult = Assert.IsType<GoogleAdminLoginResponseDto>(actionResult.Value);
Assert.Equal(jwtToken, okResult.Token);
}

[Fact]
public async Task GoogleLogin_WithInvalidAccessToken_ReturnsErrorStatusCode()
{
// Arrange
const string accessToken = "valid-google-token";

_mockGoogleAuthService
.Setup(x => x.GetUserDataFromAccessToken(accessToken))
.ReturnsAsync(Result<GoogleUserData>.Failure(StatusCodes.Status401Unauthorized, "Invalid token"));

// Act
var result = await _controller.GoogleLogin(new GoogleAdminLoginDto(accessToken));

// Assert
var actionResult = Assert.IsType<ActionResult<GoogleAdminLoginResponseDto>>(result);
var objectResult = Assert.IsType<ObjectResult>(actionResult.Result);
Assert.Equal(StatusCodes.Status401Unauthorized, objectResult.StatusCode);
Assert.Equal("Invalid token", objectResult.Value);
}

[Fact]
public async Task GoogleLogin_WithNonAdminEmail_ReturnsErrorStatusCode()
{
// Arrange
const string email = "nonadmin@test.com";
const string accessToken = "valid-google-token";

_mockGoogleAuthService
.Setup(x => x.GetUserDataFromAccessToken(accessToken))
.ReturnsAsync(Result<GoogleUserData>.Success(new GoogleUserData(email, "First", "Last")));

_mockAdminService
.Setup(x => x.GetAdminByEmailAsync(email))
.ReturnsAsync(Result<Admin>.Failure(StatusCodes.Status404NotFound, "User is not an admin"));

// Act
var result = await _controller.GoogleLogin(new GoogleAdminLoginDto(accessToken));

// Assert
var actionResult = Assert.IsType<ActionResult<GoogleAdminLoginResponseDto>>(result);
var objectResult = Assert.IsType<ObjectResult>(actionResult.Result);
Assert.Equal(StatusCodes.Status404NotFound, objectResult.StatusCode);
Assert.Equal("User is not an admin", objectResult.Value);
}


[Fact]
public async Task AboutMe_WithValidClaims_ReturnsAdminData()
{
// Arrange
var email = "admin@example.com";
var admin = new Admin { Email = email, Login = "admin" };

// Mock the HttpContext and User
var claims = new List<Claim>
{
new Claim(ClaimTypes.Email, email)
};
var identity = new ClaimsIdentity(claims);
var principal = new ClaimsPrincipal(identity);
_controller.ControllerContext = new ControllerContext
{
HttpContext = new DefaultHttpContext { User = principal }
};

_mockClaimsService
.Setup(x => x.GetEmailFromClaims(It.IsAny<IEnumerable<Claim>>()))
.Returns(Result<string>.Success(email));

_mockAdminService
.Setup(x => x.GetAdminByEmailAsync(email))
.ReturnsAsync(Result<Admin>.Success(admin));

// Act
var result = await _controller.AboutMe();

// Assert
var actionResult = Assert.IsType<ActionResult<AboutMeAdminResponseDto>>(result);
var okResult = Assert.IsType<AboutMeAdminResponseDto>(actionResult.Value);
Assert.Equal(admin.Email, okResult.Email);
Assert.Equal(admin.Login, okResult.Login);
}

[Fact]
public async Task AboutMe_WithInvalidClaims_ReturnsErrorStatusCode()
{
// Arrange
var claims = new List<Claim>();
var identity = new ClaimsIdentity(claims);
var principal = new ClaimsPrincipal(identity);
_controller.ControllerContext = new ControllerContext
{
HttpContext = new DefaultHttpContext { User = principal }
};

_mockClaimsService
.Setup(x => x.GetEmailFromClaims(It.IsAny<IEnumerable<Claim>>()))
.Returns(Result<string>.Failure(StatusCodes.Status401Unauthorized, "Email claim not found"));

// Act
var result = await _controller.AboutMe();

// Assert
var actionResult = Assert.IsType<ActionResult<AboutMeAdminResponseDto>>(result);
var objectResult = Assert.IsType<ObjectResult>(actionResult.Result);
Assert.Equal(StatusCodes.Status401Unauthorized, objectResult.StatusCode);
Assert.Equal("Email claim not found", objectResult.Value);
}

}
48 changes: 48 additions & 0 deletions TickAPI/TickAPI.Tests/Admins/Services/AdminsServiceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Microsoft.AspNetCore.Http;
using Moq;
using TickAPI.Admins.Abstractions;
using TickAPI.Admins.Models;
using TickAPI.Admins.Services;
using TickAPI.Common.Results.Generic;
using TickAPI.Common.Time.Abstractions;
using TickAPI.Customers.Abstractions;
using TickAPI.Customers.Models;
using TickAPI.Customers.Services;

namespace TickAPI.Tests.Admins.Services;

public class AdminsServiceTests
{
[Fact]
public async Task GetAdminByEmailAsync_WhenAdminWithEmailIsReturnedFromRepository_ShouldReturnUser()
{
var admin = new Admin
{
Email = "example@test.com"
};
var adminRepositoryMock = new Mock<IAdminRepository>();
adminRepositoryMock.Setup(m => m.GetAdminByEmailAsync(admin.Email)).ReturnsAsync(Result<Admin>.Success(admin));
var sut = new AdminService(adminRepositoryMock.Object);

var result = await sut.GetAdminByEmailAsync(admin.Email);

Assert.True(result.IsSuccess);
Assert.Equal(admin, result.Value);
}

[Fact]
public async Task GetAdminByEmailAsync_WhenAdminWithEmailIsNotReturnedFromRepository_ShouldReturnFailure()
{
const string email = "not@existing.com";
var adminRepositoryMock = new Mock<IAdminRepository>();
adminRepositoryMock.Setup(m => m.GetAdminByEmailAsync(email)).ReturnsAsync(Result<Admin>.Failure(StatusCodes.Status404NotFound, $"admin with email '{email}' not found"));
var sut = new AdminService(adminRepositoryMock.Object);

var result = await sut.GetAdminByEmailAsync(email);

Assert.True(result.IsError);
Assert.Equal(StatusCodes.Status404NotFound, result.StatusCode);
Assert.Equal($"admin with email '{email}' not found", result.ErrorMsg);
}

}
Loading
Loading