Skip to content

Commit

Permalink
NOX-1053 Endpoint called with incorrect parameters (#1553)
Browse files Browse the repository at this point in the history
* Refactored api routing middleware to be thread-safe

* Lock agent os to ubuntu-22.04

* Downgraded xunit to 2.8.1 as with 2.9.2 test execution gets stuck

* Updated some tests to not depend on OS culture

* Specify ms sql container image
  • Loading branch information
emir-sehovic1 authored Dec 20, 2024
1 parent 61c0e9b commit 7c6945a
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 91 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

jobs:
build:
runs-on: ubuntu-latest
runs-on: "ubuntu-latest"
strategy:
matrix:
dotnet-version: ['8.0.x']
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ on:

jobs:
build:
runs-on: ubuntu-latest
runs-on: "ubuntu-latest"
strategy:
matrix:
dotnet-version: ['8.x']
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/schema_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
jobs:
schemas-deploy:
name: Deploy
runs-on: ubuntu-latest
runs-on: "ubuntu-latest"
steps:
- name: Get latest code
uses: actions/checkout@v3
Expand Down
7 changes: 3 additions & 4 deletions src/Nox.Lib/Middlewares/ApiRoutingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ public async Task InvokeAsync(HttpContext context)
return;
}

var apiRouteMatcher = matchers.FirstOrDefault(m => m.Match(context.Request));
IDictionary<string, string>? paramValues = null;
var apiRouteMatcher = matchers.Find(m => m.Match(context.Request, out paramValues));

if (apiRouteMatcher == null)
{
await _next(context);
return;
}

var translatedTarget = apiRouteMatcher.TransformTo(apiRouteMatcher.ApiRoute.TargetUrl);

var translatedTarget = apiRouteMatcher.TransformTo(apiRouteMatcher.ApiRoute.TargetUrl, paramValues);

if (translatedTarget.Contains($"&{{$RouteQuery}}"))
{
Expand All @@ -87,5 +87,4 @@ public async Task InvokeAsync(HttpContext context)
await _next(context);
return;
}

}
14 changes: 7 additions & 7 deletions src/Nox.Lib/Middlewares/RouteMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ internal class RouteMatcher

private readonly ApiRouteMapping _apiRoute;

private IDictionary<string, string>? _values;

private const int _slash = 47;

public RouteMatcher(ApiRouteMapping apiRoute, string prefix)
Expand All @@ -33,19 +31,21 @@ public RouteMatcher(ApiRouteMapping apiRoute, string prefix)

internal ApiRouteMapping ApiRoute => _apiRoute;

public bool Match(HttpRequest httpRequest)
public bool Match(HttpRequest httpRequest, out IDictionary<string, string>? paramValues)
{
paramValues = null;
var isMatch = _matcher.Match($"{httpRequest.Path}{httpRequest.QueryString}", out var values);

_values = values;
if(isMatch)
paramValues = values;

return isMatch;
}

public string TransformTo(string toPath)
public string TransformTo(string toPath, IDictionary<string, string>? paramValues)
{
if (_values is null) return toPath;
if (paramValues is null) return toPath;

return _matcher.TransformTo(toPath, _values);
return _matcher.TransformTo(toPath, paramValues);
}
}
2 changes: 1 addition & 1 deletion tests/Nox.ClientApi.Tests/Nox.ClientApi.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="Testcontainers.MsSql" Version="3.10.0" />
<PackageReference Include="Testcontainers.PostgreSql" Version="3.10.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public async Task InitializeAsync()

case DatabaseServerProvider.SqlServer:
var sqlContainer = new MsSqlBuilder()
.WithImage("mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04")
.WithAutoRemove(true)
.WithCleanUp(true)
.Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class NoxTestMsSqlContainerFixture : NoxTestContainerFixtureBase<MsSqlCon
public NoxTestMsSqlContainerFixture()
{
_container = new MsSqlBuilder()
.WithImage("mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04")
.WithAutoRemove(true)
.WithCleanUp(true)
.Build();
Expand Down
11 changes: 7 additions & 4 deletions tests/Nox.Types.Tests/Types/DateTime/DateTimeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,17 @@ void Test()
}

