1
1
namespace StripeTests
2
2
{
3
- using System ;
4
3
using System . IO ;
5
- using System . Linq ;
6
- using System . Net ;
7
4
using System . Net . Http ;
8
5
using System . Reflection ;
9
6
using System . Text ;
10
- using System . Threading ;
11
-
12
- using Moq ;
13
- using Moq . Protected ;
14
- using Stripe ;
7
+ using Xunit ;
15
8
9
+ [ Collection ( "stripe-mock tests" ) ]
16
10
public class BaseStripeTest
17
11
{
18
- /// <value>Minimum required version of stripe-mock</value>
19
- /// <remarks>
20
- /// If you bump this, don't forget to bump `STRIPE_MOCK_VERSION` in appveyor.yml as well.
21
- /// </remarks>
22
- private const string MockMinimumVersion = "0.39.0" ;
23
-
24
- private static Mock < HttpClientHandler > mockHandler ;
25
-
26
- private static string port ;
27
-
28
- // Lazy initializer to ensure that initialization is run only once even when running tests
29
- // in parallel.
30
- private static Lazy < object > initializer = new Lazy < object > ( InitStripeMock ) ;
31
-
32
12
public BaseStripeTest ( )
13
+ : this ( null , null )
33
14
{
34
- // This triggers the lazy initialization. We don't actually care about the value of
35
- // initialized (it will be null anyway), but simply writing `initializer.Value` is not
36
- // a valid statement in C#.
37
- var initialized = initializer . Value ;
15
+ }
38
16
39
- // Reset the mock before each test
40
- mockHandler . Invocations . Clear ( ) ;
17
+ public BaseStripeTest ( StripeMockFixture stripeMockFixture )
18
+ : this ( stripeMockFixture , null )
19
+ {
41
20
}
42
21
43
- /// <summary>
44
- /// Gets fixture data from stripe-mock for a resource expected to be at the given API path.
45
- /// stripe-mock ignores whether IDs are actually valid, so it's only important to make sure
46
- /// that the route exists, rather than the actual resource. It's common to use a symbolic
47
- /// ID stand-in like <code>ch_123</code>
48
- /// </summary>
49
- /// <param name="path">API path to use to get a fixture for stripe-mock</param>
50
- /// <returns>Fixture data encoded as JSON</returns>
51
- protected static string GetFixture ( string path )
22
+ public BaseStripeTest ( MockHttpClientFixture mockHttpClientFixture )
23
+ : this ( null , mockHttpClientFixture )
52
24
{
53
- return GetFixture ( path , null ) ;
54
25
}
55
26
56
- /// <summary>
57
- /// Gets fixture data with expansions specified. Expansions are specified the same way as
58
- /// they are in the normal API like <code>customer</code> or <code>data.customer</code>.
59
- /// Use the special <code>*</code> character to specify that all fields should be
60
- /// expanded.
61
- /// </summary>
62
- /// <param name="path">API path to use to get a fixture for stripe-mock</param>
63
- /// <param name="expansions">Set of expansions that should be applied</param>
64
- /// <returns>Fixture data encoded as JSON</returns>
65
- protected static string GetFixture ( string path , string [ ] expansions )
27
+ public BaseStripeTest ( StripeMockFixture stripeMockFixture , MockHttpClientFixture mockHttpClientFixture )
66
28
{
67
- string url = $ "http://localhost:{ port } { path } ";
29
+ this . StripeMockFixture = stripeMockFixture ;
30
+ this . MockHttpClientFixture = mockHttpClientFixture ;
68
31
69
- if ( expansions != null )
32
+ if ( this . MockHttpClientFixture != null )
70
33
{
71
- string query = string . Join ( "&" , expansions . Select ( x => $ "expand[]= { x } " ) . ToArray ( ) ) ;
72
- url += $ "? { query } " ;
34
+ // Reset the mock before each test
35
+ this . MockHttpClientFixture . Reset ( ) ;
73
36
}
37
+ }
74
38
75
- using ( HttpClient client = new HttpClient ( ) )
76
- {
77
- client . DefaultRequestHeaders . Authorization
78
- = new System . Net . Http . Headers . AuthenticationHeaderValue (
79
- "Bearer" ,
80
- "sk_test_123" ) ;
81
-
82
- HttpResponseMessage response ;
83
-
84
- try
85
- {
86
- response = client . GetAsync ( url ) . Result ;
87
- }
88
- catch ( Exception )
89
- {
90
- throw new Exception (
91
- $ "Couldn't reach stripe-mock at `localhost:{ port } `. "
92
- + "Is it running? Please see README for setup instructions." ) ;
93
- }
39
+ protected MockHttpClientFixture MockHttpClientFixture { get ; }
94
40
95
- if ( response . StatusCode != HttpStatusCode . OK )
96
- {
97
- throw new Exception (
98
- $ "stripe-mock returned status code: { response . StatusCode } .") ;
99
- }
100
-
101
- return response . Content . ReadAsStringAsync ( ) . Result ;
102
- }
103
- }
41
+ protected StripeMockFixture StripeMockFixture { get ; }
104
42
105
43
/// <summary>
106
44
/// Gets a resource file and returns its contents in a string.
@@ -110,83 +48,51 @@ protected static string GetFixture(string path, string[] expansions)
110
48
protected static string GetResourceAsString ( string path )
111
49
{
112
50
var fullpath = "StripeTests.Resources." + path ;
113
- var json = new StreamReader (
51
+ var contents = new StreamReader (
114
52
typeof ( BaseStripeTest ) . GetTypeInfo ( ) . Assembly . GetManifestResourceStream ( fullpath ) ,
115
53
Encoding . UTF8 ) . ReadToEnd ( ) ;
116
54
117
- return json ;
118
- }
119
-
120
- protected void AssertRequest ( HttpMethod method , string path )
121
- {
122
- mockHandler . Protected ( ) . Verify (
123
- "SendAsync" ,
124
- Times . Once ( ) ,
125
- ItExpr . Is < HttpRequestMessage > ( m =>
126
- m . Method == method &&
127
- m . RequestUri . AbsolutePath == path ) ,
128
- ItExpr . IsAny < CancellationToken > ( ) ) ;
55
+ return contents ;
129
56
}
130
57
131
58
/// <summary>
132
- /// Checks that stripe-mock is running and that it's a recent enough version .
59
+ /// Asserts that a single HTTP request was made with the specified method and path .
133
60
/// </summary>
134
- private static object InitStripeMock ( )
61
+ protected void AssertRequest ( HttpMethod method , string path )
135
62
{
136
- port = Environment . GetEnvironmentVariable ( "STRIPE_MOCK_PORT" ) ?? "12111" ;
137
- string url = $ "http://localhost:{ port } ";
138
-
139
- using ( HttpClient client = new HttpClient ( ) )
63
+ if ( this . MockHttpClientFixture == null )
140
64
{
141
- HttpResponseMessage response ;
142
-
143
- try
144
- {
145
- response = client . GetAsync ( url ) . Result ;
146
- }
147
- catch ( Exception )
148
- {
149
- throw new Exception (
150
- $ "Couldn't reach stripe-mock at `localhost:{ port } `. "
151
- + "Is it running? Please see README for setup instructions." ) ;
152
- }
153
-
154
- string version = response . Headers . GetValues ( "Stripe-Mock-Version" ) . FirstOrDefault ( ) ;
155
-
156
- if ( ! version . Equals ( "master" ) &&
157
- ( CompareVersions ( version , MockMinimumVersion ) > 0 ) )
158
- {
159
- throw new Exception (
160
- $ "Your version of stripe-mock ({ version } ) is too old. The minimum "
161
- + $ "version to run this test suite is { MockMinimumVersion } . Please see its "
162
- + "repository for upgrade instructions." ) ;
163
- }
65
+ throw new StripeTestException (
66
+ "AssertRequest called from a test class that doesn't have access to "
67
+ + "MockHttpClientFixture. Make sure that the constructor for "
68
+ + $ "{ this . GetType ( ) . Name } receives MockHttpClientFixture and calls the "
69
+ + "base constructor." ) ;
164
70
}
165
71
166
- StripeConfiguration . SetApiBase ( $ "http://localhost:{ port } /v1") ;
167
- StripeConfiguration . SetFilesBase ( $ "http://localhost:{ port } /v1") ;
168
- StripeConfiguration . SetApiKey ( "sk_test_123" ) ;
169
-
170
- mockHandler = new Mock < HttpClientHandler >
171
- {
172
- CallBase = true
173
- } ;
174
- StripeConfiguration . HttpMessageHandler = mockHandler . Object ;
175
-
176
- return null ;
72
+ this . MockHttpClientFixture . AssertRequest ( method , path ) ;
177
73
}
178
74
179
75
/// <summary>
180
- /// Compares two version strings.
76
+ /// Gets fixture data with expansions specified. Expansions are specified the same way as
77
+ /// they are in the normal API like <code>customer</code> or <code>data.customer</code>.
78
+ /// Use the special <code>*</code> character to specify that all fields should be
79
+ /// expanded.
181
80
/// </summary>
182
- /// <param name="a">A version string (e.g. "1.2.3"). </param>
183
- /// <param name="b">Another version string. </param>
184
- /// <returns>-1 if a > b, 1 if a < b, 0 if a == b </returns>
185
- private static int CompareVersions ( string a , string b )
81
+ /// <param name="path">API path to use to get a fixture for stripe-mock </param>
82
+ /// <param name="expansions">Set of expansions that should be applied </param>
83
+ /// <returns>Fixture data encoded as JSON </returns>
84
+ protected string GetFixture ( string path , string [ ] expansions = null )
186
85
{
187
- var version1 = new Version ( a ) ;
188
- var version2 = new Version ( b ) ;
189
- return version2 . CompareTo ( version1 ) ;
86
+ if ( this . StripeMockFixture == null )
87
+ {
88
+ throw new StripeTestException (
89
+ "GetFixture called from a test class that doesn't have access to "
90
+ + "StripeMockFixture. Make sure that the constructor for "
91
+ + $ "{ this . GetType ( ) . Name } receives StripeMockFixture and calls the "
92
+ + "base constructor." ) ;
93
+ }
94
+
95
+ return this . StripeMockFixture . GetFixture ( path , expansions ) ;
190
96
}
191
97
}
192
98
}
0 commit comments