-
Notifications
You must be signed in to change notification settings - Fork 2
/
MyAwesomeApplicationSmokeTest.php
191 lines (172 loc) · 8.01 KB
/
MyAwesomeApplicationSmokeTest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<?php
use JDolba\SlimHttpSmokeTesting\Configuration;
use JDolba\SlimHttpSmokeTesting\DataSetCustomizer;
use JDolba\SlimHttpSmokeTesting\RequestDataSet;
use JDolba\SlimHttpSmokeTesting\RouterAdapter\RouterAdapterInterface;
use JDolba\SlimHttpSmokeTesting\RouterAdapter\SlimRouterAdapter;
use JDolba\SlimHttpSmokeTesting\SlimApplicationHttpSmokeTestCase;
use Slim\App;
use Slim\Http\Environment;
use Slim\Http\Request;
use Slim\Http\Response;
class MyAwesomeApplicationSmokeTest extends SlimApplicationHttpSmokeTestCase
{
public static function setUpSmokeTestAndCallConfigure(): void
{
// $app = new App(); // retrieve your App with configured routes, container etc.
// TODO: be sure that App is configured for testing environment(database)
$app = self::configureAppRoutesForExamplePurpose();
self::configure(
new Configuration(
$app,
new SlimRouterAdapter($app->getContainer()->get('router'))
)
);
}
protected function customize(DataSetCustomizer $customizer): void
{
// it is important to realize, that RequestDataSet = route + method
// example: [ GET /api/user, POST /api/user ] are 2 instance of RequestDataSet
// each DataSet may have additional DataSet, which will use same Route, but different Request
$customizer
// customize callback will be applied on ALL data sets (i.e. all routes with all methods)
->customize(
function (RequestDataSet $dataSet) {
if ($dataSet->getMethod() !== 'GET') {
$dataSet->skip('We are lazy and we will smoke-test only routes which are using GET');
}
$dataSet->setAuthenticationCallback(function (Request $request) {
// here you can inject some authentication credentials into Request headers etc.
// authenticationCallback is invoked AFTER creating Request from requestPromise method
return $request;
});
}
)
// example of modifying route with named parameters (URI params)
// it will use Router implementation by your Configuration to generate uri
->customizeByRouteName(
'/api/user/find-by-id/{userId}',
function (RequestDataSet $dataSet) {
$dataSet->setUriParamsForRouter(
[
'userId' => 42, // will create /api/user/find-by-id/42
]
);
}
)
// also you can use query params and add more RequestDataSet to test same route with more data-examples
->customizeByRouteNameAndMethod(
'/api/user',
'GET',
function (RequestDataSet $dataSet) {
$dataSet->setQueryParamsForRouter(
[
'userId' => 42, // will create /api/user?userId=42
]
);
$newRequestDataSet = $dataSet->addNewExtraRequestDataSet();
// method addNewExtraRequestDataSet returns new instance of RequestDataSet so you can modify it here
// additional data sets are NOT matched by all customize* functions
$newRequestDataSet->setQueryParamsForRouter(
[
'userId' => 96, // will create another request on same route /api/user?userId=96
]
);
$newRequestDataSet->setExpectedHttpCode(404);
}
)
// more complicated example with custom request and custom condition to match RequestDataSet
->customizeByConditionCallback(
function (RequestDataSet $dataSet) {
// here you can put any condition you like to find your desired data set
return $dataSet->getMethod() === 'POST' // route is defined to accept only post
&& $dataSet->getRouteConfiguration()->getRouteName() === '/api/user';
},
function (RequestDataSet $dataSet) {
$dataSet->asNotSkipped(); // all non-GET routes were skipped by previous customization rule
// RequestDataSet is using callback to create Request and you can use your own RequestPromise
// there is only simple RequestPromise callback by default, so for complicated requests you must
// create your own Request using setRequestPromise method, for example as below:
$dataSet->setRequestPromise(
function (RouterAdapterInterface $routerAdapter, RequestDataSet $dataSet) {
$uri = $routerAdapter->generateRelativePath(
$dataSet->getRouteConfiguration(),
$dataSet->getUriParamsForRouter(),
$dataSet->getQueryParamsForRouter()
);
$env = Environment::mock(
[
'REQUEST_METHOD' => $dataSet->getMethod(),
'REQUEST_URI' => $uri,
]
);
$request = Request::createFromEnvironment($env);
// this is standard way how to mock Requests for Slim
// lets say we are POSTing data to create new user
// don't forget that Request implementation is IMMUTABLE
return $request->withParsedBody(
[
'name' => 'Johny Walker',
'email' => 'johny@wolker.com',
]
);
}
);
$newRequest = $dataSet->addNewExtraRequestDataSet();
$newRequest->setRequestPromise($dataSet->createDefaultRequestPromise());
$newRequest->setExpectedHttpCode(500);
}
);
}
/**
* will configure base routes for example application in this test
*
* @return \Slim\App $app
*/
private static function configureAppRoutesForExamplePurpose(): App
{
$app = new App([
'settings' => [
'displayErrorDetails' => true,
]
]);
$app->any(
'/',
function (Request $request, Response $response) {
return $response;
}
);
$app->get(
'/api/user/find-by-id/{userId}',
function (Request $request, Response $response, $args) {
if ($args['userId'] == 42) {
return $response->withJson(['ok']);
}
return $response->withJson(['not found'])->withStatus(404);
}
);
$app->get(
'/api/user',
function (Request $request, Response $response) {
if ($request->getQueryParam('userId') == 42) {
return $response->withJson(['ok']);
} else {
return $response->withJson(['not found'])->withStatus(404);
}
}
);
$app->post(
'/api/user',
function (Request $request, Response $response) {
if (
$request->getParam('name') === 'Johny Walker'
&& $request->getParam('email') === 'johny@wolker.com'
) {
return $response->withJson('ok');
}
throw new \RuntimeException('MyAwesomeApplication has runtime exception');
}
);
return $app;
}
}