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

Commit fab2bec

Browse files
writeResult.StreamVersion == 0 is not sufficient to know if the stream was created
1 parent b59e533 commit fab2bec

2 files changed

Lines changed: 95 additions & 73 deletions

File tree

src/SqlStreamStore.HAL.Tests/StreamAppendTests.cs

Lines changed: 93 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ public StreamAppendTests()
2424

2525
public static IEnumerable<object[]> AppendCases()
2626
{
27-
var messageId = Guid.NewGuid();
27+
var messageId1 = Guid.NewGuid();
28+
var messageId2 = Guid.NewGuid();
2829

2930
var jsonData = JObject.FromObject(new
3031
{
@@ -36,69 +37,83 @@ public static IEnumerable<object[]> AppendCases()
3637
property = "metaValue"
3738
});
3839

39-
var bodies = new JToken[]
40+
var bodies = new (JToken, Guid[])[]
4041
{
41-
JObject.FromObject(new
42+
(JObject.FromObject(new
4243
{
43-
messageId,
44+
messageId = messageId1,
4445
type = "type",
4546
jsonData,
4647
jsonMetadata
47-
}),
48-
JArray.FromObject(new[]
49-
{
50-
new
48+
}), new[] { messageId1 }),
49+
(JArray.FromObject(new[]
5150
{
52-
messageId,
53-
type = "type",
54-
jsonData,
55-
jsonMetadata
56-
}
57-
})
51+
new
52+
{
53+
messageId = messageId1,
54+
type = "type",
55+
jsonData,
56+
jsonMetadata
57+
},
58+
new
59+
{
60+
messageId = messageId2,
61+
type = "type",
62+
jsonData,
63+
jsonMetadata
64+
}
65+
}),
66+
new[] { messageId1, messageId2 })
5867
};
5968

60-
foreach(var body in bodies)
69+
var location = new Uri($"../{Constants.Streams.Stream}/{StreamId}", UriKind.Relative);
70+
71+
foreach(var (body, messageIds) in bodies)
6172
{
6273
yield return new object[]
6374
{
64-
body,
6575
ExpectedVersion.Any,
66-
HttpStatusCode.Created,
67-
messageId,
76+
body,
77+
messageIds,
6878
jsonData,
69-
jsonMetadata
79+
jsonMetadata,
80+
HttpStatusCode.OK,
81+
null
7082
};
7183
yield return new object[]
7284
{
73-
body,
7485
default(int?),
75-
HttpStatusCode.Created,
76-
messageId,
86+
body,
87+
messageIds,
7788
jsonData,
78-
jsonMetadata
89+
jsonMetadata,
90+
HttpStatusCode.OK,
91+
null
7992
};
8093
yield return new object[]
8194
{
82-
body,
8395
ExpectedVersion.NoStream,
84-
HttpStatusCode.Created,
85-
messageId,
96+
body,
97+
messageIds,
8698
jsonData,
87-
jsonMetadata
99+
jsonMetadata,
100+
HttpStatusCode.Created,
101+
location
88102
};
89103
}
90104
}
91105

