1+ namespace SqlStreamStore . HAL . Tests
2+ {
3+ using System ;
4+ using System . Collections . Generic ;
5+ using System . Net ;
6+ using System . Net . Http ;
7+ using System . Net . Http . Headers ;
8+ using System . Threading . Tasks ;
9+ using Newtonsoft . Json . Linq ;
10+ using Shouldly ;
11+ using SqlStreamStore . Streams ;
12+ using Xunit ;
13+
14+ public class StreamAppendTests : IDisposable
15+ {
16+ private const string StreamId = "a-stream" ;
17+ private readonly SqlStreamStoreHalMiddlewareFixture _fixture ;
18+
19+ public StreamAppendTests ( )
20+ {
21+ _fixture = new SqlStreamStoreHalMiddlewareFixture ( ) ;
22+ }
23+
24+ public static IEnumerable < object [ ] > AppendCases ( )
25+ {
26+ var messageId = Guid . NewGuid ( ) ;
27+
28+ var jsonData = JObject . FromObject ( new
29+ {
30+ property = "value"
31+ } ) ;
32+
33+ var jsonMetadata = JObject . FromObject ( new
34+ {
35+ property = "metaValue"
36+ } ) ;
37+
38+ var bodies = new JToken [ ]
39+ {
40+ JObject . FromObject ( new
41+ {
42+ messageId ,
43+ type = "type" ,
44+ jsonData ,
45+ jsonMetadata
46+ } ) ,
47+ JArray . FromObject ( new [ ]
48+ {
49+ new
50+ {
51+ messageId ,
52+ type = "type" ,
53+ jsonData ,
54+ jsonMetadata
55+ }
56+ } )
57+ } ;
58+
59+ foreach ( var body in bodies )
60+ {
61+ yield return new object [ ]
62+ {
63+ body ,
64+ ExpectedVersion . Any ,
65+ HttpStatusCode . OK ,
66+ messageId ,
67+ jsonData ,
68+ jsonMetadata
69+ } ;
70+ yield return new object [ ]
71+ {
72+ body ,
73+ default ( int ? ) ,
74+ HttpStatusCode . OK ,
75+ messageId ,
76+ jsonData ,
77+ jsonMetadata
78+ } ;
79+ yield return new object [ ]
80+ {
81+ body ,
82+ ExpectedVersion . NoStream ,
83+ HttpStatusCode . Created ,
84+ messageId ,
85+ jsonData ,
86+ jsonMetadata
87+ } ;
88+ }
89+ }
90+
91+ [ Theory , MemberData ( nameof ( AppendCases ) ) ]
92+ public async Task expected_version (
93+ JToken body ,
94+ int ? expectedVersion ,
95+ HttpStatusCode statusCode ,
96+ Guid messageId ,
97+ JObject jsonData ,
98+ JObject jsonMetadata )
99+ {
100+ var request = new HttpRequestMessage ( HttpMethod . Post , $ "/streams/{ StreamId } ")
101+ {
102+ Content = new StringContent ( body . ToString ( ) )
103+ } ;
104+
105+ if ( expectedVersion . HasValue )
106+ {
107+ request . Headers . Add ( Constants . Headers . ExpectedVersion , $ "{ expectedVersion } ") ;
108+ }
109+
110+ using ( var response = await _fixture . HttpClient . SendAsync ( request ) )
111+ {
112+ response . StatusCode . ShouldBe ( statusCode ) ;
113+ }
114+
115+ var page = await _fixture . StreamStore . ReadStreamForwards ( StreamId , 0 , int . MaxValue ) ;
116+
117+ page . Status . ShouldBe ( PageReadStatus . Success ) ;
118+ page . Messages . Length . ShouldBe ( 1 ) ;
119+ page . Messages [ 0 ] . MessageId . ShouldBe ( messageId ) ;
120+ page . Messages [ 0 ] . Type . ShouldBe ( "type" ) ;
121+ JToken . DeepEquals ( JObject . Parse ( await page . Messages [ 0 ] . GetJsonData ( ) ) , jsonData ) . ShouldBeTrue ( ) ;
122+ JToken . DeepEquals ( JObject . Parse ( page . Messages [ 0 ] . JsonMetadata ) , jsonMetadata ) . ShouldBeTrue ( ) ;
123+ }
124+
125+ [ Theory ]
126+ [ InlineData ( new [ ] { ExpectedVersion . NoStream , ExpectedVersion . NoStream } ) ]
127+ [ InlineData ( new [ ] { ExpectedVersion . NoStream , 2 } ) ]
128+ public async Task wrong_expected_version ( int [ ] expectedVersions )
129+ {
130+ var jsonData = JObject . FromObject ( new
131+ {
132+ property = "value"
133+ } ) ;
134+
135+ var jsonMetadata = JObject . FromObject ( new
136+ {
137+ property = "metaValue"
138+ } ) ;
139+
140+ for ( var i = 0 ; i < expectedVersions . Length - 1 ; i ++ )
141+ {
142+ using ( await _fixture . HttpClient . SendAsync ( new HttpRequestMessage ( HttpMethod . Post , $ "/streams/{ StreamId } ")
143+ {
144+ Headers =
145+ {
146+ { Constants . Headers . ExpectedVersion , $ "{ expectedVersions [ i ] } "}
147+ } ,
148+ Content = new StringContent ( JObject . FromObject ( new
149+ {
150+ messageId = Guid . NewGuid ( ) ,
151+ type = "type" ,
152+ jsonData ,
153+ jsonMetadata
154+ } ) . ToString ( ) )
155+ {
156+ Headers =
157+ {
158+ ContentType = new MediaTypeHeaderValue ( "application/json" )
159+ }
160+ }
161+ } ) )
162+ { }
163+ }
164+
165+ using ( var response = await _fixture . HttpClient . SendAsync ( new HttpRequestMessage ( HttpMethod . Post , $ "/streams/{ StreamId } ")
166+ {
167+ Headers =
168+ {
169+ { Constants . Headers . ExpectedVersion , $ "{ expectedVersions [ expectedVersions . Length - 1 ] } "}
170+ } ,
171+ Content = new StringContent ( JObject . FromObject ( new
172+ {
173+ messageId = Guid . NewGuid ( ) ,
174+ type = "type" ,
175+ jsonData ,
176+ jsonMetadata
177+ } ) . ToString ( ) )
178+ {
179+ Headers =
180+ {
181+ ContentType = new MediaTypeHeaderValue ( "application/json" )
182+ }
183+ }
184+ } ) )
185+ {
186+ response . StatusCode . ShouldBe ( HttpStatusCode . Conflict ) ;
187+ response . Content . Headers . ContentType . ShouldBe ( new MediaTypeHeaderValue (
188+ Constants . Headers . ContentTypes . ProblemDetails ) ) ;
189+ }
190+ var page = await _fixture . StreamStore . ReadStreamForwards ( StreamId , 0 , int . MaxValue ) ;
191+
192+ page . Status . ShouldBe ( PageReadStatus . Success ) ;
193+ page . Messages . Length . ShouldBe ( expectedVersions . Length - 1 ) ;
194+ }
195+
196+ public void Dispose ( ) => _fixture . Dispose ( ) ;
197+ }
198+ }
0 commit comments