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 @@ -15,6 +15,7 @@ public class GetProjectStructureEndpoint : IEndpointDefinition
public void DefineServices(IServiceCollection services)
{
services.AddScoped<IGetProjectFilesUseCase, GetProjectFilesService>();
services.AddScoped<IGetAvailableScriptTypesUseCase, GetAvailableScriptTypesService>();
}

public void DefineEndpoints(IEndpointRouteBuilder app)
Expand Down Expand Up @@ -79,19 +80,17 @@ private static async Task<
);
}

private static async Task<Ok<WebGetAvailableScriptTypesResponse>> GetAvailableScriptTypes(
private static Ok<WebGetAvailableScriptTypesResponse> GetAvailableScriptTypes(
IGetAvailableScriptTypesUseCase useCase,
[FromRoute] string projectId
)
{
await Task.CompletedTask;
// TODO FIXIT: remove hardcoded value
var scriptTypes = useCase.GetAvailableScriptTypes();

return TypedResults.Ok(
new WebGetAvailableScriptTypesResponse([
new WebScriptLanguage("csharp", ".cs"),
new WebScriptLanguage("python", ".py"),
new WebScriptLanguage("javascript", ".js"),
])
new WebGetAvailableScriptTypesResponse(
scriptTypes.Select(s => new WebScriptLanguage(s.Name, s.Extension)).ToList()
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using ScriptBee.Domain.Model.Plugins.Manifest;
using ScriptBee.Domain.Model.ProjectStructure;
using ScriptBee.Plugins.Loader;
using ScriptBee.UseCases.Gateway.ProjectStructure;

namespace ScriptBee.Service.Gateway.ProjectStructure;

public class GetAvailableScriptTypesService(IPluginRepository pluginRepository)
: IGetAvailableScriptTypesUseCase
{
public IEnumerable<ScriptLanguage> GetAvailableScriptTypes()
{
var defaultLanguages = new List<ScriptLanguage>
{
new("csharp", ".cs"),
new("python", ".py"),
new("javascript", ".js"),
};

var pluginLanguages = pluginRepository
.GetLoadedPlugins()
.SelectMany(p => p.Manifest.ExtensionPoints)
.OfType<ScriptRunnerPluginExtensionPoint>()
.Where(r =>
!defaultLanguages.Any(dl =>
dl.Name.Equals(r.Language, StringComparison.InvariantCultureIgnoreCase)
)
)
.Select(r => new ScriptLanguage(r.Language, r.Extension));

return defaultLanguages.Concat(pluginLanguages);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using ScriptBee.Domain.Model.ProjectStructure;

namespace ScriptBee.UseCases.Gateway.ProjectStructure;

public interface IGetAvailableScriptTypesUseCase
{
IEnumerable<ScriptLanguage> GetAvailableScriptTypes();
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,34 @@ [new ScriptId(Guid.NewGuid())]

await response.AssertResponse(HttpStatusCode.OK, responsePath);
}

[Theory]
[FilePath("TestData/GetProjectStructure/available-script-types.json")]
public async Task GetAvailableScriptTypes_ShouldReturnOk(string responsePath)
{
var useCase = Substitute.For<IGetAvailableScriptTypesUseCase>();
useCase
.GetAvailableScriptTypes()
.Returns(
new List<ScriptLanguage>
{
new("csharp", ".cs"),
new("python", ".py"),
new("javascript", ".js"),
}
);

TestApiCaller<Program> api = new("/api/projects/id/structure/available-script-types");
var response = await api.GetApi(
new TestWebApplicationFactory<Program>(
outputHelper,
services =>
{
services.AddSingleton(useCase);
}
)
);

await response.AssertResponse(HttpStatusCode.OK, responsePath);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"data": [
{
"name": "csharp",
"extension": ".cs"
},
{
"name": "python",
"extension": ".py"
},
{
"name": "javascript",
"extension": ".js"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using NSubstitute;
using ScriptBee.Domain.Model.Plugins;
using ScriptBee.Domain.Model.Plugins.Manifest;
using ScriptBee.Domain.Model.ProjectStructure;
using ScriptBee.Plugins.Loader;
using ScriptBee.Service.Gateway.ProjectStructure;

namespace ScriptBee.Service.Gateway.Tests.ProjectStructure;

public class GetAvailableScriptTypesServiceTests
{
private readonly IPluginRepository _pluginRepository = Substitute.For<IPluginRepository>();
private readonly GetAvailableScriptTypesService _service;

public GetAvailableScriptTypesServiceTests()
{
_service = new GetAvailableScriptTypesService(_pluginRepository);
}

[Fact]
public void GivenNoPlugins_WhenGetAvailableScriptTypes_ThenReturnDefaults()
{
_pluginRepository.GetLoadedPlugins().Returns(Enumerable.Empty<Plugin>());

var result = _service.GetAvailableScriptTypes();

var languages = result.ToList();
languages.Count.ShouldBe(3);
languages.ShouldContain(new ScriptLanguage("csharp", ".cs"));
languages.ShouldContain(new ScriptLanguage("python", ".py"));
languages.ShouldContain(new ScriptLanguage("javascript", ".js"));
}

[Fact]
public void GivenPlugins_WhenGetAvailableScriptTypes_ThenReturnDefaultsAndPlugins()
{
var manifest = new PluginManifest
{
ExtensionPoints =
[
new ScriptRunnerPluginExtensionPoint { Language = "lua", Extension = ".lua" },
],
};
var plugin = new Plugin("path", new PluginId("lua-plugin", new Version(1, 0)), manifest);
_pluginRepository.GetLoadedPlugins().Returns(new List<Plugin> { plugin });

var result = _service.GetAvailableScriptTypes();

var languages = result.ToList();
languages.Count.ShouldBe(4);
languages.ShouldContain(new ScriptLanguage("csharp", ".cs"));
languages.ShouldContain(new ScriptLanguage("python", ".py"));
languages.ShouldContain(new ScriptLanguage("javascript", ".js"));
languages.ShouldContain(new ScriptLanguage("lua", ".lua"));
}

[Fact]
public void GivenPluginWithDefaultName_WhenGetAvailableScriptTypes_ThenDoNotDuplicate()
{
var manifest = new PluginManifest
{
ExtensionPoints =
[
new ScriptRunnerPluginExtensionPoint { Language = "CSharp", Extension = ".cs" },
],
};
var plugin = new Plugin("path", new PluginId("csharp-plugin", new Version(1, 0)), manifest);
_pluginRepository.GetLoadedPlugins().Returns(new List<Plugin> { plugin });

var result = _service.GetAvailableScriptTypes();

result.Count().ShouldBe(3);
}

[Fact]
public void GivenPluginsWithOtherExtensionPoints_WhenGetAvailableScriptTypes_ThenReturnOnlyScriptRunnerDefaultsAndPlugins()
{
var manifest = new PluginManifest
{
ExtensionPoints =
[
new ScriptRunnerPluginExtensionPoint { Language = "lua", Extension = ".lua" },
new LinkerPluginExtensionPoint
{
Kind = "Linker",
EntryPoint = "Entry",
Version = "1.0",
},
],
};
var plugin = new Plugin("path", new PluginId("lua-plugin", new Version(1, 0)), manifest);
_pluginRepository.GetLoadedPlugins().Returns(new List<Plugin> { plugin });

var result = _service.GetAvailableScriptTypes();

var languages = result.ToList();
languages.Count.ShouldBe(4);
languages.ShouldContain(new ScriptLanguage("lua", ".lua"));
languages.ShouldNotContain(new ScriptLanguage("Linker", ""));
}
}
Loading