[Theory]
[InlineData("en-GB", "20/06/2023 10:05:00 +01:00")]
[InlineData("en-US", "6/20/2023 10:05:00 AM +01:00")]
public void ToString_WithCultureParameter_ReturnsFormattedString(string culture, string expectedResult)
[InlineData("en-GB")]
[InlineData("en-US")]
public void ToString_WithCultureParameter_ReturnsFormattedString(string culture)
{
var dateTime = DateTime.From(new DateTimeOffset(2023, 6, 20, 10, 5, 0, 0, new TimeSpan(1,0,0)));

var nativeFormattingOutput = new DateTimeOffset(2023, 6, 20, 10, 5, 0, 0, new TimeSpan(1, 0, 0)).ToString(new CultureInfo(culture));

var dateTimeString = dateTime.ToString(new CultureInfo(culture));

Assert.Equal(expectedResult, dateTimeString);
Assert.Equal(nativeFormattingOutput, dateTimeString);
}

[Fact]
Expand Down
12 changes: 8 additions & 4 deletions tests/Nox.Types.Tests/Types/DateTimeRange/DateTimeRangeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,19 +346,23 @@ void Test()
}

[Theory]
[InlineData("en-GB", "20/06/2023 10:05:00 +08:00 - 20/08/2023 10:05:00 +00:00")]
[InlineData("en-US", "6/20/2023 10:05:00 AM +08:00 - 8/20/2023 10:05:00 AM +00:00")]
public void ToString_WithCultureParameter_ReturnsFormattedString(string culture, string expectedResult)
[InlineData("en-GB")]
[InlineData("en-US")]
public void ToString_WithCultureParameter_ReturnsFormattedString(string culture)
{
void Test()
{
var start = new DateTimeOffset(2023, 6, 20, 10, 5, 0, TimeSpan.FromHours(8));
var end = new DateTimeOffset(2023, 8, 20, 10, 5, 0, TimeSpan.Zero);

var startNativeFormattingOutput = new DateTimeOffset(2023, 6, 20, 10, 5, 0, 0, new System.TimeSpan(8, 0, 0)).ToString(new CultureInfo(culture));
var endNativeFormattingOutput = new DateTimeOffset(2023, 8, 20, 10, 5, 0, System.TimeSpan.Zero).ToString(new CultureInfo(culture));
var nativeFormattingOutput = $"{startNativeFormattingOutput} - {endNativeFormattingOutput}";

var dateTimeRange = DateTimeRange.From(start, end);
var dateTimeRangeString = dateTimeRange.ToString(new CultureInfo(culture));

dateTimeRangeString.Should().Be(expectedResult);
dateTimeRangeString.Should().Be(nativeFormattingOutput);
}

TestUtility.RunInInvariantCulture(Test);
Expand Down
144 changes: 76 additions & 68 deletions tests/Nox.Types.Tests/Types/Time/TimeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,19 +235,21 @@ void Test()
}

[Theory]
[InlineData("en-GB", "03:05:52")]
[InlineData("en-US", "3:05:52 AM")]
public void ToString_WithTickConstructor_ReturnsDefaultFormattedStringInProvidedCulture(string culture, string expectedResult)
[InlineData("en-GB")]
[InlineData("en-US")]
public void ToString_WithTickConstructor_ReturnsDefaultFormattedStringInProvidedCulture(string culture)
{
void Test()
{
long ticks = 111525000000;

var time = Time.From(ticks);

var nativeFormattingOutput = new System.TimeOnly(ticks).ToString("T", new CultureInfo(culture));

var timeString = time.ToString(new CultureInfo(culture));

timeString.Should().BeEquivalentTo(expectedResult);
timeString.Should().BeEquivalentTo(nativeFormattingOutput);
}

TestUtility.RunInInvariantCulture(Test);
Expand Down Expand Up @@ -300,45 +302,47 @@ void Test()
}

