Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit a9d64f9

Browse files
Merge pull request #25 from thefringeninja/links-refactor
Refactor Link Generation
2 parents 9ea7598 + 441c0b8 commit a9d64f9

65 files changed

Lines changed: 1163 additions & 1260 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/SqlStreamStore.HAL.Tests/AllStreamMessageTests.cs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public AllStreamMessageTests()
1515

1616
public void Dispose() => _fixture.Dispose();
1717
private readonly SqlStreamStoreHalMiddlewareFixture _fixture;
18-
private const string HeadOfAll = "../stream?d=b&m=20&p=-1&e=0";
18+
private const string HeadOfAll = "stream?d=b&m=20&p=-1&e=0";
1919

2020
[Fact]
2121
public async Task read_single_message_all_stream()
@@ -29,18 +29,13 @@ public async Task read_single_message_all_stream()
2929

3030
var resource = await response.AsHal();
3131

32-
resource.Links.Keys.ShouldBe(new[]
33-
{
34-
Constants.Relations.Self,
35-
Constants.Relations.Message,
36-
Constants.Relations.Feed,
37-
Constants.Relations.Find
38-
});
39-
40-
resource.ShouldLink(Constants.Relations.Self, "0");
41-
resource.ShouldLink(Constants.Relations.Message, "0");
42-
resource.ShouldLink(Constants.Relations.Feed, HeadOfAll);
43-
resource.ShouldLink(Constants.Relations.Find, "../streams/{streamId}", "Find a Stream");
32+
resource.ShouldLink(
33+
Links
34+
.RootedAt("../")
35+
.Find()
36+
.Index()
37+
.AddSelf(Constants.Relations.Message, "stream/0")
38+
.Add(Constants.Relations.Feed, HeadOfAll));
4439
}
4540
}
4641

@@ -53,14 +48,10 @@ public async Task read_single_message_does_not_exist_all_stream()
5348

5449
var resource = await response.AsHal();
5550

56-
resource.Links.Keys.ShouldBe(new[]
57-
{
58-
Constants.Relations.Feed,
59-
Constants.Relations.Find
60-
});
61-
62-
resource.ShouldLink(Constants.Relations.Feed, HeadOfAll);
63-
resource.ShouldLink(Constants.Relations.Find, "../streams/{streamId}", "Find a Stream");
51+
resource.ShouldLink(Links
52+
.RootedAt("../")
53+
.AddSelf(Constants.Relations.Message, "stream/0")
54+
.Add(Constants.Relations.Feed, HeadOfAll));
6455
}
6556
}
6657
}

src/SqlStreamStore.HAL.Tests/CanonicalUrlTests.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Net;
77
using System.Threading.Tasks;
88
using Shouldly;
9-
using SqlStreamStore.HAL.Resources;
109
using Xunit;
1110

1211
public class CanonicalUrlTests
@@ -46,31 +45,33 @@ from set in GetPermutations(parameters, 4)
4645

4746
private static IEnumerable<(string, Uri)> NonCanonical()
4847
{
48+
var bools = new[] { true, false };
49+
4950
var formatters = new Dictionary<bool, Func<string, int, long, bool, string>>
5051
{
51-
[true] = LinkFormatter.FormatForwardLink,
52-
[false] = LinkFormatter.FormatBackwardLink
52+
[true] = Links.FormatForwardLink,
53+
[false] = Links.FormatBackwardLink
5354
};
5455

55-
(string streamId, string path)[] streams =
56+
(string streamId, string path, string root)[] streams =
5657
{
57-
(StreamId, $"/streams/{StreamId}"),
58-
(Constants.Streams.All, Constants.Streams.All)
58+
(StreamId, $"streams/{StreamId}", "../"),
59+
(Constants.Streams.All, Constants.Streams.All, string.Empty)
5960
};
6061

6162
return
6263
from _ in streams
63-
from prefetch in new[] { true, false }
64-
from forward in new[] { true, false }
64+
from prefetch in bools
65+
from forward in bools
6566
let format = formatters[forward]
66-
let canonicalUri = format(_.streamId, 20, 0, prefetch)
67+
let canonicalUri = new Uri(
68+
format($"{_.root}{_.path}", 20, 0, prefetch),
69+
UriKind.Relative)
6770
from queryString in GetQueryStrings(forward, prefetch)
6871
// query strings are supposed to be case sensitive!!
6972
//.Concat(new[] { $"d={(forward ? 'F' : 'B')}&M=20&P=0{(prefetch ? "&E" : string.Empty)}" })
70-
where $"{_.streamId}?{queryString}" != canonicalUri
71-
select ($"{_.path}?{queryString}", new Uri(
72-
canonicalUri,
73-
UriKind.Relative));
73+
where !canonicalUri.OriginalString.EndsWith($"?{queryString}")
74+
select ($"{_.path}?{queryString}", canonicalUri);
7475
}
7576

