Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
64f4b6f
Start Mission and Signup design
3Mydlo3 Sep 9, 2021
eaaf8c1
Add ReDoc documentation
3Mydlo3 Sep 9, 2021
b58a664
Fix version
3Mydlo3 Sep 9, 2021
dfd6204
Set ReDoc as default start page
3Mydlo3 Sep 9, 2021
9d88111
Fix ReDoc DocumentTitle
3Mydlo3 Sep 9, 2021
18395cc
Enable Nullable feature
3Mydlo3 Sep 9, 2021
5a209d9
Fix Discord LogSeverity mapping switch not having default
3Mydlo3 Sep 9, 2021
9d32450
Set Configuration in Startup to private
3Mydlo3 Sep 9, 2021
8db36d8
Rename test project to BotService.Tests
3Mydlo3 Sep 9, 2021
34dda11
Rename DAO project to Core
3Mydlo3 Sep 9, 2021
6316811
Add Boderator.Core.Tests project
3Mydlo3 Sep 9, 2021
a4862a6
Add InternalsVisibleTo attributes
3Mydlo3 Sep 9, 2021
e4b545f
Reference Core project by BotService
3Mydlo3 Sep 9, 2021
9d04bb8
Remove clutter from BotService csproj
3Mydlo3 Sep 9, 2021
4b76b1b
Add Core reference for Core.Tests
3Mydlo3 Sep 9, 2021
7a254b8
Reorder references in csprojs
3Mydlo3 Sep 9, 2021
e2feb2c
Change indent to 2 spaces in csprojs
3Mydlo3 Sep 9, 2021
b0fce08
Add .editorconfig
3Mydlo3 Sep 9, 2021
066ded8
Merge remote-tracking branch 'origin/Boderator3.0' into Boderator30/P…
3Mydlo3 Sep 10, 2021
b402e46
Add AutoFixture, Moq and FluentAssertions to test projects
3Mydlo3 Sep 10, 2021
aadcec5
Fixes after merge
3Mydlo3 Sep 10, 2021
c96658c
Add CSharpFunctionalExtensions
3Mydlo3 Sep 10, 2021
057884e
Start work on TestApiServer
3Mydlo3 Sep 11, 2021
4d27128
Remove DiscordService from startup
3Mydlo3 Sep 11, 2021
f6bdde8
Add Result extensions for easier assertions
3Mydlo3 Sep 11, 2021
18d0a39
Fix controllers mapping
3Mydlo3 Sep 11, 2021
92108ee
Replace Debug controller with Health controller
3Mydlo3 Sep 11, 2021
f6c5bc5
Add integration test for ping endpoint
3Mydlo3 Sep 11, 2021
a2b910d
Add documentation for HealthController
3Mydlo3 Sep 11, 2021
40b36b7
Change log settings
3Mydlo3 Sep 11, 2021
2bfc938
Extract Serilog initialization to separate method
3Mydlo3 Sep 11, 2021
ed21c1b
Add log levels config
3Mydlo3 Sep 11, 2021
ee3d4a8
Set indent to 2 for json files
3Mydlo3 Sep 11, 2021
0c6c980
Move DiscordService to DiscordClient feature
3Mydlo3 Sep 11, 2021
3a4c337
Add basic Configuration
3Mydlo3 Sep 11, 2021
0bde373
Add AutoAddInterfacesAsScoped()
3Mydlo3 Nov 13, 2021
86d0117
Merge branch 'Boderator30/PrepareInfrastructure' into Boderator30/Sig…
3Mydlo3 Nov 13, 2021
9766f98
Enable nullable in all projects
3Mydlo3 Nov 13, 2021
a668ce9
Merge branch 'Boderator30/PrepareInfrastructure' into Boderator30/Sig…
3Mydlo3 Nov 13, 2021
69ea576
Move models to Core project
3Mydlo3 Nov 13, 2021
d2e98c3
Add basic Mission logic
3Mydlo3 Nov 13, 2021
807f33d
Add test for GetMission
3Mydlo3 Nov 13, 2021
1201088
Start basic validation in models
3Mydlo3 Nov 19, 2021
b59647a
Some SignupsQuery work
3Mydlo3 Mar 21, 2022
0ef0d0d
Update to .NET 6
3Mydlo3 Mar 21, 2022
62ebc0f
Merge branch 'Boderator30/PrepareInfrastructure' into Boderator30/Sig…
3Mydlo3 Mar 21, 2022
b4e6068
Add GetSignup by id
3Mydlo3 Mar 21, 2022
0f9f5e9
Update packages
3Mydlo3 Mar 21, 2022
d201673
Merge branch 'Boderator30/PrepareInfrastructure' into Boderator30/Sig…
3Mydlo3 Mar 21, 2022
26c9d81
Update structure & add endpoint names
3Mydlo3 Mar 21, 2022
e359f13
Fix mission model to be readonly
3Mydlo3 Mar 21, 2022
dc20582
Use Result & mapping in Signups
3Mydlo3 Mar 21, 2022
f2ca1e2
Add basic unit & integration tests for missions query
3Mydlo3 Mar 21, 2022
a0653f3
Split MissionRepository
3Mydlo3 Mar 21, 2022
40e7741
Merge remote-tracking branch 'origin/Boderator3.0' into Boderator30/S…
3Mydlo3 Mar 21, 2022
d2908ba
Fixes for ConnectionString configuration
3Mydlo3 Mar 21, 2022
991305b
Add ConnectionString to factory
3Mydlo3 Mar 21, 2022
9c00a76
Fix last test + add AF_Boderator_ConnectionString to launchSettings.json
3Mydlo3 Mar 21, 2022
fe3dd2a
More signups design
3Mydlo3 Mar 26, 2022
2483b41
Merge Signups into Missions feature
3Mydlo3 Apr 1, 2022
639a768
Change to file-scoped namespace
3Mydlo3 Apr 1, 2022
a8872f0
Add GetSignups(id) tests
3Mydlo3 Apr 1, 2022
6ccbaba
Add API CreateMission tests
3Mydlo3 Apr 1, 2022
0b56b07
Revert accidental launchSettings.json change
3Mydlo3 Apr 1, 2022
37ebbe8
Store SignupsStatus as short in db
3Mydlo3 Apr 1, 2022
767b2bc
Fix SignupsMapper
3Mydlo3 Apr 1, 2022
c5316d4
Fix Signups spelling
3Mydlo3 Apr 1, 2022
63f97b7
Fix bug in AutoAddInterfacesAsScoped()
3Mydlo3 Apr 1, 2022
09b9e40
Handle NotImplementedException as 501 status code
3Mydlo3 Apr 1, 2022
6b3e2e1
Add response status codes to endpoints
3Mydlo3 Apr 1, 2022
7f289e0
Fix Team.SignupsId incorrect type int -> long
3Mydlo3 Apr 1, 2022
faacc27
Add more to documentation generation
3Mydlo3 Apr 1, 2022
aafeda9
Add more documentation
3Mydlo3 Apr 2, 2022
2f19ff0
Fix remaining Signup misspelling
3Mydlo3 Apr 2, 2022
d9b2377
Fill missing documentation + enhancements
3Mydlo3 Apr 2, 2022
8f5d9bb
Create EntityTypeConfigurations
3Mydlo3 May 3, 2022
ae13436
Start work on MissionSpecification
3Mydlo3 Jul 2, 2022
593d37a
Introduce IBulidingSpecification<T>
3Mydlo3 Jul 3, 2022
ce1a6e9
Add Team and Slot specification
3Mydlo3 Jul 3, 2022
8b1f347
Exclude specification interfaces from autoregistration
3Mydlo3 Dec 27, 2022
440b056
Add SignupsCommandService.CreateSignups + start tests
3Mydlo3 Dec 27, 2022
209a368
Fix CreateMission throwing already tracking exception
3Mydlo3 Dec 31, 2022
8ae0163
Implement CreateSignups endpoint
3Mydlo3 Jan 1, 2023
a153755
Change Test projects to library
3Mydlo3 Jan 1, 2023
0a7810c
Add some more tests
3Mydlo3 Mar 24, 2023
c191b58
Add basic test for GetMissions
3Mydlo3 Mar 24, 2023
d18a494
WIP not working, TODO: test with other DB than SQLite
3Mydlo3 Mar 24, 2023
4afddd4
Test SQL Server
3Mydlo3 Mar 30, 2023
b6da0ba
Make all* tests pass on SQL Server and SQLite
3Mydlo3 Mar 31, 2023
5b482bb
Add legacy import test
3Mydlo3 Mar 31, 2023
5f3636d
Working production transactions + Core.Tests too
3Mydlo3 Mar 31, 2023
38c9fa9
Attempt at query specifications
3Mydlo3 Mar 31, 2023
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
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.vs/*
.idea/*
Logs/*
*/obj/*
*/bin/*
*/Logs/*
*.user
*.dat
*.mp3
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<OutputType>Library</OutputType>
</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.AspNetCore.Mvc.Testing" Version="6.0.3" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="6.0.3" />
<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,97 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ArmaForces.Boderator.BotService.Features.Missions.DTOs;
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.Missions
{
[Trait("Category", "Integration")]
public class MissionsControllerTests : ApiTestBase
{
public MissionsControllerTests(TestApiServiceFixture testApi)
: base(testApi) { }

[Theory, ClassData(typeof(CreateMissionInvalidRequestTestData)), Trait("Category", "Integration")]
public async Task CreateMission_InvalidRequest_ReturnsBadRequest(MissionCreateRequestDto missionCreateRequestDto)
{
var result = await HttpPostAsync<MissionCreateRequestDto, MissionDto>("api/missions", missionCreateRequestDto);

result.ShouldBeFailure();
}

[Theory, ClassData(typeof(CreateMissionValidRequestTestData)), Trait("Category", "Integration")]
public async Task CreateMission_ValidRequest_MissionCreated(MissionCreateRequestDto missionCreateRequestDto)
{
var result = await HttpPostAsync<MissionCreateRequestDto, MissionDto>("api/missions", missionCreateRequestDto);

result.ShouldBeSuccess(missionCreateRequestDto);
}

private class CreateMissionValidRequestTestData : TheoryData<MissionCreateRequestDto>
{
private readonly MissionCreateRequestDto _minimalRequest = new()
{
Title = "Test mission title",
Owner = "Test mission owner"
};

public CreateMissionValidRequestTestData()
{
var testCases = new List<MissionCreateRequestDto>
{
_minimalRequest,
_minimalRequest with
{
Description = "Test mission description"
},
_minimalRequest with
{
MissionDate = DateTime.Now.AddHours(-1)
},
_minimalRequest with
{
ModsetName = "Test-mission-modset"
},
_minimalRequest with
{
Description = "Test mission description",
MissionDate = DateTime.Now.AddHours(-1),
ModsetName = "Test-mission-modset"
}
};

foreach (var testCase in testCases) Add(testCase);
}
}

private class CreateMissionInvalidRequestTestData : TheoryData<MissionCreateRequestDto>
{
public CreateMissionInvalidRequestTestData()
{
var testCases = new List<MissionCreateRequestDto>
{
new()
{
Title = "Test mission title without owner"
},
new()
{
Owner = "Test mission owner without title"
},
new()
{
Title = "Test mission title",
Owner = "Test mission owner",
ModsetName = "Modset name with whitespace characters"
}
};

foreach (var testCase in testCases) Add(testCase);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ArmaForces.Boderator.BotService.Features.Missions.DTOs;
using ArmaForces.Boderator.BotService.Tests.TestUtilities.TestBases;
using ArmaForces.Boderator.BotService.Tests.TestUtilities.TestFixtures;
using ArmaForces.Boderator.Core.Tests.TestUtilities;
using AutoFixture;
using CSharpFunctionalExtensions;
using FluentAssertions;
using Xunit;

namespace ArmaForces.Boderator.BotService.Tests.Features.Missions;

[Trait("Category", "Integration")]
public class GetMissionsControllerTests : ApiTestBase
{
public GetMissionsControllerTests(TestApiServiceFixture testApi)
: base(testApi) { }

[Fact]
public async Task GetMission_MissionExists_ReturnsExistingMission()
{
var missionCreateRequest = new MissionCreateRequestDto
{
Title = Fixture.Create<string>(),
Owner = Fixture.Create<string>(),
Description = Fixture.Create<string>()
};

var missionCreateResult = await HttpPostAsync<MissionCreateRequestDto, MissionDto>("api/missions", missionCreateRequest);

var expectedMission = new MissionDto
{
Title = missionCreateResult.Value.Title,
Description = missionCreateRequest.Description,
Owner = missionCreateRequest.Owner,
MissionDate = missionCreateResult.Value.MissionDate,
MissionId = missionCreateResult.Value.MissionId
};

var result = await HttpGetAsync<MissionDto>($"api/missions/{expectedMission.MissionId}");

result.ShouldBeSuccess(expectedMission);
}

[Fact]
public async Task GetMissions_SomeMissionsExist_ReturnsAllMissions()
{
var createdMissions = await CreateSomeMissions(count: 5);
var creationResult = createdMissions.Combine();
creationResult.ShouldBeSuccess();

var expectedMissions = creationResult.Value
.Select(x => new MissionDto
{
Title = x.createdMission.Title,
Description = x.createdMission.Description,
Owner = x.createdMission.Owner,
MissionDate = x.createdMission.MissionDate,
MissionId = x.createdMission.MissionId
})
.ToList();

var result = await HttpGetAsync<List<MissionDto>>($"api/missions");

result.ShouldBeSuccess(x => x.Should().Contain(expectedMissions));
}

private async Task<List<Result<(MissionDto createdMission, MissionCreateRequestDto createRequest)>>> CreateSomeMissions(int count = 1)
{
return await AsyncEnumerable.Range(0, count)
.Select(x => new MissionCreateRequestDto
{
Title = Fixture.Create<string>(),
Owner = Fixture.Create<string>(),
Description = Fixture.Create<string>()
})
.SelectAwait(async createRequest => {
var createResult = await HttpPostAsync<MissionCreateRequestDto, MissionDto>("api/missions", createRequest);
return (createResult, createRequest);
})
.Select(x => x.createResult.IsSuccess
? Result.Success((x.createResult.Value, x.createRequest))
: x.createResult.ConvertFailure<(MissionDto, MissionCreateRequestDto)>())
.ToListAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using ArmaForces.Boderator.BotService.Features.Missions.DTOs;
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.Missions
{
public class SignupsControllerTests : ApiTestBase
{
public SignupsControllerTests(TestApiServiceFixture testApi)
: base(testApi) { }

[Theory, ClassData(typeof(CreateSignupsInvalidRequestTestData)), Trait("Category", "Integration")]
public async Task CreateSignups_InvalidRequest_ReturnsBadRequest(
SignupsCreateRequestDto signupsCreateRequestDto)
{
var result =
await HttpPostAsync<SignupsCreateRequestDto, SignupsDto>("api/signups", signupsCreateRequestDto);

result.ShouldBeFailure();
}

private class CreateSignupsInvalidRequestTestData : TheoryData<SignupsCreateRequestDto>
{
public CreateSignupsInvalidRequestTestData()
{
var testCases = new List<SignupsCreateRequestDto>
{
new()
{
Teams = new List<TeamDto>()
},
new()
{
Mission = new MissionCreateRequestDto(),
Teams = new List<TeamDto>()
},
new()
{
MissionId = 0,
Teams = new List<TeamDto>()
},
new()
{
MissionId = 0,
Mission = new MissionCreateRequestDto(),
Teams = new List<TeamDto>()
}
};

foreach (var testCase in testCases) Add(testCase);
}
}
}
}
Loading