Updated repository manager for the new backend
This commit is contained in:
@@ -1,29 +1,39 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DiscordBotCore.Interfaces.PluginManagement;
|
using DiscordBotCore.Interfaces.PluginManagement;
|
||||||
using DiscordBotCore.Others;
|
using DiscordBotCore.Others;
|
||||||
using DiscordBotCore.Plugin;
|
using DiscordBotCore.Plugin;
|
||||||
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
|
|
||||||
namespace DiscordBotCore.Online.Helpers;
|
namespace DiscordBotCore.Online.Helpers;
|
||||||
|
|
||||||
public class PluginRepository : IPluginRepository
|
public class PluginRepository : IPluginRepository
|
||||||
{
|
{
|
||||||
private readonly IPluginRepositoryConfiguration _pluginRepositoryConfiguration;
|
private readonly IPluginRepositoryConfiguration _pluginRepositoryConfiguration;
|
||||||
public HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
public PluginRepository(IPluginRepositoryConfiguration pluginRepositoryConfiguration)
|
public PluginRepository(IPluginRepositoryConfiguration pluginRepositoryConfiguration)
|
||||||
{
|
{
|
||||||
_pluginRepositoryConfiguration = pluginRepositoryConfiguration;
|
_pluginRepositoryConfiguration = pluginRepositoryConfiguration;
|
||||||
_httpClient = new HttpClient();
|
_httpClient = new HttpClient();
|
||||||
_httpClient.BaseAddress = new System.Uri(_pluginRepositoryConfiguration.BaseUrl);
|
_httpClient.BaseAddress = new Uri(_pluginRepositoryConfiguration.BaseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<List<OnlinePlugin>> GetAllPlugins()
|
public async Task<List<OnlinePlugin>> GetAllPlugins()
|
||||||
{
|
{
|
||||||
HttpResponseMessage response =
|
int operatingSystem = OS.GetOperatingSystemInt();
|
||||||
await _httpClient.GetAsync(_pluginRepositoryConfiguration.PluginRepositoryLocation + "get-all-plugins");
|
bool includeNotApproved = false;
|
||||||
|
|
||||||
|
string url = CreateUrlWithQueryParams(_pluginRepositoryConfiguration.PluginRepositoryLocation,
|
||||||
|
"get-all-plugins", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "operatingSystem", operatingSystem.ToString() },
|
||||||
|
{ "includeNotApproved", includeNotApproved.ToString() }
|
||||||
|
});
|
||||||
|
|
||||||
|
HttpResponseMessage response = await _httpClient.GetAsync(url);
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
@@ -39,9 +49,13 @@ public class PluginRepository : IPluginRepository
|
|||||||
|
|
||||||
public async Task<OnlinePlugin?> GetPluginById(int pluginId)
|
public async Task<OnlinePlugin?> GetPluginById(int pluginId)
|
||||||
{
|
{
|
||||||
HttpResponseMessage response =
|
string url = CreateUrlWithQueryParams(_pluginRepositoryConfiguration.PluginRepositoryLocation,
|
||||||
await _httpClient.GetAsync(_pluginRepositoryConfiguration.PluginRepositoryLocation +
|
"get-plugin", new Dictionary<string, string>
|
||||||
$"get-plugin/{pluginId}");
|
{
|
||||||
|
{ "pluginId", pluginId.ToString() },
|
||||||
|
{ "includeNotApproved", "false" }
|
||||||
|
});
|
||||||
|
HttpResponseMessage response = await _httpClient.GetAsync(url);
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
@@ -57,9 +71,14 @@ public class PluginRepository : IPluginRepository
|
|||||||
|
|
||||||
public async Task<OnlinePlugin?> GetPluginByName(string pluginName)
|
public async Task<OnlinePlugin?> GetPluginByName(string pluginName)
|
||||||
{
|
{
|
||||||
HttpResponseMessage response =
|
string url = CreateUrlWithQueryParams(_pluginRepositoryConfiguration.PluginRepositoryLocation,
|
||||||
await _httpClient.GetAsync(_pluginRepositoryConfiguration.PluginRepositoryLocation +
|
"get-plugin-by-name", new Dictionary<string, string>
|
||||||
$"get-plugin-by-name/{pluginName}");
|
{
|
||||||
|
{ "pluginName", pluginName },
|
||||||
|
{ "operatingSystem", OS.GetOperatingSystemInt().ToString() },
|
||||||
|
{ "includeNotApproved", "false" }
|
||||||
|
});
|
||||||
|
HttpResponseMessage response = await _httpClient.GetAsync(url);
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
@@ -75,7 +94,13 @@ public class PluginRepository : IPluginRepository
|
|||||||
|
|
||||||
public async Task<List<OnlineDependencyInfo>> GetDependenciesForPlugin(int pluginId)
|
public async Task<List<OnlineDependencyInfo>> GetDependenciesForPlugin(int pluginId)
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await _httpClient.GetAsync(_pluginRepositoryConfiguration.DependenciesRepositoryLocation + $"get-dependencies-for-plugin/{pluginId}");
|
string url = CreateUrlWithQueryParams(_pluginRepositoryConfiguration.DependenciesRepositoryLocation,
|
||||||
|
"get-dependencies-for-plugin", new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "pluginId", pluginId.ToString() }
|
||||||
|
});
|
||||||
|
|
||||||
|
HttpResponseMessage response = await _httpClient.GetAsync(url);
|
||||||
if(!response.IsSuccessStatusCode)
|
if(!response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
Application.Log("Failed to get dependencies for plugin from the repository", LogType.Warning);
|
Application.Log("Failed to get dependencies for plugin from the repository", LogType.Warning);
|
||||||
@@ -87,4 +112,18 @@ public class PluginRepository : IPluginRepository
|
|||||||
|
|
||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string CreateUrlWithQueryParams(string baseUrl, string endpoint, Dictionary<string, string> queryParams)
|
||||||
|
{
|
||||||
|
QueryBuilder queryBuilder = new QueryBuilder();
|
||||||
|
foreach (var(key,value) in queryParams)
|
||||||
|
{
|
||||||
|
queryBuilder.Add(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
string queryString = queryBuilder.ToQueryString().ToString();
|
||||||
|
string url = baseUrl + endpoint + queryString;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,9 @@ namespace DiscordBotCore.Online.Helpers;
|
|||||||
|
|
||||||
public class PluginRepositoryConfiguration : IPluginRepositoryConfiguration
|
public class PluginRepositoryConfiguration : IPluginRepositoryConfiguration
|
||||||
{
|
{
|
||||||
public static PluginRepositoryConfiguration Default => new ("http://localhost:5097/api/v1/", "plugins-repository/", "dependencies-repository/");
|
public static PluginRepositoryConfiguration Default => new ("http://localhost:8080/api/v1/",
|
||||||
|
"plugin/",
|
||||||
|
"dependency/");
|
||||||
|
|
||||||
public string BaseUrl { get; }
|
public string BaseUrl { get; }
|
||||||
public string PluginRepositoryLocation { get; }
|
public string PluginRepositoryLocation { get; }
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public sealed class PluginManager : IPluginManager
|
|||||||
|
|
||||||
if (!onlinePlugins.Any())
|
if (!onlinePlugins.Any())
|
||||||
{
|
{
|
||||||
Application.Log("Failed to get all plugins from the repository", LogType.Warning);
|
Application.Log("Could not get any plugins from the repository", LogType.Warning);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
using DiscordBotCore;
|
|
||||||
using DiscordBotCore.API.Endpoints.PluginManagement;
|
|
||||||
using DiscordBotCore.Online;
|
|
||||||
using DiscordBotCore.Plugin;
|
|
||||||
using Moq;
|
|
||||||
|
|
||||||
namespace SethCoreTests;
|
|
||||||
|
|
||||||
public class PluginInstallEndpointTests
|
|
||||||
{
|
|
||||||
private readonly Mock<IPluginManager> _mockPluginManager;
|
|
||||||
private readonly PluginInstallEndpoint _endpoint;
|
|
||||||
|
|
||||||
public PluginInstallEndpointTests()
|
|
||||||
{
|
|
||||||
_mockPluginManager = new Mock<IPluginManager>();
|
|
||||||
_endpoint = new PluginInstallEndpoint(_mockPluginManager.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task HandleRequest_SuccessfulPluginInstallation_ReturnsOk()
|
|
||||||
{
|
|
||||||
var pluginName = "TestPlugin";
|
|
||||||
var pluginInfo = new OnlinePlugin(1, pluginName, "Description", "1.0", "Author", "http://link", 1);
|
|
||||||
_mockPluginManager.Setup(pm => pm.GetPluginDataByName(pluginName)).ReturnsAsync(pluginInfo);
|
|
||||||
_mockPluginManager.Setup(pm => pm.InstallPluginNoProgress(pluginInfo)).Returns(Task.CompletedTask);
|
|
||||||
|
|
||||||
var jsonRequest = $"{{\"pluginName\":\"{pluginName}\"}}";
|
|
||||||
var response = await _endpoint.HandleRequest(jsonRequest);
|
|
||||||
|
|
||||||
Assert.True(response.Success);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task HandleRequest_PluginNotFound_ReturnsFail()
|
|
||||||
{
|
|
||||||
var pluginName = "NonExistentPlugin";
|
|
||||||
_mockPluginManager.Setup(pm => pm.GetPluginDataByName(pluginName)).ReturnsAsync((OnlinePlugin?)null);
|
|
||||||
|
|
||||||
var jsonRequest = $"{{\"pluginName\":\"{pluginName}\"}}";
|
|
||||||
var response = await _endpoint.HandleRequest(jsonRequest);
|
|
||||||
|
|
||||||
Assert.False(response.Success);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
using System.Net;
|
|
||||||
using DiscordBotCore.Interfaces.PluginManagement;
|
|
||||||
using DiscordBotCore.Online.Helpers;
|
|
||||||
using Moq;
|
|
||||||
using Moq.Protected;
|
|
||||||
|
|
||||||
namespace SethCoreTests;
|
|
||||||
|
|
||||||
public class PluginRepositoryTests
|
|
||||||
{
|
|
||||||
private readonly Mock<IPluginRepositoryConfiguration> _mockConfig;
|
|
||||||
private readonly Mock<HttpMessageHandler> _mockHttpMessageHandler;
|
|
||||||
private readonly PluginRepository _pluginRepository;
|
|
||||||
|
|
||||||
public PluginRepositoryTests()
|
|
||||||
{
|
|
||||||
_mockConfig = new Mock<IPluginRepositoryConfiguration>();
|
|
||||||
_mockConfig.SetupGet(c => c.BaseUrl).Returns("http://localhost/");
|
|
||||||
_mockConfig.SetupGet(c => c.PluginRepositoryLocation).Returns("api/plugins/");
|
|
||||||
_mockConfig.SetupGet(c => c.DependenciesRepositoryLocation).Returns("api/dependencies/");
|
|
||||||
|
|
||||||
_mockHttpMessageHandler = new Mock<HttpMessageHandler>();
|
|
||||||
var httpClient = new HttpClient(_mockHttpMessageHandler.Object)
|
|
||||||
{
|
|
||||||
BaseAddress = new System.Uri(_mockConfig.Object.BaseUrl)
|
|
||||||
};
|
|
||||||
|
|
||||||
_pluginRepository = new PluginRepository(_mockConfig.Object)
|
|
||||||
{
|
|
||||||
_httpClient = httpClient
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetAllPlugins_ReturnsListOfPlugins()
|
|
||||||
{
|
|
||||||
var pluginsJson = "[{\"PluginId\":1,\"PluginName\":\"TestPlugin\",\"PluginDescription\":\"Description\",\"LatestVersion\":\"1.0\",\"PluginAuthor\":\"Author\",\"PluginLink\":\"http://link\",\"OperatingSystem\":1}]";
|
|
||||||
_mockHttpMessageHandler.Protected()
|
|
||||||
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
|
|
||||||
.ReturnsAsync(new HttpResponseMessage
|
|
||||||
{
|
|
||||||
StatusCode = HttpStatusCode.OK,
|
|
||||||
Content = new StringContent(pluginsJson)
|
|
||||||
});
|
|
||||||
|
|
||||||
var result = await _pluginRepository.GetAllPlugins();
|
|
||||||
|
|
||||||
Assert.Single(result);
|
|
||||||
Assert.Equal("TestPlugin", result[0].PluginName);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetPluginById_ReturnsPlugin()
|
|
||||||
{
|
|
||||||
var pluginJson = "{\"PluginId\":1,\"PluginName\":\"TestPlugin\",\"PluginDescription\":\"Description\",\"LatestVersion\":\"1.0\",\"PluginAuthor\":\"Author\",\"PluginLink\":\"http://link\",\"OperatingSystem\":1}";
|
|
||||||
_mockHttpMessageHandler.Protected()
|
|
||||||
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
|
|
||||||
.ReturnsAsync(new HttpResponseMessage
|
|
||||||
{
|
|
||||||
StatusCode = HttpStatusCode.OK,
|
|
||||||
Content = new StringContent(pluginJson)
|
|
||||||
});
|
|
||||||
|
|
||||||
var result = await _pluginRepository.GetPluginById(1);
|
|
||||||
|
|
||||||
Assert.NotNull(result);
|
|
||||||
Assert.Equal("TestPlugin", result.PluginName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
<IsTestProject>true</IsTestProject>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
|
|
||||||
<PackageReference Include="Moq" Version="4.20.72" />
|
|
||||||
<PackageReference Include="xunit" Version="2.5.3"/>
|
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Using Include="Xunit"/>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\DiscordBotCore\DiscordBotCore.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -25,10 +25,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CppCompatibilityModule", "M
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBotWebUI", "DiscordBotWebUI\DiscordBotWebUI.csproj", "{8683B195-B729-48BB-805A-D44CA98A0BF6}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBotWebUI", "DiscordBotWebUI\DiscordBotWebUI.csproj", "{8683B195-B729-48BB-805A-D44CA98A0BF6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SethTests", "SethTests", "{9D2F471B-89EE-4F17-B1EA-869069A9A3B8}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SethCoreTests", "SethCoreTests\SethCoreTests.csproj", "{AB4BD8D1-7384-4669-9D75-3BBECFA0A96E}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -67,10 +63,6 @@ Global
|
|||||||
{8683B195-B729-48BB-805A-D44CA98A0BF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{8683B195-B729-48BB-805A-D44CA98A0BF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{8683B195-B729-48BB-805A-D44CA98A0BF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8683B195-B729-48BB-805A-D44CA98A0BF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8683B195-B729-48BB-805A-D44CA98A0BF6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8683B195-B729-48BB-805A-D44CA98A0BF6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{AB4BD8D1-7384-4669-9D75-3BBECFA0A96E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{AB4BD8D1-7384-4669-9D75-3BBECFA0A96E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{AB4BD8D1-7384-4669-9D75-3BBECFA0A96E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{AB4BD8D1-7384-4669-9D75-3BBECFA0A96E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -81,7 +73,6 @@ Global
|
|||||||
{FCE9743F-7EB4-4639-A080-FCDDFCC7D689} = {5CF9AD7B-6BF0-4035-835F-722F989C01E1}
|
{FCE9743F-7EB4-4639-A080-FCDDFCC7D689} = {5CF9AD7B-6BF0-4035-835F-722F989C01E1}
|
||||||
{F3C61A47-F758-4145-B496-E3ECCF979D89} = {5CF9AD7B-6BF0-4035-835F-722F989C01E1}
|
{F3C61A47-F758-4145-B496-E3ECCF979D89} = {5CF9AD7B-6BF0-4035-835F-722F989C01E1}
|
||||||
{C67908F9-4A55-4DD8-B993-C26C648226F1} = {EA4FA308-7B2C-458E-8485-8747D745DD59}
|
{C67908F9-4A55-4DD8-B993-C26C648226F1} = {EA4FA308-7B2C-458E-8485-8747D745DD59}
|
||||||
{AB4BD8D1-7384-4669-9D75-3BBECFA0A96E} = {9D2F471B-89EE-4F17-B1EA-869069A9A3B8}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF}
|
SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF}
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
services:
|
services:
|
||||||
discord-bot-client:
|
discord-bot-client:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ./DiscordBot
|
||||||
dockerfile: DiscordBot/Dockerfile
|
dockerfile: Dockerfile
|
||||||
tty: true
|
tty: true
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
|
|
||||||
discord-bot-webui:
|
discord-bot-webui:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ./DiscordBotWebUI
|
||||||
dockerfile: DiscordBotWebUI/Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
ports:
|
||||||
|
- '4444:8080'
|
||||||
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
Reference in New Issue
Block a user