92106
[Theory, MemberData(nameof(AppendCases))]
93107
public async Task expected_version(
94-
JToken body,
95108
int? expectedVersion,
96-
HttpStatusCode statusCode,
97-
Guid messageId,
109+
JToken body,
110+
Guid[] messageIds,
98111
JObject jsonData,
99-
JObject jsonMetadata)
112+
JObject jsonMetadata,
113+
HttpStatusCode statusCode,
114+
Uri location)
100115
{
101-
var request = new HttpRequestMessage(HttpMethod.Post, $"/streams/{StreamId}")
116+
var request = new HttpRequestMessage(HttpMethod.Post, $"/{Constants.Streams.Stream}/{StreamId}")
102117
{
103118
Content = new StringContent(body.ToString())
104119
};
@@ -111,21 +126,25 @@ public async Task expected_version(
111126
using(var response = await _fixture.HttpClient.SendAsync(request))
112127
{
113128
response.StatusCode.ShouldBe(statusCode);
129+
response.Headers.Location.ShouldBe(location);
114130
}
115131

116132
var page = await _fixture.StreamStore.ReadStreamForwards(StreamId, 0, int.MaxValue);
117-
133+
118134
page.Status.ShouldBe(PageReadStatus.Success);
119-
page.Messages.Length.ShouldBe(1);
120-
page.Messages[0].MessageId.ShouldBe(messageId);
121-
page.Messages[0].Type.ShouldBe("type");
122-
JToken.DeepEquals(JObject.Parse(await page.Messages[0].GetJsonData()), jsonData).ShouldBeTrue();
123-
JToken.DeepEquals(JObject.Parse(page.Messages[0].JsonMetadata), jsonMetadata).ShouldBeTrue();
135+
page.Messages.Length.ShouldBe(messageIds.Length);
136+
for(var i = 0; i < messageIds.Length; i++)
137+
{
138+
page.Messages[i].MessageId.ShouldBe(messageIds[i]);
139+
page.Messages[i].Type.ShouldBe("type");
140+
JToken.DeepEquals(JObject.Parse(await page.Messages[i].GetJsonData()), jsonData).ShouldBeTrue();
141+
JToken.DeepEquals(JObject.Parse(page.Messages[i].JsonMetadata), jsonMetadata).ShouldBeTrue();
142+
}
124143
}
125144

126145
[Theory]
127-
[InlineData(new[]{ExpectedVersion.NoStream, ExpectedVersion.NoStream})]
128-
[InlineData(new[]{ExpectedVersion.NoStream, 2})]
146+
[InlineData(new[] { ExpectedVersion.NoStream, ExpectedVersion.NoStream })]
147+
[InlineData(new[] { ExpectedVersion.NoStream, 2 })]
129148
public async Task wrong_expected_version(int[] expectedVersions)
130149
{
131150
var jsonData = JObject.FromObject(new
@@ -140,11 +159,36 @@ public async Task wrong_expected_version(int[] expectedVersions)
140159

141160
for(var i = 0; i < expectedVersions.Length - 1; i++)
142161
{
143-
using(await _fixture.HttpClient.SendAsync(new HttpRequestMessage(HttpMethod.Post, $"/streams/{StreamId}")
162+
using(await _fixture.HttpClient.SendAsync(
163+
new HttpRequestMessage(HttpMethod.Post, $"/streams/{StreamId}")
164+
{
165+
Headers =
166+
{
167+
{ Constants.Headers.ExpectedVersion, $"{expectedVersions[i]}" }
168+
},
169+
Content = new StringContent(JObject.FromObject(new
170+
{
171+
messageId = Guid.NewGuid(),
172+
type = "type",
173+
jsonData,
174+
jsonMetadata
175+
}).ToString())
176+
{
177+
Headers =
178+
{
179+
ContentType = new MediaTypeHeaderValue("application/json")
180+
}
181+
}
182+
}))
183+
{ }
184+
}
185+
186+
using(var response = await _fixture.HttpClient.SendAsync(
187+
new HttpRequestMessage(HttpMethod.Post, $"/streams/{StreamId}")
144188
{
145189
Headers =
146190
{
147-
{Constants.Headers.ExpectedVersion, $"{expectedVersions[i]}"}
191+
{ Constants.Headers.ExpectedVersion, $"{expectedVersions[expectedVersions.Length - 1]}" }
148192
},
149193
Content = new StringContent(JObject.FromObject(new
150194
{
@@ -160,46 +204,24 @@ public async Task wrong_expected_version(int[] expectedVersions)
160204
}
161205
}
162206
}))
163-
{ }
164-
}
165-
166-
using(var response = await _fixture.HttpClient.SendAsync(new HttpRequestMessage(HttpMethod.Post, $"/streams/{StreamId}")
167-
{
168-
Headers =
169-
{
170-
{Constants.Headers.ExpectedVersion, $"{expectedVersions[expectedVersions.Length - 1]}"}
171-
},
172-
Content = new StringContent(JObject.FromObject(new
173-
{
174-
messageId = Guid.NewGuid(),
175-
type = "type",
176-
jsonData,
177-
jsonMetadata
178-
}).ToString())
179-
{
180-
Headers =
181-
{
182-
ContentType = new MediaTypeHeaderValue("application/json")
183-
}
184-
}
185-
}))
186207
{
187208
response.StatusCode.ShouldBe(HttpStatusCode.Conflict);
188209
response.Content.Headers.ContentType.ShouldBe(new MediaTypeHeaderValue(
189210
Constants.MediaTypes.HalJson));
190211
}
212+
191213
var page = await _fixture.StreamStore.ReadStreamForwards(StreamId, 0, int.MaxValue);
192-
214+
193215
page.Status.ShouldBe(PageReadStatus.Success);
194216
page.Messages.Length.ShouldBe(expectedVersions.Length - 1);
195217
}
196218

197219
private static IEnumerable<string> MalformedRequests()
198220
{
199221
var messageId = Guid.NewGuid();
200-
222+
201223
const string type = "type";
202-
224+
203225
var jsonData = JObject.FromObject(new
204226
{
205227
property = "value"
@@ -209,18 +231,18 @@ private static IEnumerable<string> MalformedRequests()
209231
{
210232
property = "metaValue"
211233
});
212-
234+
213235
yield return string.Empty;
214236
yield return "{}";
215-
237+
216238
yield return JObject.FromObject(new
217239
{
218240
messageId = Guid.Empty,
219241
type,
220242
jsonData,
221243
jsonMetadata
222244
}).ToString();
223-
245+
224246
yield return JObject.FromObject(new
225247
{
226248
type,

src/SqlStreamStore.HAL/Streams/StreamResource.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ public async Task<Response> Post(
4040
var response = new HalJsonResponse(
4141
new HALResponse(result)
4242
.AddLinks(links),
43-
result.CurrentVersion == 0
43+
operation.ExpectedVersion == ExpectedVersion.NoStream
4444
? 201
4545
: 200);
46-
if(operation.ExpectedVersion == ExpectedVersion.NoStream)
46+
if(response.StatusCode == 201)
4747
{
4848
response.Headers[Constants.Headers.Location] =
4949
new[] { $"{_relativePathToRoot}streams/{operation.StreamId}" };

0 commit comments

Comments
 (0)