7677
public static IEnumerable<object[]> NonCanonicalUriCases()

src/SqlStreamStore.HAL.Tests/HeadersTests.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Net.Http;
66
using System.Threading.Tasks;
77
using Shouldly;
8-
using SqlStreamStore.HAL.Resources;
98
using SqlStreamStore.Streams;
109
using Xunit;
1110

@@ -37,7 +36,7 @@ public async Task all_stream_head_link(HttpMethod method)
3736
using(var response = await _fixture.HttpClient.SendAsync(
3837
new HttpRequestMessage(
3938
method,
40-
LinkFormatter.FormatBackwardLink("/stream", 20, Position.End, true))))
39+
Links.FormatBackwardLink("/stream", 20, Position.End, true))))
4140
{
4241
response.IsSuccessStatusCode.ShouldBeTrue();
4342

src/SqlStreamStore.HAL.Tests/Link.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ public bool Equals(Link other)
1414
return false;
1515
if(ReferenceEquals(this, other))
1616
return true;
17-
return string.Equals(Rel, other.Rel) && string.Equals(Href, other.Href)
17+
return string.Equals(Rel, other.Rel)
18+
&& string.Equals(Href ?? string.Empty, other.Href ?? string.Empty)
1819
&& string.Equals(Title, other.Title);
1920
}
2021

src/SqlStreamStore.HAL.Tests/LinkAssertionExtensions.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,20 @@ public static void ShouldLink(this Resource resource, string rel, string href, s
1313
Rel = rel,
1414
Title = title
1515
});
16+
17+
public static void ShouldLink(this Resource resource, Links links)
18+
{
19+
var halLinks = links.ToHalLinks();
20+
21+
foreach(var link in halLinks)
22+
{
23+
resource.Links[link.Rel].ShouldContain(new Link
24+
{
25+
Rel = link.Rel,
26+
Href = link.Href,
27+
Title = link.Title
28+
});
29+
}
30+
}
1631
}
1732
}

src/SqlStreamStore.HAL.Tests/OptionsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static IEnumerable<object[]> OptionsAllowedMethodCases()
4343
yield return new object[]
4444
{
4545
"/streams/a-stream/0",
46-
new[] { HttpMethod.Get, HttpMethod.Head, HttpMethod.Options }
46+
new[] { HttpMethod.Get, HttpMethod.Head, HttpMethod.Delete, HttpMethod.Options }
4747
};
4848
}
4949

src/SqlStreamStore.HAL.Tests/StreamMessageTests.cs

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public StreamMessageTests()
1616

1717
public void Dispose() => _fixture.Dispose();
1818
private readonly SqlStreamStoreHalMiddlewareFixture _fixture;
19-
private const string HeadOfStream = "../a-stream?d=b&m=20&p=-1&e=0";
19+
private const string HeadOfStream = "streams/a-stream?d=b&m=20&p=-1&e=0";
2020

2121
[Fact]
2222
public async Task read_single_message_stream()
@@ -30,24 +30,16 @@ public async Task read_single_message_stream()
3030
3131
var resource = await response.AsHal();
3232
33-
resource.Links.Keys.ShouldBe(new[]
34-
{
35-
Constants.Relations.Self,
36-
Constants.Relations.First,
37-
Constants.Relations.Next,
38-
Constants.Relations.Last,
39-
Constants.Relations.Feed,
40-
Constants.Relations.Message,
41-
Constants.Relations.Find
42-
});
43-
44-
resource.ShouldLink(Constants.Relations.Self, "0");
45-
resource.ShouldLink(Constants.Relations.First, "0");
46-
resource.ShouldLink(Constants.Relations.Next, "1");
47-
resource.ShouldLink(Constants.Relations.Last, "-1");
48-
resource.ShouldLink(Constants.Relations.Feed, HeadOfStream);
49-
resource.ShouldLink(Constants.Relations.Message, "0");
50-
resource.ShouldLink(Constants.Relations.Find, "../../streams/{streamId}", "Find a Stream");
33+
resource.ShouldLink(Links
34+
.RootedAt("../../")
35+
.Index()
36+
.Find()
37+
.Add(Constants.Relations.Self, "streams/a-stream/0")
38+
.Add(Constants.Relations.First, "streams/a-stream/0")
39+
.Add(Constants.Relations.Next, "streams/a-stream/1")
40+
.Add(Constants.Relations.Last, "streams/a-stream/-1")
41+
.Add(Constants.Relations.Feed, HeadOfStream)
42+
.Add(Constants.Relations.Message, "streams/a-stream/0"));
5143
}
5244
}
5345

