Add unittests
This commit is contained in:
53
src/backend/tests/unit/Common/ResultTests.cs
Normal file
53
src/backend/tests/unit/Common/ResultTests.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Randall.Domain.Common;
|
||||
|
||||
namespace Randall.Domain.UnitTests.Common;
|
||||
|
||||
public class ResultTests
|
||||
{
|
||||
[Fact]
|
||||
public void Success_IsSuccessIsTrue()
|
||||
{
|
||||
var result = Result.Success();
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Null(result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Failure_IsSuccessIsFalse()
|
||||
{
|
||||
var result = Result.Failure("Something went wrong");
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal("Something went wrong", result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SuccessOfT_ContainsValue()
|
||||
{
|
||||
var result = Result.Success(42);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(42, result.Value);
|
||||
Assert.Null(result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FailureOfT_ValueIsDefault()
|
||||
{
|
||||
var result = Result.Failure<int>("error");
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(default, result.Value);
|
||||
Assert.Equal("error", result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FailureOfT_ReferenceType_ValueIsNull()
|
||||
{
|
||||
var result = Result.Failure<string>("error");
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Null(result.Value);
|
||||
}
|
||||
}
|
||||
25
src/backend/tests/unit/Randall.Domain.UnitTests.csproj
Normal file
25
src/backend/tests/unit/Randall.Domain.UnitTests.csproj
Normal file
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Randall.Domain\Randall.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,48 @@
|
||||
using Randall.Domain.Reservations;
|
||||
|
||||
namespace Randall.Domain.UnitTests.Reservations;
|
||||
|
||||
public class ReservationCancelTests
|
||||
{
|
||||
private static Reservation CreateActiveReservation()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
return Reservation.Create(Guid.NewGuid(), "jane@company.com", "Jane", today, today).Value!;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Cancel_ActiveReservation_Succeeds()
|
||||
{
|
||||
var reservation = CreateActiveReservation();
|
||||
|
||||
var result = reservation.Cancel();
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(ReservationStatus.Cancelled, reservation.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Cancel_AlreadyCancelledReservation_Fails()
|
||||
{
|
||||
var reservation = CreateActiveReservation();
|
||||
reservation.Cancel();
|
||||
|
||||
var result = reservation.Cancel();
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Contains("already cancelled", result.Error, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Cancel_DoesNotChangeOtherFields()
|
||||
{
|
||||
var reservation = CreateActiveReservation();
|
||||
var originalDate = reservation.Date;
|
||||
var originalEmail = reservation.EmployeeEmail;
|
||||
|
||||
reservation.Cancel();
|
||||
|
||||
Assert.Equal(originalDate, reservation.Date);
|
||||
Assert.Equal(originalEmail, reservation.EmployeeEmail);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using Randall.Domain.Reservations;
|
||||
|
||||
namespace Randall.Domain.UnitTests.Reservations;
|
||||
|
||||
public class ReservationCreateTests
|
||||
{
|
||||
private static readonly Guid WorkplaceId = Guid.NewGuid();
|
||||
private const string Email = "jane@company.com";
|
||||
private const string Name = "Jane Smith";
|
||||
|
||||
[Fact]
|
||||
public void Create_WithValidFutureDate_Succeeds()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var result = Reservation.Create(WorkplaceId, Email, Name, today, today);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.NotNull(result.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_WithTodayAsDate_Succeeds()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var result = Reservation.Create(WorkplaceId, Email, Name, today, today);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_WithMaxAdvanceDate_Succeeds()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var maxDate = today.AddDays(Reservation.MaxAdvanceDays);
|
||||
|
||||
var result = Reservation.Create(WorkplaceId, Email, Name, maxDate, today);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_WithPastDate_Fails()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var yesterday = today.AddDays(-1);
|
||||
|
||||
var result = Reservation.Create(WorkplaceId, Email, Name, yesterday, today);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Contains("past", result.Error, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_BeyondMaxAdvanceDays_Fails()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var tooFar = today.AddDays(Reservation.MaxAdvanceDays + 1);
|
||||
|
||||
var result = Reservation.Create(WorkplaceId, Email, Name, tooFar, today);
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Contains(Reservation.MaxAdvanceDays.ToString(), result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_SetsStatusToActive()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var result = Reservation.Create(WorkplaceId, Email, Name, today, today);
|
||||
|
||||
Assert.Equal(ReservationStatus.Active, result.Value!.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_PopulatesAllFields()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var result = Reservation.Create(WorkplaceId, Email, Name, today, today);
|
||||
|
||||
var reservation = result.Value!;
|
||||
Assert.Equal(WorkplaceId, reservation.WorkplaceId);
|
||||
Assert.Equal(Email, reservation.EmployeeEmail);
|
||||
Assert.Equal(Name, reservation.EmployeeName);
|
||||
Assert.Equal(today, reservation.Date);
|
||||
Assert.NotEqual(Guid.Empty, reservation.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_SetsCreatedAtToApproximatelyNow()
|
||||
{
|
||||
var before = DateTime.UtcNow;
|
||||
var today = DateOnly.FromDateTime(DateTime.UtcNow);
|
||||
var result = Reservation.Create(WorkplaceId, Email, Name, today, today);
|
||||
var after = DateTime.UtcNow;
|
||||
|
||||
Assert.InRange(result.Value!.CreatedAt, before, after);
|
||||
}
|
||||
}
|
||||
84
src/backend/tests/unit/Users/UserCreateTests.cs
Normal file
84
src/backend/tests/unit/Users/UserCreateTests.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using Randall.Domain.Users;
|
||||
|
||||
namespace Randall.Domain.UnitTests.Users;
|
||||
|
||||
public class UserCreateTests
|
||||
{
|
||||
[Fact]
|
||||
public void Create_WithValidData_Succeeds()
|
||||
{
|
||||
var result = User.Create("jane@company.com", "Jane Smith", "hash");
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.NotNull(result.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_NormalisesEmailToLowercase()
|
||||
{
|
||||
var result = User.Create("JANE@COMPANY.COM", "Jane Smith", "hash");
|
||||
|
||||
Assert.Equal("jane@company.com", result.Value!.Email);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_TrimsNameWhitespace()
|
||||
{
|
||||
var result = User.Create("jane@company.com", " Jane Smith ", "hash");
|
||||
|
||||
Assert.Equal("Jane Smith", result.Value!.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_WithEmptyEmail_Fails()
|
||||
{
|
||||
var result = User.Create("", "Jane Smith", "hash");
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Contains("email", result.Error, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_WithWhitespaceEmail_Fails()
|
||||
{
|
||||
var result = User.Create(" ", "Jane Smith", "hash");
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_WithEmptyName_Fails()
|
||||
{
|
||||
var result = User.Create("jane@company.com", "", "hash");
|
||||
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Contains("name", result.Error, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_RegularUser_IsNotApprovedByDefault()
|
||||
{
|
||||
var result = User.Create("jane@company.com", "Jane Smith", "hash");
|
||||
|
||||
Assert.False(result.Value!.IsApproved);
|
||||
Assert.False(result.Value!.IsAdmin);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_AdminUser_IsAutoApproved()
|
||||
{
|
||||
var result = User.Create("admin@company.com", "Admin", "hash", isAdmin: true);
|
||||
|
||||
Assert.True(result.Value!.IsAdmin);
|
||||
Assert.True(result.Value!.IsApproved);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_AssignsUniqueId()
|
||||
{
|
||||
var a = User.Create("a@company.com", "A", "hash").Value!;
|
||||
var b = User.Create("b@company.com", "B", "hash").Value!;
|
||||
|
||||
Assert.NotEqual(a.Id, b.Id);
|
||||
}
|
||||
}
|
||||
42
src/backend/tests/unit/Users/UserStateTests.cs
Normal file
42
src/backend/tests/unit/Users/UserStateTests.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using Randall.Domain.Users;
|
||||
|
||||
namespace Randall.Domain.UnitTests.Users;
|
||||
|
||||
public class UserStateTests
|
||||
{
|
||||
private static User CreateRegularUser() =>
|
||||
User.Create("jane@company.com", "Jane Smith", "hash").Value!;
|
||||
|
||||
[Fact]
|
||||
public void Approve_SetsIsApprovedToTrue()
|
||||
{
|
||||
var user = CreateRegularUser();
|
||||
|
||||
user.Approve();
|
||||
|
||||
Assert.True(user.IsApproved);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MakeAdmin_SetsIsAdminAndIsApproved()
|
||||
{
|
||||
var user = CreateRegularUser();
|
||||
|
||||
user.MakeAdmin();
|
||||
|
||||
Assert.True(user.IsAdmin);
|
||||
Assert.True(user.IsApproved);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MakeAdmin_OnAlreadyApprovedUser_RemainsApproved()
|
||||
{
|
||||
var user = CreateRegularUser();
|
||||
user.Approve();
|
||||
|
||||
user.MakeAdmin();
|
||||
|
||||
Assert.True(user.IsApproved);
|
||||
Assert.True(user.IsAdmin);
|
||||
}
|
||||
}
|
||||
61
src/backend/tests/unit/Workplaces/WorkplaceTests.cs
Normal file
61
src/backend/tests/unit/Workplaces/WorkplaceTests.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Randall.Domain.Workplaces;
|
||||
|
||||
namespace Randall.Domain.UnitTests.Workplaces;
|
||||
|
||||
public class WorkplaceTests
|
||||
{
|
||||
[Fact]
|
||||
public void Create_IsActiveByDefault()
|
||||
{
|
||||
var workplace = new Workplace("A1", "Pod A");
|
||||
|
||||
Assert.True(workplace.IsActive);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_SetsNameAndLocation()
|
||||
{
|
||||
var workplace = new Workplace("A1", "Pod A");
|
||||
|
||||
Assert.Equal("A1", workplace.Name);
|
||||
Assert.Equal("Pod A", workplace.Location);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_AssignsNonEmptyId()
|
||||
{
|
||||
var workplace = new Workplace("A1", "Pod A");
|
||||
|
||||
Assert.NotEqual(Guid.Empty, workplace.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Deactivate_SetsIsActiveToFalse()
|
||||
{
|
||||
var workplace = new Workplace("A1", "Pod A");
|
||||
|
||||
workplace.Deactivate();
|
||||
|
||||
Assert.False(workplace.IsActive);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Activate_AfterDeactivate_SetsIsActiveToTrue()
|
||||
{
|
||||
var workplace = new Workplace("A1", "Pod A");
|
||||
workplace.Deactivate();
|
||||
|
||||
workplace.Activate();
|
||||
|
||||
Assert.True(workplace.IsActive);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_TwoWorkplaces_HaveDifferentIds()
|
||||
{
|
||||
var a = new Workplace("A1", "Pod A");
|
||||
var b = new Workplace("A2", "Pod A");
|
||||
|
||||
Assert.NotEqual(a.Id, b.Id);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user