Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private static async Task<DownloadResult> DownloadIndividualFile(
namedStream.Name
),
error => error.ToProblem(context),
error =>error.ToProblem(context)
error => error.ToProblem(context)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private static async Task<

return result.Match<Results<Ok<WebGetAnalysisResultConsole>, NotFound<ProblemDetails>>>(
content => TypedResults.Ok(new WebGetAnalysisResultConsole(content)),
error =>error.ToProblem(context)
error => error.ToProblem(context)
);
}

Expand Down Expand Up @@ -95,7 +95,7 @@ private static async Task<

return result.Match<Results<Ok<WebGetAnalysisResultFileList>, NotFound<ProblemDetails>>>(
files => TypedResults.Ok(WebGetAnalysisResultFileList.Map(files)),
error =>error.ToProblem(context)
error => error.ToProblem(context)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ CancellationToken cancellationToken
return result.Match<Results<NoContent, NotFound<ProblemDetails>>>(
_ => TypedResults.NoContent(),
error => error.ToProblem(context),
error =>error.ToProblem(context)
error => error.ToProblem(context)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ CancellationToken cancellationToken
return result.Match<Results<NoContent, NotFound<ProblemDetails>>>(
_ => TypedResults.NoContent(),
error => error.ToProblem(context),
error =>error.ToProblem(context)
error => error.ToProblem(context)
);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using ScriptBee.Common.Web;
using ScriptBee.Domain.Model.Project;
using ScriptBee.Service.Project.Analysis;
using ScriptBee.UseCases.Project.Analysis;
using ScriptBee.Web.EndpointDefinitions.Instances.Contracts;
using ScriptBee.Web.Exceptions;

namespace ScriptBee.Web.EndpointDefinitions.Instances;

using GetCurrentInstanceType = Results<Ok<WebProjectInstance>, NotFound<ProblemDetails>>;

public class GetCurrentInstanceEndpoint : IEndpointDefinition
{
public void DefineServices(IServiceCollection services)
{
services.AddSingleton<IGetCurrentInstanceUseCase, GetCurrentInstanceService>();
}

public void DefineEndpoints(IEndpointRouteBuilder app)
{
app.MapGet("/api/projects/{projectId}/instances/current", GetCurrentInstance);
}

private static async Task<GetCurrentInstanceType> GetCurrentInstance(
HttpContext context,
[FromRoute] string projectId,
IGetCurrentInstanceUseCase useCase,
CancellationToken cancellationToken
)
{
var result = await useCase.GetCurrentInstance(
ProjectId.FromValue(projectId),
cancellationToken
);

return result.Match<GetCurrentInstanceType>(
instanceInfo => TypedResults.Ok(WebProjectInstance.Map(instanceInfo)),
error => error.ToNotFoundProblem(context)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ public class GetProjectInstancesEndpoint : IEndpointDefinition
public void DefineServices(IServiceCollection services)
{
services.AddSingleton<IGetProjectInstancesUseCase, GetProjectInstancesService>();
services.AddSingleton<IGetCurrentInstanceUseCase, GetCurrentInstanceService>();
}

public void DefineEndpoints(IEndpointRouteBuilder app)
{
app.MapGet("/api/projects/{projectId}/instances", GetAllInstances);
app.MapGet("/api/projects/{projectId}/instances/current", GetCurrentInstance);
}

private static async Task<Ok<WebGetProjectInstancesListResponse>> GetAllInstances(
Expand All @@ -33,27 +31,4 @@ private static async Task<Ok<WebGetProjectInstancesListResponse>> GetAllInstance

return TypedResults.Ok(WebGetProjectInstancesListResponse.Map(calculationInstanceInfos));
}

private static async Task<Ok<WebGetProjectInstanceInfo>> GetCurrentInstance(
[FromRoute] string projectId
)
{
await Task.CompletedTask;

// TODO FIXIT: remove hardcoded value

return TypedResults.Ok(
new WebGetProjectInstanceInfo(
"instance-id",
["honeydew", "InspectorGit"],
["software-analysis"],
new Dictionary<string, IEnumerable<string>>
{
{ "InspectorGit", ["honeydew.iglog"] },
{ "honeydew", ["honeydew-raw.json"] },
},
DateTimeOffset.UtcNow
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private static async Task<UploadResult> UploadLoaderFiles(
TypedResults.Ok(
new WebUploadLoaderFilesResponse(loaderId, fileData.Select(f => f.Name))
),
error =>error.ToProblem(context)
error => error.ToProblem(context)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace ScriptBee.Web.EndpointDefinitions.ProjectStructure;
using CreateResponse = Results<
Created<WebScriptData>,
NotFound<ProblemDetails>,
BadRequest<ProblemDetails>,
ValidationProblem,
Conflict<ProblemDetails>
>;
Expand Down Expand Up @@ -50,6 +51,7 @@ private static async Task<CreateResponse> CreateProjectScript(
WebScriptData.Map(script)
),
error => error.ToProblem(context),
error => error.ToBadRequestProblem(context),
error => error.ToProblem(context),
error => error.ToProblem(context)
);
Expand Down
27 changes: 27 additions & 0 deletions src/Adapters/Driving/Web/Exceptions/ApiErrorExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using ScriptBee.Common.Web.Extensions;
using ScriptBee.Domain.Model.Analysis;
using ScriptBee.Domain.Model.Errors;
using ScriptBee.Web.EndpointDefinitions.ProjectStructure.Contracts;

Expand Down Expand Up @@ -101,4 +102,30 @@ HttpContext context
)
);
}

public static BadRequest<ProblemDetails> ToBadRequestProblem(
this NoInstanceAllocatedForProjectError error,
HttpContext context
)
{
return TypedResults.BadRequest(
context.ToProblemDetails(
"No Instance Allocated For Project",
$"There is no instance allocated for project with the ID '{error.ProjectId}'"
)
);
}

public static NotFound<ProblemDetails> ToNotFoundProblem(
this NoInstanceAllocatedForProjectError error,
HttpContext context
)
{
return TypedResults.NotFound(
context.ToProblemDetails(
"No Instance Allocated For Project",
$"There is no instance allocated for project with the ID '{error.ProjectId}'"
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using ScriptBee.Domain.Model.Project;

namespace ScriptBee.Domain.Model.Analysis;

public record NoInstanceAllocatedForProjectError(ProjectId ProjectId);
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
using ScriptBee.Domain.Model.Instance;
using OneOf;
using ScriptBee.Domain.Model.Analysis;
using ScriptBee.Domain.Model.Instance;
using ScriptBee.Domain.Model.Project;
using ScriptBee.Ports.Instance;
using ScriptBee.UseCases.Project.Analysis;

namespace ScriptBee.Service.Project.Analysis;

public class GetCurrentInstanceService : IGetCurrentInstanceUseCase
public class GetCurrentInstanceService(IGetAllProjectInstances getAllProjectInstances)
: IGetCurrentInstanceUseCase
{
public Task<InstanceInfo> GetOrAllocate(
public async Task<OneOf<InstanceInfo, NoInstanceAllocatedForProjectError>> GetCurrentInstance(
ProjectId projectId,
CancellationToken cancellationToken = default
)
{
// TODO FIXIT(#45): implement it
throw new NotImplementedException();
var instanceInfos = await getAllProjectInstances.GetAll(projectId, cancellationToken);

var instanceInfo = instanceInfos.FirstOrDefault();

if (instanceInfo == null)
{
return new NoInstanceAllocatedForProjectError(projectId);
}

return instanceInfo;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using OneOf;
using ScriptBee.Common;
using ScriptBee.Domain.Model.Analysis;
using ScriptBee.Domain.Model.Errors;
using ScriptBee.Domain.Model.Instance;
using ScriptBee.Domain.Model.Project;
using ScriptBee.Domain.Model.ProjectStructure;
using ScriptBee.Ports.Files;
Expand All @@ -15,6 +17,7 @@ namespace ScriptBee.Service.Project.ProjectStructure;
using CreateResult = OneOf<
Script,
ProjectDoesNotExistsError,
NoInstanceAllocatedForProjectError,
ScriptLanguageDoesNotExistsError,
ScriptPathAlreadyExistsError
>;
Expand Down Expand Up @@ -47,10 +50,25 @@ private async Task<CreateResult> Create(
CancellationToken cancellationToken = default
)
{
var instanceInfo = await currentInstanceUseCase.GetOrAllocate(
var result = await currentInstanceUseCase.GetCurrentInstance(
projectDetails.Id,
cancellationToken
);

return await result.Match<Task<CreateResult>>(
async instanceInfo =>
await Create(command, instanceInfo, projectDetails, cancellationToken),
error => Task.FromResult<CreateResult>(error)
);
}

private async Task<CreateResult> Create(
CreateScriptCommand command,
InstanceInfo instanceInfo,
ProjectDetails projectDetails,
CancellationToken cancellationToken = default
)
{
var languageResult = await getScriptLanguages.Get(
instanceInfo,
command.Language,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using ScriptBee.Domain.Model.Instance;
using OneOf;
using ScriptBee.Domain.Model.Analysis;
using ScriptBee.Domain.Model.Instance;
using ScriptBee.Domain.Model.Project;

namespace ScriptBee.UseCases.Project.Analysis;

public interface IGetCurrentInstanceUseCase
{
Task<InstanceInfo> GetOrAllocate(
Task<OneOf<InstanceInfo, NoInstanceAllocatedForProjectError>> GetCurrentInstance(
ProjectId projectId,
CancellationToken cancellationToken = default
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using OneOf;
using ScriptBee.Domain.Model.Analysis;
using ScriptBee.Domain.Model.Errors;
using ScriptBee.Domain.Model.ProjectStructure;

Expand All @@ -10,6 +11,7 @@ public interface ICreateScriptUseCase
OneOf<
Script,
ProjectDoesNotExistsError,
NoInstanceAllocatedForProjectError,
ScriptLanguageDoesNotExistsError,
ScriptPathAlreadyExistsError
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System.Net;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using OneOf;
using ScriptBee.Domain.Model.Analysis;
using ScriptBee.Domain.Model.Instance;
using ScriptBee.Domain.Model.Project;
using ScriptBee.Tests.Common;
using ScriptBee.UseCases.Project.Analysis;
using ScriptBee.Web.EndpointDefinitions.Instances.Contracts;
using Xunit.Abstractions;
using static ScriptBee.Tests.Common.InstanceInfoFixture;
using static ScriptBee.Tests.Common.ProblemValidationUtils;

namespace ScriptBee.Web.Tests.EndpointDefinitions.Instances;

public class GetCurrentInstanceEndpointTest(ITestOutputHelper outputHelper)
{
private const string TestUrl = "/api/projects/project-id/instances/current";
private readonly TestApiCaller<Program> _api = new(TestUrl);

[Fact]
public async Task ShouldReturnInstanceInfoWithContext()
{
var useCase = Substitute.For<IGetCurrentInstanceUseCase>();
var projectId = ProjectId.FromValue("project-id");
var instanceInfo = BasicInstanceInfo(projectId);
useCase
.GetCurrentInstance(projectId, Arg.Any<CancellationToken>())
.Returns(
Task.FromResult<OneOf<InstanceInfo, NoInstanceAllocatedForProjectError>>(
instanceInfo
)
);

var response = await _api.GetApi(
new TestWebApplicationFactory<Program>(
outputHelper,
services =>
{
services.AddSingleton(useCase);
}
)
);

response.StatusCode.ShouldBe(HttpStatusCode.OK);
var webProjectInstanceInfo = await response.ReadContentAsync<WebProjectInstance>();
webProjectInstanceInfo.Id.ShouldBe(instanceInfo.Id.ToString());
webProjectInstanceInfo.CreationDate.ShouldBe(instanceInfo.CreationDate);
}

[Fact]
public async Task NoInstanceAllocatedForProject_ShouldReturnNotFound()
{
var useCase = Substitute.For<IGetCurrentInstanceUseCase>();
var projectId = ProjectId.FromValue("project-id");
useCase
.GetCurrentInstance(projectId, Arg.Any<CancellationToken>())
.Returns(
Task.FromResult<OneOf<InstanceInfo, NoInstanceAllocatedForProjectError>>(
new NoInstanceAllocatedForProjectError(projectId)
)
);

var response = await _api.GetApi(
new TestWebApplicationFactory<Program>(
outputHelper,
services =>
{
services.AddSingleton(useCase);
}
)
);

await AssertNoInstanceAllocatedForProjectNotFoundProblem(response, TestUrl);
}
}
Loading
Loading