[Theory]
[InlineData("en-US", "h:mm", "3:05")]
[InlineData("en-US", "hh:mm", "03:05")]
[InlineData("en-US", "HH:mm", "03:05")]
[InlineData("en-US", "h:mm tt", "3:05 AM")]
[InlineData("en-US", "hh:mm tt", "03:05 AM")]
[InlineData("en-US", "HH:mm tt", "03:05 AM")]
[InlineData("en-US", "HH:mm:ss", "03:05:52")]
[InlineData("en-US", "hh:mm:ss", "03:05:52")]
[InlineData("en-US", "hh:mm:ss fff", "03:05:52 500")]
[InlineData("en-US", "HH:mm:ss fff", "03:05:52 500")]
[InlineData("en-US", "hh:mm:ss fff tt", "03:05:52 500 AM")]
[InlineData("en-US", "HH:mm:ss fff tt", "03:05:52 500 AM")]
[InlineData("en-US", "t", "3:05 AM")]
[InlineData("en-US", "T", "3:05:52 AM")]
[InlineData("en-GB", "h:mm", "3:05")]
[InlineData("en-GB", "hh:mm", "03:05")]
[InlineData("en-GB", "HH:mm", "03:05")]
[InlineData("en-GB", "h:mm tt", "3:05 AM")]
[InlineData("en-GB", "hh:mm tt", "03:05 AM")]
[InlineData("en-GB", "HH:mm tt", "03:05 AM")]
[InlineData("en-GB", "HH:mm:ss", "03:05:52")]
[InlineData("en-GB", "hh:mm:ss", "03:05:52")]
[InlineData("en-GB", "hh:mm:ss fff", "03:05:52 500")]
[InlineData("en-GB", "HH:mm:ss fff", "03:05:52 500")]
[InlineData("en-GB", "hh:mm:ss fff tt", "03:05:52 500 AM")]
[InlineData("en-GB", "HH:mm:ss fff tt", "03:05:52 500 AM")]
[InlineData("en-GB", "t", "03:05")]
[InlineData("en-GB", "T", "03:05:52")]
public void ToString_WithTickConstructor_ReturnsFormattedStringInProvidedCulture(string culture, string format, string expectedResult)
[InlineData("en-US", "h:mm")]
[InlineData("en-US", "hh:mm")]
[InlineData("en-US", "HH:mm")]
[InlineData("en-US", "h:mm tt")]
[InlineData("en-US", "hh:mm tt")]
[InlineData("en-US", "HH:mm tt")]
[InlineData("en-US", "HH:mm:ss")]
[InlineData("en-US", "hh:mm:ss")]
[InlineData("en-US", "hh:mm:ss fff")]
[InlineData("en-US", "HH:mm:ss fff")]
[InlineData("en-US", "hh:mm:ss fff tt")]
[InlineData("en-US", "HH:mm:ss fff tt")]
[InlineData("en-US", "t")]
[InlineData("en-US", "T")]
[InlineData("en-GB", "h:mm")]
[InlineData("en-GB", "hh:mm")]
[InlineData("en-GB", "HH:mm")]
[InlineData("en-GB", "h:mm tt")]
[InlineData("en-GB", "hh:mm tt")]
[InlineData("en-GB", "HH:mm tt")]
[InlineData("en-GB", "HH:mm:ss")]
[InlineData("en-GB", "hh:mm:ss")]
[InlineData("en-GB", "hh:mm:ss fff")]
[InlineData("en-GB", "HH:mm:ss fff")]
[InlineData("en-GB", "hh:mm:ss fff tt")]
[InlineData("en-GB", "HH:mm:ss fff tt")]
[InlineData("en-GB", "t")]
[InlineData("en-GB", "T")]
public void ToString_WithTickConstructor_ReturnsFormattedStringInProvidedCulture(string culture, string format)
{
void Test()
{
long ticks = 111525000000;

var time = Time.From(ticks);

var nativeFormattingOutput = new System.TimeOnly(ticks).ToString(format, new CultureInfo(culture));

var timeString = time.ToString(format, new CultureInfo(culture));

timeString.Should().BeEquivalentTo(expectedResult);
timeString.Should().BeEquivalentTo(nativeFormattingOutput);
}

TestUtility.RunInCulture(Test, culture);
Expand Down Expand Up @@ -368,9 +372,9 @@ void Test()
}

[Theory]
[InlineData("en-GB", "13:05:52")]
[InlineData("en-US", "1:05:52 PM")]
public void ToString_WithNoFormatParameter_ReturnsDefaultFormattedStringInProvidedCulture(string culture, string expectedResult)
[InlineData("en-GB")]
[InlineData("en-US")]
public void ToString_WithNoFormatParameter_ReturnsDefaultFormattedStringInProvidedCulture(string culture)
{
void Test()
{
Expand All @@ -380,9 +384,11 @@ void Test()
int millisecond = 500;
var time = Time.From(hour, minute, second, millisecond);

var nativeFormattingOutput = new System.TimeOnly(hour, minute, second, millisecond).ToString("T", new CultureInfo(culture));

var timeString = time.ToString(new CultureInfo(culture));

timeString.Should().BeEquivalentTo(expectedResult);
timeString.Should().BeEquivalentTo(nativeFormattingOutput);
}

TestUtility.RunInCulture(Test, culture);
Expand Down Expand Up @@ -436,35 +442,35 @@ void Test()
}