@@ -61,22 +53,15 @@ public async Task read_single_message_does_not_exist_stream()
6153

6254
var resource = await response.AsHal();
6355

64-
resource.Links.Keys.ShouldBe(new[]
65-
{
66-
Constants.Relations.Self,
67-
Constants.Relations.First,
68-
Constants.Relations.Last,
69-
Constants.Relations.Feed,
70-
Constants.Relations.Message,
71-
Constants.Relations.Find
72-
});
73-
74-
resource.ShouldLink(Constants.Relations.Self, "0");
75-
resource.ShouldLink(Constants.Relations.First, "0");
76-
resource.ShouldLink(Constants.Relations.Last, "-1");
77-
resource.ShouldLink(Constants.Relations.Feed, HeadOfStream);
78-
resource.ShouldLink(Constants.Relations.Message, "0");
79-
resource.ShouldLink(Constants.Relations.Find, "../../streams/{streamId}", "Find a Stream");
56+
resource.ShouldLink(Links
57+
.RootedAt("../../")
58+
.Index()
59+
.Find()
60+
.Add(Constants.Relations.Self, "streams/a-stream/0")
61+
.Add(Constants.Relations.First, "streams/a-stream/0")
62+
.Add(Constants.Relations.Last, "streams/a-stream/-1")
63+
.Add(Constants.Relations.Feed, HeadOfStream)
64+
.Add(Constants.Relations.Message, "streams/a-stream/0"));
8065
}
8166
}
8267

src/SqlStreamStore.HAL.Tests/StreamMetadataTests.cs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,17 @@ await _fixture.HttpClient.SendAsync(
3636

3737
((string) resource.State.streamId).ShouldBe(StreamId);
3838
((int) resource.State.metadataStreamVersion).ShouldBe(ExpectedVersion.NoStream);
39-
((int?) resource.State.maxAge).ShouldBe(default(int?));
40-
((int?) resource.State.maxCount).ShouldBe(default(int?));
39+
((int?) resource.State.maxAge).ShouldBe(default);
40+
((int?) resource.State.maxCount).ShouldBe(default);
4141
((string) resource.State.metadataJson).ShouldBeNull();
4242

43-
resource.ShouldLink(Constants.Relations.Self, "metadata");
44-
resource.ShouldLink(Constants.Relations.Metadata, "metadata");
45-
resource.ShouldLink(Constants.Relations.Feed, $"../{StreamId}");
43+
resource.ShouldLink(
44+
Links
45+
.RootedAt("../../../")
46+
.Index()
47+
.Find()
48+
.Add(Constants.Relations.Metadata, $"streams/{StreamId}/metadata").Self()
49+
.Add(Constants.Relations.Feed, $"streams/{StreamId}"));
4650
}
4751
}
4852

@@ -87,9 +91,13 @@ await _fixture.HttpClient.SendAsync(
8791
type = "a-type"
8892
})).ShouldBeTrue();
8993

90-
resource.ShouldLink(Constants.Relations.Self, "metadata");
91-
resource.ShouldLink(Constants.Relations.Metadata, "metadata");
92-
resource.ShouldLink(Constants.Relations.Feed, $"../{StreamId}");
94+
resource.ShouldLink(
95+
Links
96+
.RootedAt("../../../")
97+
.Index()
98+
.Find()
99+
.Add(Constants.Relations.Metadata, $"streams/{StreamId}/metadata").Self()
100+
.Add(Constants.Relations.Feed, $"streams/{StreamId}"));
93101
}
94102
}
95103

@@ -129,9 +137,13 @@ public async Task set_metadata()
129137
type = "a-type"
130138
})).ShouldBeTrue();
131139

132-
resource.ShouldLink(Constants.Relations.Self, "metadata");
133-
resource.ShouldLink(Constants.Relations.Metadata, "metadata");
134-
resource.ShouldLink(Constants.Relations.Feed, $"../{StreamId}");
140+
resource.ShouldLink(
141+
Links
142+
.RootedAt("../../../")
143+
.Index()
144+
.Find()
145+
.Add(Constants.Relations.Metadata, $"streams/{StreamId}/metadata").Self()
146+
.Add(Constants.Relations.Feed, $"streams/{StreamId}"));
135147
}
136148
}
137149

0 commit comments

Comments
 (0)