Skip to content

Commit

Permalink
Refactor URI construction and enhance test coverage (#126)
Browse files Browse the repository at this point in the history
* Refactor URI construction and enhance test coverage

Refactored `DeleteOperation` and `ReplaceOperation` to directly include `operation.ItemId` in URI construction via `MakeAbsoluteUri`. Updated `ExecutableOperation` to support an optional `itemId` parameter in `MakeAbsoluteUri`. Added `MakeAbsoluteUri_WorksWithId` theory test to validate various URI construction scenarios.

* Refactor URI handling and update related tests

Modified `MakeAbsoluteUri` in `ExecutableOperation.cs` to handle `itemId` more robustly by conditionally formatting it with a leading slash if it is not empty and avoiding trailing slashes before `itemId`. Updated test cases in `OfflineDbContext_Tests.cs`, `AddOperation_Tests.cs`, and `ExecutableOperation_Tests.cs` to reflect the new URI formatting rules, specifically removing trailing slashes before query parameters in the expected URIs.

---------

Co-authored-by: Adrian Hall <[email protected]>
  • Loading branch information
richard-einfinity and adrianhall authored Oct 8, 2024
1 parent db1a7e2 commit 801caee
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ internal class DeleteOperation(DatasyncOperation operation) : ExecutableOperatio
/// <returns>The result of the push operation (async).</returns>
internal override async Task<ServiceResponse> ExecuteAsync(EntityDatasyncOptions options, CancellationToken cancellationToken = default)
{
Uri endpoint = MakeAbsoluteUri(options.HttpClient.BaseAddress, options.Endpoint);
using HttpRequestMessage request = new(HttpMethod.Delete, new Uri(endpoint, operation.ItemId));
Uri endpoint = MakeAbsoluteUri(options.HttpClient.BaseAddress, options.Endpoint, operation.ItemId);
using HttpRequestMessage request = new(HttpMethod.Delete, endpoint);
if (!string.IsNullOrEmpty(operation.EntityVersion))
{
request.Headers.IfMatch.Add(new EntityTagHeaderValue($"\"{operation.EntityVersion}\""));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,22 @@ internal abstract class ExecutableOperation
/// </summary>
/// <param name="baseAddress">The base address from the client.</param>
/// <param name="relativeOrAbsoluteUri">A relative or absolute URI</param>
/// <param name="itemId">The id of the item to append to the URI.</param>
/// <returns></returns>
internal static Uri MakeAbsoluteUri(Uri? baseAddress, Uri relativeOrAbsoluteUri)
internal static Uri MakeAbsoluteUri(Uri? baseAddress, Uri relativeOrAbsoluteUri, string? itemId = null)
{
itemId = string.IsNullOrWhiteSpace(itemId) ? string.Empty : $"/{itemId}";

if (relativeOrAbsoluteUri.IsAbsoluteUri)
{
return new Uri($"{relativeOrAbsoluteUri.ToString().TrimEnd('/')}/");
return new Uri($"{relativeOrAbsoluteUri.ToString().TrimEnd('/')}{itemId}");
}

if (baseAddress != null)
{
if (baseAddress.IsAbsoluteUri)
{
return new Uri($"{new Uri(baseAddress, relativeOrAbsoluteUri).ToString().TrimEnd('/')}/");
return new Uri($"{new Uri(baseAddress, relativeOrAbsoluteUri).ToString().TrimEnd('/')}{itemId}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ internal class ReplaceOperation(DatasyncOperation operation) : ExecutableOperati
/// <returns>The result of the push operation (async).</returns>
internal override async Task<ServiceResponse> ExecuteAsync(EntityDatasyncOptions options, CancellationToken cancellationToken = default)
{
Uri endpoint = MakeAbsoluteUri(options.HttpClient.BaseAddress, options.Endpoint);
using HttpRequestMessage request = new(HttpMethod.Put, new Uri(endpoint, operation.ItemId))
Uri endpoint = MakeAbsoluteUri(options.HttpClient.BaseAddress, options.Endpoint, operation.ItemId);
using HttpRequestMessage request = new(HttpMethod.Put, endpoint)
{
Content = new StringContent(operation.Item, JsonMediaType)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ public async Task PullAsync_List_Works_InitialSync()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");

DatasyncDeltaToken token = this.context.DatasyncDeltaTokens.Find(["CommunityToolkit.Datasync.TestCommon.Databases.ClientMovie"]);
token.Should().NotBeNull();
Expand Down Expand Up @@ -103,10 +103,10 @@ public async Task PullAsync_DbSet_Works_InitialSync()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");

DatasyncDeltaToken token = this.context.DatasyncDeltaTokens.Find(["CommunityToolkit.Datasync.TestCommon.Databases.ClientMovie"]);
token.Should().NotBeNull();
Expand Down Expand Up @@ -147,10 +147,10 @@ public async Task PullAsync_Configurator_Works_InitialSync_Ver1()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$filter=startswith%28title%2C%27abc%27%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$filter=startswith%28title%2C%27abc%27%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");

DatasyncDeltaToken token = this.context.DatasyncDeltaTokens.Find(["q-CommunityToolkit.Datasync.TestCommon.Databases.ClientMovie-abc"]);
token.Should().NotBeNull();
Expand Down Expand Up @@ -191,10 +191,10 @@ public async Task PullAsync_Configurator_Works_InitialSync_Ver2()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$filter=startswith%28title%2C%27abc%27%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$filter=startswith%28title%2C%27abc%27%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");

DatasyncDeltaToken token = this.context.DatasyncDeltaTokens.Find(["q-CommunityToolkit.Datasync.TestCommon.Databases.ClientMovie-a87ec01f71a5577199797b433e3bcc6b"]);
token.Should().NotBeNull();
Expand Down Expand Up @@ -242,10 +242,10 @@ public async Task PullAsync_Configurator_Works_InitialSync_Ver3()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$filter=startswith%28title%2C%27abc%27%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$filter=startswith%28title%2C%27abc%27%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");

DatasyncDeltaToken token = this.context.DatasyncDeltaTokens.Find(["q-CommunityToolkit.Datasync.TestCommon.Databases.ClientMovie-a87ec01f71a5577199797b433e3bcc6b"]);
token.Should().NotBeNull();
Expand Down Expand Up @@ -281,10 +281,10 @@ public async Task PullAsync_Configurator_Works_InitialSync_Ver4()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");

DatasyncDeltaToken token = this.context.DatasyncDeltaTokens.Find(["CommunityToolkit.Datasync.TestCommon.Databases.ClientMovie"]);
token.Should().NotBeNull();
Expand Down Expand Up @@ -321,10 +321,10 @@ public async Task PullAsync_List_Works_FollowonSync()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$filter=%28updatedAt gt cast%282024-08-23T20%3A22%3A54.291Z%2CEdm.DateTimeOffset%29%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$filter=%28updatedAt gt cast%282024-08-23T20%3A22%3A54.291Z%2CEdm.DateTimeOffset%29%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");
}

[Fact]
Expand Down Expand Up @@ -362,10 +362,10 @@ public async Task PullAsync_List_Works_DoesntAddDeletions()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$filter=%28updatedAt gt cast%282024-08-23T20%3A22%3A54.291Z%2CEdm.DateTimeOffset%29%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$filter=%28updatedAt gt cast%282024-08-23T20%3A22%3A54.291Z%2CEdm.DateTimeOffset%29%29&$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");
}

[Fact]
Expand Down Expand Up @@ -410,10 +410,10 @@ public async Task PullAsync_List_Works_DeletionsAndReplacements()
actual.Should().BeEquivalentTo(expected);

this.context.Handler.Requests.Should().HaveCount(4);
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/?$skip=15");
this.context.Handler.Requests[0].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$orderby=updatedAt&$count=true&__includedeleted=true");
this.context.Handler.Requests[1].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=5");
this.context.Handler.Requests[2].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=10");
this.context.Handler.Requests[3].RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies?$skip=15");
}

[Fact]
Expand All @@ -426,7 +426,7 @@ public async Task PullAsync_List_FailedRequest()
pullResult.IsSuccessful.Should().BeFalse();
pullResult.FailedRequests.Should().HaveCount(1);
KeyValuePair<Uri, ServiceResponse> kv = pullResult.FailedRequests.Single();
kv.Key.Should().Be("https://test.zumo.net/tables/movies/?$orderby=updatedAt&$count=true&__includedeleted=true");
kv.Key.Should().Be("https://test.zumo.net/tables/movies?$orderby=updatedAt&$count=true&__includedeleted=true");
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public async Task AddOperation_ExecuteAsync()
HttpRequestMessage request = handler.Requests.SingleOrDefault();
request.Should().NotBeNull();
request.Method.Should().Be(HttpMethod.Post);
request.RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies/");
request.RequestUri.ToString().Should().Be("https://test.zumo.net/tables/movies");
(await request.Content.ReadAsStringAsync()).Should().Be(itemJson);

response.Should().NotBeNull();
Expand Down
Loading

0 comments on commit 801caee

Please sign in to comment.