@@ -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 ,
@@ -258,6 +280,47 @@ public async Task malformed_request_body(string malformedRequest)
258280 }
259281 }
260282
283+ public static IEnumerable < object [ ] > BadExpectedVersionCases ( )
284+ {
285+ var random = new Random ( ) ;
286+
287+ var maximumBadExpectedVersion = Constants . Headers . MinimumExpectedVersion - 1 ;
288+
289+ yield return new object [ ] { maximumBadExpectedVersion } ;
290+ for ( var i = 0 ; i < 5 ; i ++ )
291+ {
292+ yield return new object [ ] { random . Next ( int . MinValue , maximumBadExpectedVersion ) } ;
293+ }
294+ }
295+
296+ [ Theory , MemberData ( nameof ( BadExpectedVersionCases ) ) ]
297+ public async Task bad_expected_version ( int badExpectedVersion )
298+ {
299+ using ( var response = await _fixture . HttpClient . SendAsync (
300+ new HttpRequestMessage ( HttpMethod . Post , $ "/streams/{ StreamId } ")
301+ {
302+ Headers =
303+ {
304+ { Constants . Headers . ExpectedVersion , $ "{ badExpectedVersion } "}
305+ } ,
306+ Content = new StringContent ( JObject . FromObject ( new
307+ {
308+ messageId = Guid . NewGuid ( ) ,
309+ jsonData = new { } ,
310+ type = "type"
311+ } ) . ToString ( ) )
312+ {
313+ Headers =
314+ {
315+ ContentType = new MediaTypeHeaderValue ( Constants . MediaTypes . HalJson )
316+ }
317+ }
318+ } ) )
319+ {
320+ response . StatusCode . ShouldBe ( HttpStatusCode . BadRequest ) ;
321+ }
322+ }
323+
261324 public void Dispose ( ) => _fixture . Dispose ( ) ;
262325 }
263326}
0 commit comments