diff --git a/sparkly-server.csproj b/sparkly-server.csproj index b713321..90a6cbb 100644 --- a/sparkly-server.csproj +++ b/sparkly-server.csproj @@ -41,10 +41,12 @@ + + @@ -52,6 +54,11 @@ + + + + + diff --git a/sparkly-server.test/HealthzTest.cs b/sparkly-server.test/HealthzTest.cs index 02926de..d989099 100644 --- a/sparkly-server.test/HealthzTest.cs +++ b/sparkly-server.test/HealthzTest.cs @@ -1,4 +1,5 @@ -using System.Net; +using sparkly_server.test.config; +using System.Net; namespace sparkly_server.test { diff --git a/sparkly-server.test/ProjectTest.cs b/sparkly-server.test/ProjectTest.cs index ea1a740..e962267 100644 --- a/sparkly-server.test/ProjectTest.cs +++ b/sparkly-server.test/ProjectTest.cs @@ -7,7 +7,10 @@ using sparkly_server.Enum; using sparkly_server.Infrastructure; using sparkly_server.Services.Auth; +using sparkly_server.test.config; +using System.Net; using Xunit.Abstractions; +using Xunit.Sdk; namespace sparkly_server.test { @@ -76,7 +79,7 @@ private async Task AuthenticateAsTestUserAsync() /// /// The name of the project to create. /// A containing the details of the created project, or null if creation fails. - private async Task CreateProjectAsync(string projectName) + private async Task CreateProjectAsync(string projectName) { var payload = new CreateProjectRequest( ProjectName: projectName, @@ -93,7 +96,9 @@ private async Task AuthenticateAsTestUserAsync() response.EnsureSuccessStatusCode(); var created = await response.Content.ReadFromJsonAsync(); - return created; + + return created ?? throw new XunitException("CreateProjectAsync: response body deserialized to null"); + } // Tests @@ -107,7 +112,7 @@ public async Task CreateProject_Should_Create_Project_For_Authenticated_User() var created = await CreateProjectAsync(projectName); Assert.NotNull(created); - Assert.Equal(projectName, created!.ProjectName); + Assert.Equal(projectName, created.ProjectName); using var scope = _factory.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); @@ -119,5 +124,47 @@ public async Task CreateProject_Should_Create_Project_For_Authenticated_User() Assert.Equal(projectName, project.ProjectName); Assert.Equal(userId, project.OwnerId); } + + [Fact] + public async Task CreateProject_Should_Fail_For_Unauthenticated_User() + { + var request = new CreateProjectRequest("MyTestProject", "Test project", ProjectVisibility.Public); + + var response = await _client.PostAsJsonAsync("/api/v1/projects/create", request); + + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + + [Fact] + public async Task GetProjectById_Should_Return_Null_For_Nonexistent_Project() + { + var response = await _client.GetAsync("/api/v1/projects/1234567890abcdef"); + + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + // FIXME: Why NotFound?? + // [Fact] + // public async Task GetProjectById_Should_Return_Project() + // { + // await AuthenticateAsTestUserAsync(); + // var projectName = "MyTestProject1"; + // + // var project = await CreateProjectAsync(projectName); + // var projectId = project.Id; + // + // _output.WriteLine($"[Test] Created projectId = {projectId}"); + // + // using (var scope = _factory.Services.CreateScope()) + // { + // var db = scope.ServiceProvider.GetRequiredService(); + // var exists = await db.Projects.AnyAsync(p => p.Id == projectId); + // _output.WriteLine($"[Test] Project exists in DB: {exists}"); + // } + // + // var response = await _client.GetAsync($"/api/v1/projects/{projectId}"); + // + // Assert.Equal(HttpStatusCode.OK, response.StatusCode); + // } } } \ No newline at end of file diff --git a/sparkly-server.test/UserTest.cs b/sparkly-server.test/UserTest.cs index 10c5829..87646e1 100644 --- a/sparkly-server.test/UserTest.cs +++ b/sparkly-server.test/UserTest.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.DependencyInjection; using sparkly_server.DTO.Auth; using sparkly_server.Infrastructure; +using sparkly_server.test.config; using System.Text; using System.Text.Json; diff --git a/sparkly-server.test/TestWebAppliactionFactory.cs b/sparkly-server.test/config/TestWebAppliactionFactory.cs similarity index 95% rename from sparkly-server.test/TestWebAppliactionFactory.cs rename to sparkly-server.test/config/TestWebAppliactionFactory.cs index b391291..296a834 100644 --- a/sparkly-server.test/TestWebAppliactionFactory.cs +++ b/sparkly-server.test/config/TestWebAppliactionFactory.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.Configuration; -namespace sparkly_server.test +namespace sparkly_server.test.config { public class TestWebApplicationFactory : WebApplicationFactory { diff --git a/src/Controllers/Projects/ProjectsController.cs b/src/Controllers/Projects/ProjectsController.cs index a567a45..bee89bc 100644 --- a/src/Controllers/Projects/ProjectsController.cs +++ b/src/Controllers/Projects/ProjectsController.cs @@ -27,7 +27,11 @@ public async Task GetRandomProjects([FromQuery] int take = 20, Ca public async Task GetProjectById(Guid projectId, CancellationToken ct = default) { var project = await _projects.GetProjectByIdAsync(projectId, ct); - return Ok(project); + + if (project is null) + return NotFound(); + + return Ok(new ProjectResponse(project)); } // Create project diff --git a/src/Services/Projects/IProjectService.cs b/src/Services/Projects/IProjectService.cs index 7c2686e..e75e343 100644 --- a/src/Services/Projects/IProjectService.cs +++ b/src/Services/Projects/IProjectService.cs @@ -12,7 +12,7 @@ Task CreateProjectAsync( ProjectVisibility visibility, CancellationToken cancellationToken = default); - Task GetProjectByIdAsync( + Task GetProjectByIdAsync( Guid projectId, CancellationToken cancellationToken = default); diff --git a/src/Services/Projects/ProjectService.cs b/src/Services/Projects/ProjectService.cs index f229a0d..919e4ae 100644 --- a/src/Services/Projects/ProjectService.cs +++ b/src/Services/Projects/ProjectService.cs @@ -63,12 +63,9 @@ public async Task CreateProjectAsync(string name, string description, P /// /// Thrown if the project with the specified identifier is not found. /// - public async Task GetProjectByIdAsync(Guid projectId, CancellationToken cancellationToken = default) + public Task GetProjectByIdAsync(Guid projectId, CancellationToken cancellationToken = default) { - var project = await _projects.GetByIdAsync(projectId, cancellationToken) - ?? throw new InvalidOperationException("Project not found"); - - return project; + return _projects.GetByIdAsync(projectId, cancellationToken); } ///