Skip to content

Commit 51c8a03

Browse files
Refactor test configuration, improve project test coverage, update GetProjectById to handle null results, and reorganize namespaces for better structure.
1 parent 5831056 commit 51c8a03

File tree

8 files changed

+68
-12
lines changed

8 files changed

+68
-12
lines changed

sparkly-server.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,24 @@
4141

4242
<ItemGroup>
4343
<None Remove="Properties\launchSettings.json" />
44+
<None Remove="sparkly-server.test\config\**" />
4445
</ItemGroup>
4546

4647
<ItemGroup>
4748
<Content Include=".github\workflows\ci.yml" />
49+
<Content Remove="sparkly-server.test\config\**" />
4850
</ItemGroup>
4951

5052
<ItemGroup>
5153
<Compile Remove="sparkly-server.test\HealthzTest.cs" />
5254
<Compile Remove="sparkly-server.test\UserTest.cs" />
5355
<Compile Remove="sparkly-server.test\ProjectTest.cs" />
5456
<Compile Remove="sparkly-server.test\TestWebAppliactionFactory.cs" />
57+
<Compile Remove="sparkly-server.test\config\**" />
58+
</ItemGroup>
59+
60+
<ItemGroup>
61+
<EmbeddedResource Remove="sparkly-server.test\config\**" />
5562
</ItemGroup>
5663

5764
</Project>

sparkly-server.test/HealthzTest.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Net;
1+
using sparkly_server.test.config;
2+
using System.Net;
23

34
namespace sparkly_server.test
45
{

sparkly-server.test/ProjectTest.cs

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
using sparkly_server.Enum;
88
using sparkly_server.Infrastructure;
99
using sparkly_server.Services.Auth;
10+
using sparkly_server.test.config;
11+
using System.Net;
1012
using Xunit.Abstractions;
13+
using Xunit.Sdk;
1114

1215
namespace sparkly_server.test
1316
{
@@ -76,7 +79,7 @@ private async Task<Guid> AuthenticateAsTestUserAsync()
7679
/// </summary>
7780
/// <param name="projectName">The name of the project to create.</param>
7881
/// <returns>A <see cref="ProjectResponse"/> containing the details of the created project, or null if creation fails.</returns>
79-
private async Task<ProjectResponse?> CreateProjectAsync(string projectName)
82+
private async Task<ProjectResponse> CreateProjectAsync(string projectName)
8083
{
8184
var payload = new CreateProjectRequest(
8285
ProjectName: projectName,
@@ -93,7 +96,9 @@ private async Task<Guid> AuthenticateAsTestUserAsync()
9396
response.EnsureSuccessStatusCode();
9497

9598
var created = await response.Content.ReadFromJsonAsync<ProjectResponse>();
96-
return created;
99+
100+
return created ?? throw new XunitException("CreateProjectAsync: response body deserialized to null");
101+
97102
}
98103

99104
// Tests
@@ -107,7 +112,7 @@ public async Task CreateProject_Should_Create_Project_For_Authenticated_User()
107112
var created = await CreateProjectAsync(projectName);
108113

109114
Assert.NotNull(created);
110-
Assert.Equal(projectName, created!.ProjectName);
115+
Assert.Equal(projectName, created.ProjectName);
111116

112117
using var scope = _factory.Services.CreateScope();
113118
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
@@ -119,5 +124,46 @@ public async Task CreateProject_Should_Create_Project_For_Authenticated_User()
119124
Assert.Equal(projectName, project.ProjectName);
120125
Assert.Equal(userId, project.OwnerId);
121126
}
127+
128+
[Fact]
129+
public async Task CreateProject_Should_Fail_For_Unauthenticated_User()
130+
{
131+
var request = new CreateProjectRequest("MyTestProject", "Test project", ProjectVisibility.Public);
132+
133+
var response = await _client.PostAsJsonAsync("/api/v1/projects/create", request);
134+
135+
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
136+
}
137+
138+
[Fact]
139+
public async Task GetProjectById_Should_Return_Null_For_Nonexistent_Project()
140+
{
141+
var response = await _client.GetAsync("/api/v1/projects/1234567890abcdef");
142+
143+
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
144+
}
145+
146+
[Fact]
147+
public async Task GetProjectById_Should_Return_Project()
148+
{
149+
await AuthenticateAsTestUserAsync();
150+
var projectName = "MyTestProject1";
151+
152+
var project = await CreateProjectAsync(projectName);
153+
var projectId = project.Id;
154+
155+
_output.WriteLine($"[Test] Created projectId = {projectId}");
156+
157+
using (var scope = _factory.Services.CreateScope())
158+
{
159+
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
160+
var exists = await db.Projects.AnyAsync(p => p.Id == projectId);
161+
_output.WriteLine($"[Test] Project exists in DB: {exists}");
162+
}
163+
164+
var response = await _client.GetAsync($"/api/v1/projects/{projectId}");
165+
166+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
167+
}
122168
}
123169
}

sparkly-server.test/UserTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.Extensions.DependencyInjection;
22
using sparkly_server.DTO.Auth;
33
using sparkly_server.Infrastructure;
4+
using sparkly_server.test.config;
45
using System.Text;
56
using System.Text.Json;
67

sparkly-server.test/TestWebAppliactionFactory.cs renamed to sparkly-server.test/config/TestWebAppliactionFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using Microsoft.AspNetCore.Mvc.Testing;
33
using Microsoft.Extensions.Configuration;
44

5-
namespace sparkly_server.test
5+
namespace sparkly_server.test.config
66
{
77
public class TestWebApplicationFactory : WebApplicationFactory<Program>
88
{

src/Controllers/Projects/ProjectsController.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ public async Task<IActionResult> GetRandomProjects([FromQuery] int take = 20, Ca
2727
public async Task<IActionResult> GetProjectById(Guid projectId, CancellationToken ct = default)
2828
{
2929
var project = await _projects.GetProjectByIdAsync(projectId, ct);
30-
return Ok(project);
30+
31+
if (project is null)
32+
return NotFound();
33+
34+
return Ok(new ProjectResponse(project));
3135
}
3236

3337
// Create project

src/Services/Projects/IProjectService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Task<Project> CreateProjectAsync(
1212
ProjectVisibility visibility,
1313
CancellationToken cancellationToken = default);
1414

15-
Task<Project> GetProjectByIdAsync(
15+
Task<Project?> GetProjectByIdAsync(
1616
Guid projectId, CancellationToken
1717
cancellationToken = default);
1818

src/Services/Projects/ProjectService.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,9 @@ public async Task<Project> CreateProjectAsync(string name, string description, P
6363
/// <exception cref="InvalidOperationException">
6464
/// Thrown if the project with the specified identifier is not found.
6565
/// </exception>
66-
public async Task<Project> GetProjectByIdAsync(Guid projectId, CancellationToken cancellationToken = default)
66+
public Task<Project?> GetProjectByIdAsync(Guid projectId, CancellationToken cancellationToken = default)
6767
{
68-
var project = await _projects.GetByIdAsync(projectId, cancellationToken)
69-
?? throw new InvalidOperationException("Project not found");
70-
71-
return project;
68+
return _projects.GetByIdAsync(projectId, cancellationToken);
7269
}
7370

7471
/// <summary>

0 commit comments

Comments
 (0)