Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boderator 3.0 rewrite #47

Draft
wants to merge 34 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
21c9047
Remove useless web project and move mission class to main project
3Mydlo3 Dec 25, 2020
8e0ad9d
Reformat Signups.cs and split Mission, Slot and Team to files
3Mydlo3 Dec 25, 2020
a6fc042
Create SlotFactory and EmoteProvider, use IEmote in Slot
3Mydlo3 Dec 25, 2020
1b5cdc3
Merge branch 'master' into signups-fixes
3Mydlo3 Feb 9, 2021
42cdb56
Merge remote-tracking branch 'origin/master' into signups-fixes
3Mydlo3 Feb 28, 2021
8a78586
Fix compile time errors
3Mydlo3 Feb 28, 2021
9030358
Fix incorrect stuff
3Mydlo3 Mar 7, 2021
10a08e5
Add SlotFactory and EmoteProvider to DI
3Mydlo3 Mar 7, 2021
85b0dc9
Fix dialogs crashing
3Mydlo3 Mar 7, 2021
a624837
Fix mission date not always read
3Mydlo3 Mar 7, 2021
30b5441
Start SignupHandler refactor
3Mydlo3 Mar 8, 2021
9175063
BanHandler cleanup
3Mydlo3 Mar 8, 2021
5c15c7f
Some Signups cleanup
3Mydlo3 Mar 8, 2021
2264b72
Extract most of signups logic to separate classes
3Mydlo3 Apr 4, 2021
3aed658
Startup fixes
3Mydlo3 Apr 12, 2021
1700604
Chop SigunpsLogic parameters
3Mydlo3 Apr 24, 2021
e241165
Start design of SignupsCreateRequest
3Mydlo3 Apr 24, 2021
cac4708
Init commit
Ingvarr100th Apr 29, 2021
c64dcfd
Basic configurations
Ingvarr100th Apr 30, 2021
64744a9
DiscordService, Configuration manager
Ingvarr100th May 2, 2021
136a003
Removal of unnecessary defaults
Ingvarr100th May 2, 2021
a38ca31
Move discord client log event init into DiscordService constructor
Ingvarr100th May 2, 2021
9ea60e9
Addition of appsettings
Ingvarr100th May 2, 2021
fb3987d
Review fixes
Ingvarr100th May 3, 2021
830406d
Interface fix
Ingvarr100th May 3, 2021
1e67c05
Removal of unuser var
Ingvarr100th May 3, 2021
6a534a4
Add newline
Ingvarr100th May 5, 2021
434b7c7
Merge pull request #49 from ArmaForces/Boderator3.0_DiscordService
Ingvarr100th May 5, 2021
2024fef
Remove old projects
3Mydlo3 Sep 9, 2021
1a2422c
Move projects to repo root
3Mydlo3 Sep 9, 2021
fe6d251
Remove MediatR (#57)
3Mydlo3 Sep 10, 2021
568eb5c
Add ReDoc documentation (#59)
3Mydlo3 Sep 10, 2021
5970dc7
Prepare infrastructure for projects (#60)
3Mydlo3 Mar 21, 2022
0774e3c
WIP Attendance extractor + plots generation
3Mydlo3 Nov 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 19 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
root = true

[*]
end_of_line = crlf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.csproj]
indent_size = 2

[*.json]
indent_size
= 2
6 changes: 1 addition & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
.vs/*
.idea/*
Logs/*
*/obj/*
*/bin/*
*.user
*.dat
*.mp3
*.ttf
*.json
*.env
*.dll
Boderator/*
BoderatorTest/*
BoderatorWeb/*
BoderatorWebTest/*
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\ArmaForces.Boderator.BotService\ArmaForces.Boderator.BotService.csproj" />
<ProjectReference Include="..\ArmaForces.Boderator.Core.Tests\ArmaForces.Boderator.Core.Tests.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.17.0" />
<PackageReference Include="CSharpFunctionalExtensions" Version="2.28.3" />
<PackageReference Include="FluentAssertions" Version="6.5.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="Moq" Version="4.17.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Threading.Tasks;
using ArmaForces.Boderator.BotService.Tests.TestUtilities.TestBases;
using ArmaForces.Boderator.BotService.Tests.TestUtilities.TestFixtures;
using ArmaForces.Boderator.Core.Tests.TestUtilities;
using Xunit;

namespace ArmaForces.Boderator.BotService.Tests.Features.Health
{
[Trait("Category", "Integration")]
public class HealthControllerTests : ApiTestBase
{
public HealthControllerTests(TestApiServiceFixture testApi)
: base(testApi) { }

[Fact]
public async Task Ping_AllOk_ReturnsPong()
{
var result = await HttpGetAsync("api/health/ping");

result.ShouldBeSuccess("pong");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ArmaForces.Boderator.BotService.Tests.TestUtilities.Collections
{
internal static class CollectionsNames
{
public const string ApiTest = "TestAPI";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using ArmaForces.Boderator.BotService.Tests.TestUtilities.TestFixtures;
using Xunit;

namespace ArmaForces.Boderator.BotService.Tests.TestUtilities.Collections.Definitions
{
[CollectionDefinition(CollectionsNames.ApiTest)]
public class TestApiCollection : ICollectionFixture<TestApiServiceFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using ArmaForces.Boderator.BotService.Tests.TestUtilities.Collections;
using ArmaForces.Boderator.BotService.Tests.TestUtilities.TestFixtures;
using CSharpFunctionalExtensions;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Xunit;

namespace ArmaForces.Boderator.BotService.Tests.TestUtilities.TestBases
{
/// <summary>
/// Base class for integration tests involving API.
/// Provider test server and methods to invoke endpoints.
/// </summary>
[Collection(CollectionsNames.ApiTest)]
public abstract class ApiTestBase
{
private readonly HttpClient _httpClient;

protected IServiceProvider Provider { get; }

protected ApiTestBase(TestApiServiceFixture testApi)
{
_httpClient = testApi.HttpClient;

Provider = new ServiceCollection()
.BuildServiceProvider();
}

protected async Task<Result<T>> HttpGetAsync<T>(string path)
{
return await HttpGetAsync(path)
.Bind(DeserializeContent<T>);
}

protected async Task<Result<string>> HttpGetAsync(string path)
{
var httpResponseMessage = await _httpClient.GetAsync(path);
if (httpResponseMessage.IsSuccessStatusCode)
{
return await httpResponseMessage.Content.ReadAsStringAsync();
}

var responseBody = await httpResponseMessage.Content.ReadAsStringAsync();
var error = string.IsNullOrWhiteSpace(responseBody)
? httpResponseMessage.ReasonPhrase
: responseBody;

return Result.Failure<string>(error);
}

protected async Task<Result> HttpPostAsync<T>(string path, T body)
{
var httpResponseMessage = await _httpClient.PostAsync(path, new StringContent(JsonConvert.SerializeObject(body)));
if (httpResponseMessage.IsSuccessStatusCode)
{
return Result.Success();
}

var responseBody = await httpResponseMessage.Content.ReadAsStringAsync();
var error = string.IsNullOrWhiteSpace(responseBody)
? httpResponseMessage.ReasonPhrase
: responseBody;

return Result.Failure<T>(error);
}

private static Result<T> DeserializeContent<T>(string content)
=> JsonConvert.DeserializeObject<T>(content);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace ArmaForces.Boderator.BotService.Tests.TestUtilities.TestFixtures
{
public class TestApiServiceFixture : IDisposable
{
private const int Port = 43421;
private readonly SocketsHttpHandler _socketsHttpHandler;
private readonly IHost _host;

public HttpClient HttpClient { get; }

public TestApiServiceFixture()
{
_socketsHttpHandler = new SocketsHttpHandler();
HttpClient = new HttpClient(_socketsHttpHandler)
{
BaseAddress = new Uri($"http://localhost:{Port}")
};

_host = Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(ConfigureWebBuilder())
.Build();

_host.Start();
}

public void Dispose()
{
HttpClient.Dispose();
_socketsHttpHandler.Dispose();
_host.Dispose();
GC.SuppressFinalize(this);
}

private static Action<IWebHostBuilder> ConfigureWebBuilder() => webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseKestrel(x => x.ListenLocalhost(Port));
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<UserSecretsId>a9e33227-0f21-4863-9830-8aa69ac1e928</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\ArmaForces.Boderator.Core\ArmaForces.Boderator.Core.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="CSharpFunctionalExtensions" Version="2.28.3" />
<PackageReference Include="Discord.Net" Version="3.4.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="5.0.0" />
<PackageReference Include="Serilog.Enrichers.Thread" Version="3.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.0" />
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.3.0" />
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ArmaForces.Boderator.BotService.Configuration
{
internal record BoderatorConfiguration
{
public string DiscordToken { get; init; } = string.Empty;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections;
using System.Configuration;

namespace ArmaForces.Boderator.BotService.Configuration
{
internal class BoderatorConfigurationFactory
{
private readonly IDictionary _environmentVariables;

public BoderatorConfigurationFactory()
{
_environmentVariables = Environment.GetEnvironmentVariables();
}

// TODO: Consider making this a bit more automatic so configuration is easily extensible
public BoderatorConfiguration CreateConfiguration() => new BoderatorConfiguration
{
DiscordToken = GetStringValue(nameof(BoderatorConfiguration.DiscordToken))
};

private string GetStringValue(string variableName)
{
var fullVariableName = $"AF_Boderator_{variableName}";
var value = _environmentVariables[fullVariableName];

return value is not null
? (string) value
: throw new ConfigurationErrorsException($"Variable {fullVariableName} does not exist.");
}
}
}
22 changes: 22 additions & 0 deletions ArmaForces.Boderator.BotService/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["ArmaForces.Boderator.WebService/ArmaForces.Boderator.WebService.csproj", "ArmaForces.Boderator.WebService/"]
RUN dotnet restore "ArmaForces.Boderator.WebService/ArmaForces.Boderator.WebService.csproj"
COPY . .
WORKDIR "/src/ArmaForces.Boderator.WebService"
RUN dotnet build "ArmaForces.Boderator.WebService.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "ArmaForces.Boderator.WebService.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ArmaForces.Boderator.WebService.dll"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

namespace ArmaForces.Boderator.BotService.Documentation
{
internal static class DocumentationExtensions
{
private const string DefaultSwaggerJsonUrl = "/swagger/v3/swagger.json";

public static IServiceCollection AddDocumentation(this IServiceCollection services, OpenApiInfo openApiConfig)
{
return services.AddSwaggerGen(
options =>
{
options.SwaggerDoc(openApiConfig.Version, openApiConfig);
});
}

public static IApplicationBuilder AddDocumentation(
this IApplicationBuilder app,
OpenApiInfo openApiConfig,
string url = DefaultSwaggerJsonUrl)
{
return app.UseSwagger()
.UseSwaggerUI(
options => options.SwaggerEndpoint(
url,
openApiConfig.Title))
.UseReDoc(
options =>
{
options.DocumentTitle = openApiConfig.Title;
options.SpecUrl = url;
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Discord;

namespace ArmaForces.Boderator.BotService.Features.DiscordClient.DTOs
{
public class DiscordServiceStatusDto
{
public ConnectionState ConnectionState { get; init; }
public LoginState LoginState { get; init; }
public UserStatus ClientState { get; init; }
}
}
Loading
Loading