[Theory]
[InlineData("en-US", "h:mm", "1:05")]
[InlineData("en-US", "hh:mm", "01:05")]
[InlineData("en-US", "HH:mm", "13:05")]
[InlineData("en-US", "h:mm tt", "1:05 PM")]
[InlineData("en-US", "hh:mm tt", "01:05 PM")]
[InlineData("en-US", "HH:mm tt", "13:05 PM")]
[InlineData("en-US", "HH:mm:ss", "13:05:52")]
[InlineData("en-US", "hh:mm:ss", "01:05:52")]
[InlineData("en-US", "hh:mm:ss fff", "01:05:52 500")]
[InlineData("en-US", "HH:mm:ss fff", "13:05:52 500")]
[InlineData("en-US", "hh:mm:ss fff tt", "01:05:52 500 PM")]
[InlineData("en-US", "HH:mm:ss fff tt", "13:05:52 500 PM")]
[InlineData("en-US", "t", "1:05 PM")]
[InlineData("en-US", "T", "1:05:52 PM")]
[InlineData("en-GB", "h:mm", "1:05")]
[InlineData("en-GB", "hh:mm", "01:05")]
[InlineData("en-GB", "HH:mm", "13:05")]
[InlineData("en-GB", "h:mm tt", "1:05 pm")]
[InlineData("en-GB", "hh:mm tt", "01:05 pm")]
[InlineData("en-GB", "HH:mm tt", "13:05 pm")]
[InlineData("en-GB", "HH:mm:ss", "13:05:52")]
[InlineData("en-GB", "hh:mm:ss", "01:05:52")]
[InlineData("en-GB", "hh:mm:ss fff", "01:05:52 500")]
[InlineData("en-GB", "HH:mm:ss fff", "13:05:52 500")]
[InlineData("en-GB", "hh:mm:ss fff tt", "01:05:52 500 pm")]
[InlineData("en-GB", "HH:mm:ss fff tt", "13:05:52 500 pm")]
[InlineData("en-GB", "t", "13:05")]
[InlineData("en-GB", "T", "13:05:52")]
public void ToString_WithFormatParameter_ReturnsFormattedStringInProvidedCulture(string culture, string format, string expectedResult)
[InlineData("en-US", "h:mm")]
[InlineData("en-US", "hh:mm")]
[InlineData("en-US", "HH:mm")]
[InlineData("en-US", "h:mm tt")]
[InlineData("en-US", "hh:mm tt")]
[InlineData("en-US", "HH:mm tt")]
[InlineData("en-US", "HH:mm:ss")]
[InlineData("en-US", "hh:mm:ss")]
[InlineData("en-US", "hh:mm:ss fff")]
[InlineData("en-US", "HH:mm:ss fff")]
[InlineData("en-US", "hh:mm:ss fff tt")]
[InlineData("en-US", "HH:mm:ss fff tt")]
[InlineData("en-US", "t")]
[InlineData("en-US", "T")]
[InlineData("en-GB", "h:mm")]
[InlineData("en-GB", "hh:mm")]
[InlineData("en-GB", "HH:mm")]
[InlineData("en-GB", "h:mm tt")]
[InlineData("en-GB", "hh:mm tt")]
[InlineData("en-GB", "HH:mm tt")]
[InlineData("en-GB", "HH:mm:ss")]
[InlineData("en-GB", "hh:mm:ss")]
[InlineData("en-GB", "hh:mm:ss fff")]
[InlineData("en-GB", "HH:mm:ss fff")]
[InlineData("en-GB", "hh:mm:ss fff tt")]
[InlineData("en-GB", "HH:mm:ss fff tt")]
[InlineData("en-GB", "t")]
[InlineData("en-GB", "T")]
public void ToString_WithFormatParameter_ReturnsFormattedStringInProvidedCulture(string culture, string format)
{
void Test()
{
Expand All @@ -474,9 +480,11 @@ void Test()
int millisecond = 500;
var time = Time.From(hour, minute, second, millisecond);

var nativeFormattingOutput = new System.TimeOnly(hour, minute, second, millisecond).ToString(format, new CultureInfo(culture));

var timeString = time.ToString(format, new CultureInfo(culture));

timeString.Should().BeEquivalentTo(expectedResult);
timeString.Should().BeEquivalentTo(nativeFormattingOutput);
}

TestUtility.RunInCulture(Test, culture);
Expand Down

0 comments on commit 7c6945a

Please sign in to comment.