|
@@ -1,173 +1,62 @@
|
1
|
1
|
<?php
|
2
|
2
|
|
3
|
3
|
require_once(__DIR__ . '/TestBase.php');
|
4
|
|
-require_once(__DIR__ . '/../api.php');
|
5
|
|
-
|
6
|
|
-class API
|
7
|
|
-{
|
8
|
|
- /**
|
9
|
|
- * Database configuration array
|
10
|
|
- *
|
11
|
|
- * @var array
|
12
|
|
- */
|
13
|
|
- protected $config;
|
14
|
|
-
|
15
|
|
- /**
|
16
|
|
- * @var PHP_CRUD_API_Test
|
17
|
|
- */
|
18
|
|
- protected $test;
|
19
|
|
-
|
20
|
|
- /**
|
21
|
|
- * @var PHP_CRUD_API
|
22
|
|
- */
|
23
|
|
- protected $api;
|
24
|
|
-
|
25
|
|
- public function __construct($test)
|
26
|
|
- {
|
27
|
|
- $this->test = $test;
|
28
|
|
- $this->config = $test::$config;
|
29
|
|
- $this->config['dbengine'] = $test->getEngineName();
|
30
|
|
- }
|
31
|
|
-
|
32
|
|
- private function action($method,$url,$data='')
|
33
|
|
- {
|
34
|
|
- $url = parse_url($url);
|
35
|
|
- $query = isset($url['query'])?$url['query']:'';
|
36
|
|
- parse_str($query,$get);
|
37
|
|
-
|
38
|
|
- $this->api = new PHP_CRUD_API(array(
|
39
|
|
- 'dbengine'=>$this->config['dbengine'],
|
40
|
|
- 'hostname'=>$this->config['hostname'],
|
41
|
|
- 'username'=>$this->config['username'],
|
42
|
|
- 'password'=>$this->config['password'],
|
43
|
|
- 'database'=>$this->config['database'],
|
44
|
|
- // callbacks
|
45
|
|
- 'table_authorizer'=>function($action,$database,$table) { return true; },
|
46
|
|
- 'column_authorizer'=>function($action,$database,$table,$column) { return !($column=='password'&&$action=='list'); },
|
47
|
|
- 'record_filter'=>function($action,$database,$table) { return ($table=='posts')?array('id,neq,13'):false; },
|
48
|
|
- 'tenancy_function'=>function($action,$database,$table,$column) { return ($table=='users'&&$column=='id')?1:null; },
|
49
|
|
- 'input_sanitizer'=>function($action,$database,$table,$column,$type,$value) { return is_string($value)?strip_tags($value):$value; },
|
50
|
|
- 'input_validator'=>function($action,$database,$table,$column,$type,$value,$context) { return ($column=='category_id' && !is_numeric($value))?'must be numeric':true; },
|
51
|
|
- 'before'=>function(&$action,&$database,&$table,&$id,&$input) { if ($table=='products') if ($action=='create') $input->created_at = '2013-12-11 10:09:08'; else if ($action=='delete') { $action='update'; $input = (object)array('deleted_at' => '2013-12-11 11:10:09'); } },
|
52
|
|
- 'after'=>function($action,$database,$table,$id,$input,$output) { file_put_contents('log.txt',var_export(array($action,$database,$table,$id,$input,$output),true),FILE_APPEND); },
|
53
|
|
- // for tests
|
54
|
|
- 'method'=>$method,
|
55
|
|
- 'request'=>$url['path'],
|
56
|
|
- 'post'=>$data,
|
57
|
|
- 'get'=>$get,
|
58
|
|
- ));
|
59
|
|
- return $this;
|
60
|
|
- }
|
61
|
|
-
|
62
|
|
- public function get($url)
|
63
|
|
- {
|
64
|
|
- return $this->action('GET',$url);
|
65
|
|
- }
|
66
|
|
-
|
67
|
|
- public function post($url,$data)
|
68
|
|
- {
|
69
|
|
- return $this->action('POST',$url,$data);
|
70
|
|
- }
|
71
|
|
-
|
72
|
|
- public function put($url,$data)
|
73
|
|
- {
|
74
|
|
- return $this->action('PUT',$url,$data);
|
75
|
|
- }
|
76
|
|
-
|
77
|
|
- public function delete($url)
|
78
|
|
- {
|
79
|
|
- return $this->action('DELETE',$url);
|
80
|
|
- }
|
81
|
|
-
|
82
|
|
- public function options($url)
|
83
|
|
- {
|
84
|
|
- return $this->action('OPTIONS',$url);
|
85
|
|
- }
|
86
|
|
-
|
87
|
|
- public function patch($url,$data)
|
88
|
|
- {
|
89
|
|
- return $this->action('PATCH',$url,$data);
|
90
|
|
- }
|
91
|
|
-
|
92
|
|
- public function expectAny()
|
93
|
|
- {
|
94
|
|
- ob_start();
|
95
|
|
- $this->api->executeCommand();
|
96
|
|
- ob_end_clean();
|
97
|
|
- return $this;
|
98
|
|
- }
|
99
|
|
-
|
100
|
|
- public function expect($output,$error=false)
|
101
|
|
- {
|
102
|
|
- $exception = false;
|
103
|
|
- ob_start();
|
104
|
|
- try {
|
105
|
|
- $this->api->executeCommand();
|
106
|
|
- } catch (\Exception $e) {
|
107
|
|
- $exception = $e->getMessage();
|
108
|
|
- }
|
109
|
|
- $data = ob_get_contents();
|
110
|
|
- ob_end_clean();
|
111
|
|
- if ($exception) $this->test->assertEquals($error, $exception);
|
112
|
|
- else $this->test->assertEquals($output, $data);
|
113
|
|
- return $this;
|
114
|
|
- }
|
115
|
|
-}
|
|
4
|
+require_once(__DIR__ . '/Api.php');
|
116
|
5
|
|
117
|
6
|
abstract class Tests extends TestBase
|
118
|
7
|
{
|
119
|
8
|
public function testListPosts()
|
120
|
9
|
{
|
121
|
|
- $test = new API($this);
|
|
10
|
+ $test = new Api($this);
|
122
|
11
|
$test->get('/posts');
|
123
|
12
|
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"],[2,1,2,"It works!"]]}}');
|
124
|
13
|
}
|
125
|
14
|
|
126
|
15
|
public function testListPostColumns()
|
127
|
16
|
{
|
128
|
|
- $test = new API($this);
|
|
17
|
+ $test = new Api($this);
|
129
|
18
|
$test->get('/posts?columns=id,content');
|
130
|
19
|
$test->expect('{"posts":{"columns":["id","content"],"records":[[1,"blog started"],[2,"It works!"]]}}');
|
131
|
20
|
}
|
132
|
21
|
|
133
|
22
|
public function testListPostsWithTransform()
|
134
|
23
|
{
|
135
|
|
- $test = new API($this);
|
|
24
|
+ $test = new Api($this);
|
136
|
25
|
$test->get('/posts?transform=1');
|
137
|
26
|
$test->expect('{"posts":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":2,"user_id":1,"category_id":2,"content":"It works!"}]}');
|
138
|
27
|
}
|
139
|
28
|
|
140
|
29
|
public function testReadPost()
|
141
|
30
|
{
|
142
|
|
- $test = new API($this);
|
|
31
|
+ $test = new Api($this);
|
143
|
32
|
$test->get('/posts/2');
|
144
|
33
|
$test->expect('{"id":2,"user_id":1,"category_id":2,"content":"It works!"}');
|
145
|
34
|
}
|
146
|
35
|
|
147
|
36
|
public function testReadPosts()
|
148
|
37
|
{
|
149
|
|
- $test = new API($this);
|
|
38
|
+ $test = new Api($this);
|
150
|
39
|
$test->get('/posts/1,2');
|
151
|
40
|
$test->expect('[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":2,"user_id":1,"category_id":2,"content":"It works!"}]');
|
152
|
41
|
}
|
153
|
42
|
|
154
|
43
|
public function testReadPostColumns()
|
155
|
44
|
{
|
156
|
|
- $test = new API($this);
|
|
45
|
+ $test = new Api($this);
|
157
|
46
|
$test->get('/posts/2?columns=id,content');
|
158
|
47
|
$test->expect('{"id":2,"content":"It works!"}');
|
159
|
48
|
}
|
160
|
49
|
|
161
|
50
|
public function testAddPost()
|
162
|
51
|
{
|
163
|
|
- $test = new API($this);
|
|
52
|
+ $test = new Api($this);
|
164
|
53
|
$test->post('/posts','{"user_id":1,"category_id":1,"content":"test"}');
|
165
|
54
|
$test->expect('3');
|
166
|
55
|
}
|
167
|
56
|
|
168
|
57
|
public function testEditPost()
|
169
|
58
|
{
|
170
|
|
- $test = new API($this);
|
|
59
|
+ $test = new Api($this);
|
171
|
60
|
$test->put('/posts/3','{"user_id":1,"category_id":1,"content":"test (edited)"}');
|
172
|
61
|
$test->expect('1');
|
173
|
62
|
$test->get('/posts/3');
|
|
@@ -176,7 +65,7 @@ abstract class Tests extends TestBase
|
176
|
65
|
|
177
|
66
|
public function testEditPostColumnsMissingField()
|
178
|
67
|
{
|
179
|
|
- $test = new API($this);
|
|
68
|
+ $test = new Api($this);
|
180
|
69
|
$test->put('/posts/3?columns=id,content','{"content":"test (edited 2)"}');
|
181
|
70
|
$test->expect('1');
|
182
|
71
|
$test->get('/posts/3');
|
|
@@ -185,7 +74,7 @@ abstract class Tests extends TestBase
|
185
|
74
|
|
186
|
75
|
public function testEditPostColumnsExtraField()
|
187
|
76
|
{
|
188
|
|
- $test = new API($this);
|
|
77
|
+ $test = new Api($this);
|
189
|
78
|
$test->put('/posts/3?columns=id,content','{"user_id":2,"content":"test (edited 3)"}');
|
190
|
79
|
$test->expect('1');
|
191
|
80
|
$test->get('/posts/3');
|
|
@@ -195,7 +84,7 @@ abstract class Tests extends TestBase
|
195
|
84
|
public function testEditPostWithUtf8Content()
|
196
|
85
|
{
|
197
|
86
|
$utf8 = json_encode('Hello world, Καλημέρα κόσμε, コンニチハ');
|
198
|
|
- $test = new API($this);
|
|
87
|
+ $test = new Api($this);
|
199
|
88
|
$test->put('/posts/2','{"content":'.$utf8.'}');
|
200
|
89
|
$test->expect('1');
|
201
|
90
|
$test->get('/posts/2');
|
|
@@ -207,7 +96,7 @@ abstract class Tests extends TestBase
|
207
|
96
|
$utf8 = '€ Hello world, Καλημέρα κόσμε, コンニチハ';
|
208
|
97
|
$url_encoded = urlencode($utf8);
|
209
|
98
|
$json_encoded = json_encode($utf8);
|
210
|
|
- $test = new API($this);
|
|
99
|
+ $test = new Api($this);
|
211
|
100
|
$test->put('/posts/2','content='.$url_encoded);
|
212
|
101
|
$test->expect('1');
|
213
|
102
|
$test->get('/posts/2');
|
|
@@ -216,7 +105,7 @@ abstract class Tests extends TestBase
|
216
|
105
|
|
217
|
106
|
public function testDeletePost()
|
218
|
107
|
{
|
219
|
|
- $test = new API($this);
|
|
108
|
+ $test = new Api($this);
|
220
|
109
|
$test->delete('/posts/3');
|
221
|
110
|
$test->expect('1');
|
222
|
111
|
$test->get('/posts/3');
|
|
@@ -225,14 +114,14 @@ abstract class Tests extends TestBase
|
225
|
114
|
|
226
|
115
|
public function testAddPostWithPost()
|
227
|
116
|
{
|
228
|
|
- $test = new API($this);
|
|
117
|
+ $test = new Api($this);
|
229
|
118
|
$test->post('/posts','user_id=1&category_id=1&content=test');
|
230
|
119
|
$test->expect('4');
|
231
|
120
|
}
|
232
|
121
|
|
233
|
122
|
public function testEditPostWithPost()
|
234
|
123
|
{
|
235
|
|
- $test = new API($this);
|
|
124
|
+ $test = new Api($this);
|
236
|
125
|
$test->put('/posts/4','user_id=1&category_id=1&content=test+(edited)');
|
237
|
126
|
$test->expect('1');
|
238
|
127
|
$test->get('/posts/4');
|
|
@@ -241,7 +130,7 @@ abstract class Tests extends TestBase
|
241
|
130
|
|
242
|
131
|
public function testDeletePostWithPost()
|
243
|
132
|
{
|
244
|
|
- $test = new API($this);
|
|
133
|
+ $test = new Api($this);
|
245
|
134
|
$test->delete('/posts/4');
|
246
|
135
|
$test->expect('1');
|
247
|
136
|
$test->get('/posts/4');
|
|
@@ -250,7 +139,7 @@ abstract class Tests extends TestBase
|
250
|
139
|
|
251
|
140
|
public function testListWithPaginate()
|
252
|
141
|
{
|
253
|
|
- $test = new API($this);
|
|
142
|
+ $test = new Api($this);
|
254
|
143
|
for ($i=1;$i<=10;$i++) {
|
255
|
144
|
$test->post('/posts','{"user_id":1,"category_id":1,"content":"#'.$i.'"}');
|
256
|
145
|
$test->expect(4+$i);
|
|
@@ -261,56 +150,56 @@ abstract class Tests extends TestBase
|
261
|
150
|
|
262
|
151
|
public function testListWithPaginateInMultipleOrder()
|
263
|
152
|
{
|
264
|
|
- $test = new API($this);
|
|
153
|
+ $test = new Api($this);
|
265
|
154
|
$test->get('/posts?page=1,2&order[]=category_id,asc&order[]=id,desc');
|
266
|
155
|
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[14,1,1,"#10"],[12,1,1,"#8"]],"results":11}}');
|
267
|
156
|
}
|
268
|
157
|
|
269
|
158
|
public function testListWithPaginateInDescendingOrder()
|
270
|
159
|
{
|
271
|
|
- $test = new API($this);
|
|
160
|
+ $test = new Api($this);
|
272
|
161
|
$test->get('/posts?page=2,2&order=id,desc');
|
273
|
162
|
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[11,1,1,"#7"],[10,1,1,"#6"]],"results":11}}');
|
274
|
163
|
}
|
275
|
164
|
|
276
|
165
|
public function testListWithPaginateLastPage()
|
277
|
166
|
{
|
278
|
|
- $test = new API($this);
|
|
167
|
+ $test = new Api($this);
|
279
|
168
|
$test->get('/posts?page=3,5&order=id');
|
280
|
169
|
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[14,1,1,"#10"]],"results":11}}');
|
281
|
170
|
}
|
282
|
171
|
|
283
|
172
|
public function testListExampleFromReadmeFullRecord()
|
284
|
173
|
{
|
285
|
|
- $test = new API($this);
|
|
174
|
+ $test = new Api($this);
|
286
|
175
|
$test->get('/posts?filter=id,eq,1');
|
287
|
176
|
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"]]}}');
|
288
|
177
|
}
|
289
|
178
|
|
290
|
179
|
public function testListExampleFromReadmeWithExclude()
|
291
|
180
|
{
|
292
|
|
- $test = new API($this);
|
|
181
|
+ $test = new Api($this);
|
293
|
182
|
$test->get('/posts?exclude=id&filter=id,eq,1');
|
294
|
183
|
$test->expect('{"posts":{"columns":["user_id","category_id","content"],"records":[[1,1,"blog started"]]}}');
|
295
|
184
|
}
|
296
|
185
|
|
297
|
186
|
public function testListExampleFromReadme()
|
298
|
187
|
{
|
299
|
|
- $test = new API($this);
|
|
188
|
+ $test = new Api($this);
|
300
|
189
|
$test->get('/posts?include=categories,tags,comments&filter=id,eq,1');
|
301
|
190
|
$test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"]]},"post_tags":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","tag_id"],"records":[[1,1,1],[2,1,2]]},"categories":{"relations":{"id":"posts.category_id"},"columns":["id","name","icon"],"records":[[1,"announcement",null]]},"tags":{"relations":{"id":"post_tags.tag_id"},"columns":["id","name"],"records":[[1,"funny"],[2,"important"]]},"comments":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","message"],"records":[[1,1,"great"],[2,1,"fantastic"]]}}');
|
302
|
191
|
}
|
303
|
192
|
|
304
|
193
|
public function testListExampleFromReadmeWithTransform()
|
305
|
194
|
{
|
306
|
|
- $test = new API($this);
|
|
195
|
+ $test = new Api($this);
|
307
|
196
|
$test->get('/posts?include=categories,tags,comments&filter=id,eq,1&transform=1');
|
308
|
197
|
$test->expect('{"posts":[{"id":1,"post_tags":[{"id":1,"post_id":1,"tag_id":1,"tags":[{"id":1,"name":"funny"}]},{"id":2,"post_id":1,"tag_id":2,"tags":[{"id":2,"name":"important"}]}],"comments":[{"id":1,"post_id":1,"message":"great"},{"id":2,"post_id":1,"message":"fantastic"}],"user_id":1,"category_id":1,"categories":[{"id":1,"name":"announcement","icon":null}],"content":"blog started"}]}');
|
309
|
198
|
}
|
310
|
199
|
|
311
|
200
|
public function testListExampleFromReadmeWithTransformWithExclude()
|
312
|
201
|
{
|
313
|
|
- $test = new API($this);
|
|
202
|
+ $test = new Api($this);
|
314
|
203
|
$test->get('/posts?include=categories,tags,comments&exclude=comments.message&filter=id,eq,1&transform=1');
|
315
|
204
|
$test->expect('{"posts":[{"id":1,"post_tags":[{"id":1,"post_id":1,"tag_id":1,"tags":[{"id":1,"name":"funny"}]},{"id":2,"post_id":1,"tag_id":2,"tags":[{"id":2,"name":"important"}]}],"comments":[{"id":1,"post_id":1},{"id":2,"post_id":1}],"user_id":1,"category_id":1,"categories":[{"id":1,"name":"announcement","icon":null}],"content":"blog started"}]}');
|
316
|
205
|
}
|
|
@@ -319,7 +208,7 @@ abstract class Tests extends TestBase
|
319
|
208
|
{
|
320
|
209
|
$binary = base64_encode("\0abc\0\n\r\b\0");
|
321
|
210
|
$base64url = rtrim(strtr($binary, '+/', '-_'), '=');
|
322
|
|
- $test = new API($this);
|
|
211
|
+ $test = new Api($this);
|
323
|
212
|
$test->put('/categories/2','{"icon":"'.$base64url.'"}');
|
324
|
213
|
$test->expect('1');
|
325
|
214
|
$test->get('/categories/2');
|
|
@@ -328,7 +217,7 @@ abstract class Tests extends TestBase
|
328
|
217
|
|
329
|
218
|
public function testEditCategoryWithNull()
|
330
|
219
|
{
|
331
|
|
- $test = new API($this);
|
|
220
|
+ $test = new Api($this);
|
332
|
221
|
$test->put('/categories/2','{"icon":null}');
|
333
|
222
|
$test->expect('1');
|
334
|
223
|
$test->get('/categories/2');
|
|
@@ -339,7 +228,7 @@ abstract class Tests extends TestBase
|
339
|
228
|
{
|
340
|
229
|
$binary = base64_encode("€ \0abc\0\n\r\b\0");
|
341
|
230
|
$base64url = rtrim(strtr($binary, '+/', '-_'), '=');
|
342
|
|
- $test = new API($this);
|
|
231
|
+ $test = new Api($this);
|
343
|
232
|
$test->put('/categories/2','icon='.$base64url);
|
344
|
233
|
$test->expect('1');
|
345
|
234
|
$test->get('/categories/2');
|
|
@@ -348,14 +237,14 @@ abstract class Tests extends TestBase
|
348
|
237
|
|
349
|
238
|
public function testListCategoriesWithBinaryContent()
|
350
|
239
|
{
|
351
|
|
- $test = new API($this);
|
|
240
|
+ $test = new Api($this);
|
352
|
241
|
$test->get('/categories');
|
353
|
242
|
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[[1,"announcement",null],[2,"article","4oKsIABhYmMACg1cYgA="]]}}');
|
354
|
243
|
}
|
355
|
244
|
|
356
|
245
|
public function testEditCategoryWithNullWithPost()
|
357
|
246
|
{
|
358
|
|
- $test = new API($this);
|
|
247
|
+ $test = new Api($this);
|
359
|
248
|
$test->put('/categories/2','icon__is_null');
|
360
|
249
|
$test->expect('1');
|
361
|
250
|
$test->get('/categories/2');
|
|
@@ -364,35 +253,35 @@ abstract class Tests extends TestBase
|
364
|
253
|
|
365
|
254
|
public function testAddPostFailure()
|
366
|
255
|
{
|
367
|
|
- $test = new API($this);
|
|
256
|
+ $test = new Api($this);
|
368
|
257
|
$test->post('/posts','{"user_id":"a","category_id":1,"content":"tests"}');
|
369
|
258
|
$test->expect('null');
|
370
|
259
|
}
|
371
|
260
|
|
372
|
261
|
public function testOptionsRequest()
|
373
|
262
|
{
|
374
|
|
- $test = new API($this);
|
|
263
|
+ $test = new Api($this);
|
375
|
264
|
$test->options('/posts/2');
|
376
|
265
|
$test->expect('["Access-Control-Allow-Headers: Content-Type, X-XSRF-TOKEN","Access-Control-Allow-Methods: OPTIONS, GET, PUT, POST, DELETE, PATCH","Access-Control-Allow-Credentials: true","Access-Control-Max-Age: 1728000"]',false);
|
377
|
266
|
}
|
378
|
267
|
|
379
|
268
|
public function testHidingPasswordColumn()
|
380
|
269
|
{
|
381
|
|
- $test = new API($this);
|
|
270
|
+ $test = new Api($this);
|
382
|
271
|
$test->get('/users?filter=id,eq,1&transform=1');
|
383
|
272
|
$test->expect('{"users":[{"id":1,"username":"user1","location":null}]}');
|
384
|
273
|
}
|
385
|
274
|
|
386
|
275
|
public function testValidatorErrorMessage()
|
387
|
276
|
{
|
388
|
|
- $test = new API($this);
|
|
277
|
+ $test = new Api($this);
|
389
|
278
|
$test->put('/posts/1','{"category_id":"a"}');
|
390
|
279
|
$test->expect(false,'{"category_id":"must be numeric"}');
|
391
|
280
|
}
|
392
|
281
|
|
393
|
282
|
public function testSanitizerToStripTags()
|
394
|
283
|
{
|
395
|
|
- $test = new API($this);
|
|
284
|
+ $test = new Api($this);
|
396
|
285
|
$test->put('/categories/2','{"name":"<script>alert();</script>"}');
|
397
|
286
|
$test->expect('1');
|
398
|
287
|
$test->get('/categories/2');
|
|
@@ -401,42 +290,42 @@ abstract class Tests extends TestBase
|
401
|
290
|
|
402
|
291
|
public function testErrorOnInvalidJson()
|
403
|
292
|
{
|
404
|
|
- $test = new API($this);
|
|
293
|
+ $test = new Api($this);
|
405
|
294
|
$test->post('/posts','{"}');
|
406
|
295
|
$test->expect(false,'Not found (input)');
|
407
|
296
|
}
|
408
|
297
|
|
409
|
298
|
public function testErrorOnDuplicatePrimaryKey()
|
410
|
299
|
{
|
411
|
|
- $test = new API($this);
|
|
300
|
+ $test = new Api($this);
|
412
|
301
|
$test->post('/posts','{"id":1,"user_id":1,"category_id":1,"content":"blog started (duplicate)"}');
|
413
|
302
|
$test->expect('null');
|
414
|
303
|
}
|
415
|
304
|
|
416
|
305
|
public function testErrorOnFailingForeignKeyConstraint()
|
417
|
306
|
{
|
418
|
|
- $test = new API($this);
|
|
307
|
+ $test = new Api($this);
|
419
|
308
|
$test->post('/posts','{"user_id":3,"category_id":1,"content":"fk constraint"}');
|
420
|
309
|
$test->expect('null');
|
421
|
310
|
}
|
422
|
311
|
|
423
|
312
|
public function testMissingIntermediateTable()
|
424
|
313
|
{
|
425
|
|
- $test = new API($this);
|
|
314
|
+ $test = new Api($this);
|
426
|
315
|
$test->get('/users?include=posts,tags');
|
427
|
316
|
$test->expect('{"users":{"columns":["id","username","location"],"records":[[1,"user1",null]]},"posts":{"relations":{"user_id":"users.id"},"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"],[2,1,2,"\u20ac Hello world, \u039a\u03b1\u03bb\u03b7\u03bc\u1f73\u03c1\u03b1 \u03ba\u1f79\u03c3\u03bc\u03b5, \u30b3\u30f3\u30cb\u30c1\u30cf"],[5,1,1,"#1"],[6,1,1,"#2"],[7,1,1,"#3"],[8,1,1,"#4"],[9,1,1,"#5"],[10,1,1,"#6"],[11,1,1,"#7"],[12,1,1,"#8"],[14,1,1,"#10"]]},"post_tags":{"relations":{"post_id":"posts.id"},"columns":["id","post_id","tag_id"],"records":[[1,1,1],[2,1,2],[3,2,1],[4,2,2]]},"tags":{"relations":{"id":"post_tags.tag_id"},"columns":["id","name"],"records":[[1,"funny"],[2,"important"]]}}');
|
428
|
317
|
}
|
429
|
318
|
|
430
|
319
|
public function testEditUserPassword()
|
431
|
320
|
{
|
432
|
|
- $test = new API($this);
|
|
321
|
+ $test = new Api($this);
|
433
|
322
|
$test->put('/users/1','{"password":"testtest"}');
|
434
|
323
|
$test->expect('1');
|
435
|
324
|
}
|
436
|
325
|
|
437
|
326
|
public function testEditUserLocation()
|
438
|
327
|
{
|
439
|
|
- $test = new API($this);
|
|
328
|
+ $test = new Api($this);
|
440
|
329
|
$test->put('/users/1','{"location":"POINT(30 20)"}');
|
441
|
330
|
$test->expect('1');
|
442
|
331
|
$test->get('/users/1?columns=id,location');
|
|
@@ -449,7 +338,7 @@ abstract class Tests extends TestBase
|
449
|
338
|
|
450
|
339
|
public function testListUserLocations()
|
451
|
340
|
{
|
452
|
|
- $test = new API($this);
|
|
341
|
+ $test = new Api($this);
|
453
|
342
|
$test->get('/users?columns=id,location');
|
454
|
343
|
if ($this->getEngineName()=='SQLServer') {
|
455
|
344
|
$test->expect('{"users":{"columns":["id","location"],"records":[[1,"POINT (30 20)"]]}}');
|
|
@@ -461,7 +350,7 @@ abstract class Tests extends TestBase
|
461
|
350
|
public function testEditUserWithId()
|
462
|
351
|
{
|
463
|
352
|
if ($this->getEngineName()!='SQLServer') {
|
464
|
|
- $test = new API($this);
|
|
353
|
+ $test = new Api($this);
|
465
|
354
|
$test->put('/users/1','{"id":2,"password":"testtest2"}');
|
466
|
355
|
$test->expect('1');
|
467
|
356
|
$test->get('/users/1?columns=id,username,password');
|
|
@@ -471,98 +360,98 @@ abstract class Tests extends TestBase
|
471
|
360
|
|
472
|
361
|
public function testReadOtherUser()
|
473
|
362
|
{
|
474
|
|
- $test = new API($this);
|
|
363
|
+ $test = new Api($this);
|
475
|
364
|
$test->get('/users/2');
|
476
|
365
|
$test->expect(false,'Not found (object)');
|
477
|
366
|
}
|
478
|
367
|
|
479
|
368
|
public function testEditOtherUser()
|
480
|
369
|
{
|
481
|
|
- $test = new API($this);
|
|
370
|
+ $test = new Api($this);
|
482
|
371
|
$test->put('/users/2','{"password":"testtest"}');
|
483
|
372
|
$test->expect('0');
|
484
|
373
|
}
|
485
|
374
|
|
486
|
375
|
public function testFilterCategoryOnNullIcon()
|
487
|
376
|
{
|
488
|
|
- $test = new API($this);
|
|
377
|
+ $test = new Api($this);
|
489
|
378
|
$test->get('/categories?filter[]=icon,is,null&transform=1');
|
490
|
379
|
$test->expect('{"categories":[{"id":1,"name":"announcement","icon":null},{"id":2,"name":"alert();","icon":null}]}');
|
491
|
380
|
}
|
492
|
381
|
|
493
|
382
|
public function testFilterCategoryOnNotNullIcon()
|
494
|
383
|
{
|
495
|
|
- $test = new API($this);
|
|
384
|
+ $test = new Api($this);
|
496
|
385
|
$test->get('/categories?filter[]=icon,nis,null&transform=1');
|
497
|
386
|
$test->expect('{"categories":[]}');
|
498
|
387
|
}
|
499
|
388
|
|
500
|
389
|
public function testFilterPostsNotIn()
|
501
|
390
|
{
|
502
|
|
- $test = new API($this);
|
|
391
|
+ $test = new Api($this);
|
503
|
392
|
$test->get('/posts?filter[]=id,nin,1,2,3,4,7,8,9,10,11,12,13,14&transform=1');
|
504
|
393
|
$test->expect('{"posts":[{"id":5,"user_id":1,"category_id":1,"content":"#1"},{"id":6,"user_id":1,"category_id":1,"content":"#2"}]}');
|
505
|
394
|
}
|
506
|
395
|
|
507
|
396
|
public function testFilterPostsBetween()
|
508
|
397
|
{
|
509
|
|
- $test = new API($this);
|
|
398
|
+ $test = new Api($this);
|
510
|
399
|
$test->get('/posts?filter[]=id,bt,5,6&transform=1');
|
511
|
400
|
$test->expect('{"posts":[{"id":5,"user_id":1,"category_id":1,"content":"#1"},{"id":6,"user_id":1,"category_id":1,"content":"#2"}]}');
|
512
|
401
|
}
|
513
|
402
|
|
514
|
403
|
public function testFilterPostsNotBetween()
|
515
|
404
|
{
|
516
|
|
- $test = new API($this);
|
|
405
|
+ $test = new Api($this);
|
517
|
406
|
$test->get('/posts?filter[]=id,nbt,2,13&transform=1');
|
518
|
407
|
$test->expect('{"posts":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":14,"user_id":1,"category_id":1,"content":"#10"}]}');
|
519
|
408
|
}
|
520
|
409
|
|
521
|
410
|
public function testColumnsWithTable()
|
522
|
411
|
{
|
523
|
|
- $test = new API($this);
|
|
412
|
+ $test = new Api($this);
|
524
|
413
|
$test->get('/posts?columns=posts.content&filter=id,eq,1&transform=1');
|
525
|
414
|
$test->expect('{"posts":[{"content":"blog started"}]}');
|
526
|
415
|
}
|
527
|
416
|
|
528
|
417
|
public function testColumnsWithTableWildcard()
|
529
|
418
|
{
|
530
|
|
- $test = new API($this);
|
|
419
|
+ $test = new Api($this);
|
531
|
420
|
$test->get('/posts?columns=posts.*&filter=id,eq,1&transform=1');
|
532
|
421
|
$test->expect('{"posts":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"}]}');
|
533
|
422
|
}
|
534
|
423
|
|
535
|
424
|
public function testColumnsOnInclude()
|
536
|
425
|
{
|
537
|
|
- $test = new API($this);
|
|
426
|
+ $test = new Api($this);
|
538
|
427
|
$test->get('/posts?include=categories&columns=categories.name&filter=id,eq,1&transform=1');
|
539
|
428
|
$test->expect('{"posts":[{"category_id":1,"categories":[{"id":1,"name":"announcement"}]}]}');
|
540
|
429
|
}
|
541
|
430
|
|
542
|
431
|
public function testFilterOnRelationAnd()
|
543
|
432
|
{
|
544
|
|
- $test = new API($this);
|
|
433
|
+ $test = new Api($this);
|
545
|
434
|
$test->get('/categories?include=posts&filter[]=id,ge,1&filter[]=id,le,1&filter[]=id,le,2&filter[]=posts.id,lt,8&filter[]=posts.id,gt,4');
|
546
|
435
|
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[[1,"announcement",null]]},"posts":{"relations":{"category_id":"categories.id"},"columns":["id","user_id","category_id","content"],"records":[[5,1,1,"#1"],[6,1,1,"#2"],[7,1,1,"#3"]]}}');
|
547
|
436
|
}
|
548
|
437
|
|
549
|
438
|
public function testFilterOnRelationOr()
|
550
|
439
|
{
|
551
|
|
- $test = new API($this);
|
|
440
|
+ $test = new Api($this);
|
552
|
441
|
$test->get('/categories?include=posts&filter[]=id,ge,1&filter[]=id,le,1&filter[]=posts.id,eq,5&filter[]=posts.id,eq,6&filter[]=posts.id,eq,7&satisfy=all,posts.any');
|
553
|
442
|
$test->expect('{"categories":{"columns":["id","name","icon"],"records":[[1,"announcement",null]]},"posts":{"relations":{"category_id":"categories.id"},"columns":["id","user_id","category_id","content"],"records":[[5,1,1,"#1"],[6,1,1,"#2"],[7,1,1,"#3"]]}}');
|
554
|
443
|
}
|
555
|
444
|
|
556
|
445
|
public function testColumnsOnWrongInclude()
|
557
|
446
|
{
|
558
|
|
- $test = new API($this);
|
|
447
|
+ $test = new Api($this);
|
559
|
448
|
$test->get('/posts?include=categories&columns=categories&filter=id,eq,1&transform=1');
|
560
|
449
|
$test->expect('{"posts":[{"category_id":1,"categories":[{"id":1}]}]}');
|
561
|
450
|
}
|
562
|
451
|
|
563
|
452
|
public function testColumnsOnImplicitJoin()
|
564
|
453
|
{
|
565
|
|
- $test = new API($this);
|
|
454
|
+ $test = new Api($this);
|
566
|
455
|
$test->get('/posts?include=tags&columns=posts.id,tags.name&filter=id,eq,1&transform=1');
|
567
|
456
|
$test->expect('{"posts":[{"id":1,"post_tags":[{"post_id":1,"tag_id":1,"tags":[{"id":1,"name":"funny"}]},{"post_id":1,"tag_id":2,"tags":[{"id":2,"name":"important"}]}]}]}');
|
568
|
457
|
}
|
|
@@ -570,7 +459,7 @@ abstract class Tests extends TestBase
|
570
|
459
|
public function testSpatialFilterWithin()
|
571
|
460
|
{
|
572
|
461
|
if (static::$capabilities & self::GIS) {
|
573
|
|
- $test = new API($this);
|
|
462
|
+ $test = new Api($this);
|
574
|
463
|
$test->get('/users?columns=id,username&filter=location,swi,POINT(30 20)');
|
575
|
464
|
$test->expect('{"users":{"columns":["id","username"],"records":[[1,"user1"]]}}');
|
576
|
465
|
}
|
|
@@ -578,7 +467,7 @@ abstract class Tests extends TestBase
|
578
|
467
|
|
579
|
468
|
public function testAddPostsWithNonExistingCategory()
|
580
|
469
|
{
|
581
|
|
- $test = new API($this);
|
|
470
|
+ $test = new Api($this);
|
582
|
471
|
$test->post('/posts','[{"user_id":1,"category_id":1,"content":"tests"},{"user_id":1,"category_id":15,"content":"tests"}]');
|
583
|
472
|
$test->expect('null');
|
584
|
473
|
$test->get('/posts?columns=content&filter=content,eq,tests');
|
|
@@ -587,7 +476,7 @@ abstract class Tests extends TestBase
|
587
|
476
|
|
588
|
477
|
public function testAddPosts()
|
589
|
478
|
{
|
590
|
|
- $test = new API($this);
|
|
479
|
+ $test = new Api($this);
|
591
|
480
|
$test->post('/posts','[{"user_id":1,"category_id":1,"content":"tests"},{"user_id":1,"category_id":1,"content":"tests"}]');
|
592
|
481
|
$test->expectAny();
|
593
|
482
|
$test->get('/posts?columns=content&filter=content,eq,tests');
|
|
@@ -596,14 +485,14 @@ abstract class Tests extends TestBase
|
596
|
485
|
|
597
|
486
|
public function testListEvents()
|
598
|
487
|
{
|
599
|
|
- $test = new API($this);
|
|
488
|
+ $test = new Api($this);
|
600
|
489
|
$test->get('/events?columns=datetime');
|
601
|
490
|
$test->expect('{"events":{"columns":["datetime"],"records":[["2016-01-01 13:01:01"]]}}');
|
602
|
491
|
}
|
603
|
492
|
|
604
|
493
|
public function testIncrementEventVisitors()
|
605
|
494
|
{
|
606
|
|
- $test = new API($this);
|
|
495
|
+ $test = new Api($this);
|
607
|
496
|
$test->patch('/events/1','{"visitors":11}');
|
608
|
497
|
$test->expect('1');
|
609
|
498
|
$test->get('/events/1');
|
|
@@ -612,7 +501,7 @@ abstract class Tests extends TestBase
|
612
|
501
|
|
613
|
502
|
public function testIncrementEventVisitorsWithZero()
|
614
|
503
|
{
|
615
|
|
- $test = new API($this);
|
|
504
|
+ $test = new Api($this);
|
616
|
505
|
$test->patch('/events/1','{"visitors":0}');
|
617
|
506
|
$test->expect('1');
|
618
|
507
|
$test->get('/events/1');
|
|
@@ -621,7 +510,7 @@ abstract class Tests extends TestBase
|
621
|
510
|
|
622
|
511
|
public function testDecrementEventVisitors()
|
623
|
512
|
{
|
624
|
|
- $test = new API($this);
|
|
513
|
+ $test = new Api($this);
|
625
|
514
|
$test->patch('/events/1','{"visitors":-5}');
|
626
|
515
|
$test->expect('1');
|
627
|
516
|
$test->get('/events/1');
|
|
@@ -630,14 +519,14 @@ abstract class Tests extends TestBase
|
630
|
519
|
|
631
|
520
|
public function testListTagUsage()
|
632
|
521
|
{
|
633
|
|
- $test = new API($this);
|
|
522
|
+ $test = new Api($this);
|
634
|
523
|
$test->get('/tag_usage');
|
635
|
524
|
$test->expect('{"tag_usage":{"columns":["name","count"],"records":[["funny",2],["important",2]]}}');
|
636
|
525
|
}
|
637
|
526
|
|
638
|
527
|
public function testUpdateMultipleTags()
|
639
|
528
|
{
|
640
|
|
- $test = new API($this);
|
|
529
|
+ $test = new Api($this);
|
641
|
530
|
$test->get('/tags?transform=1');
|
642
|
531
|
$test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
|
643
|
532
|
$test->put('/tags/1,2','[{"name":"funny"},{"name":"important"}]');
|
|
@@ -646,7 +535,7 @@ abstract class Tests extends TestBase
|
646
|
535
|
|
647
|
536
|
public function testUpdateMultipleTagsTooManyIds()
|
648
|
537
|
{
|
649
|
|
- $test = new API($this);
|
|
538
|
+ $test = new Api($this);
|
650
|
539
|
$test->put('/tags/1,2,3','[{"name":"funny!!!"},{"name":"important"}]');
|
651
|
540
|
$test->expect(false,'Not found (subject)');
|
652
|
541
|
$test->get('/tags?transform=1');
|
|
@@ -655,7 +544,7 @@ abstract class Tests extends TestBase
|
655
|
544
|
|
656
|
545
|
public function testUpdateMultipleTagsWithoutFields()
|
657
|
546
|
{
|
658
|
|
- $test = new API($this);
|
|
547
|
+ $test = new Api($this);
|
659
|
548
|
$test->put('/tags/1,2','[{"name":"funny!!!"},{}]');
|
660
|
549
|
$test->expect('null');
|
661
|
550
|
$test->get('/tags?transform=1');
|
|
@@ -664,7 +553,7 @@ abstract class Tests extends TestBase
|
664
|
553
|
|
665
|
554
|
public function testDeleteMultipleTags()
|
666
|
555
|
{
|
667
|
|
- $test = new API($this);
|
|
556
|
+ $test = new Api($this);
|
668
|
557
|
$test->post('/tags','[{"name":"extra"},{"name":"more"}]');
|
669
|
558
|
$test->expect('[3,4]');
|
670
|
559
|
$test->delete('/tags/3,4');
|
|
@@ -675,14 +564,14 @@ abstract class Tests extends TestBase
|
675
|
564
|
|
676
|
565
|
public function testListProducts()
|
677
|
566
|
{
|
678
|
|
- $test = new API($this);
|
|
567
|
+ $test = new Api($this);
|
679
|
568
|
$test->get('/products?columns=id,name,price&transform=1');
|
680
|
569
|
$test->expect('{"products":[{"id":1,"name":"Calculator","price":"23.01"}]}');
|
681
|
570
|
}
|
682
|
571
|
|
683
|
572
|
public function testListProductsProperties()
|
684
|
573
|
{
|
685
|
|
- $test = new API($this);
|
|
574
|
+ $test = new Api($this);
|
686
|
575
|
$test->get('/products?columns=id,properties&transform=1');
|
687
|
576
|
if (static::$capabilities & self::JSON) {
|
688
|
577
|
$test->expect('{"products":[{"id":1,"properties":{"depth":false,"model":"TRX-120","width":100,"height":null}}]}');
|
|
@@ -693,7 +582,7 @@ abstract class Tests extends TestBase
|
693
|
582
|
|
694
|
583
|
public function testReadProductProperties()
|
695
|
584
|
{
|
696
|
|
- $test = new API($this);
|
|
585
|
+ $test = new Api($this);
|
697
|
586
|
$test->get('/products/1?columns=id,properties');
|
698
|
587
|
if (static::$capabilities & self::JSON) {
|
699
|
588
|
$test->expect('{"id":1,"properties":{"depth":false,"model":"TRX-120","width":100,"height":null}}');
|
|
@@ -704,7 +593,7 @@ abstract class Tests extends TestBase
|
704
|
593
|
|
705
|
594
|
public function testWriteProductProperties()
|
706
|
595
|
{
|
707
|
|
- $test = new API($this);
|
|
596
|
+ $test = new Api($this);
|
708
|
597
|
if (static::$capabilities & self::JSON) {
|
709
|
598
|
$test->put('/products/1','{"properties":{"depth":false,"model":"TRX-120","width":100,"height":123}}');
|
710
|
599
|
} else {
|
|
@@ -721,7 +610,7 @@ abstract class Tests extends TestBase
|
721
|
610
|
|
722
|
611
|
public function testAddProducts()
|
723
|
612
|
{
|
724
|
|
- $test = new API($this);
|
|
613
|
+ $test = new Api($this);
|
725
|
614
|
if (static::$capabilities & self::JSON) {
|
726
|
615
|
$test->post('/products','{"name":"Laptop","price":"1299.99","properties":{}}');
|
727
|
616
|
} else {
|
|
@@ -734,7 +623,7 @@ abstract class Tests extends TestBase
|
734
|
623
|
|
735
|
624
|
public function testSoftDeleteProducts()
|
736
|
625
|
{
|
737
|
|
- $test = new API($this);
|
|
626
|
+ $test = new Api($this);
|
738
|
627
|
$test->delete('/products/1,2');
|
739
|
628
|
$test->expect('[1,1]');
|
740
|
629
|
$test->get('/products?columns=id,deleted_at');
|
|
@@ -743,7 +632,7 @@ abstract class Tests extends TestBase
|
743
|
632
|
|
744
|
633
|
public function testVarBinaryBarcodes()
|
745
|
634
|
{
|
746
|
|
- $test = new API($this);
|
|
635
|
+ $test = new Api($this);
|
747
|
636
|
$test->get('/barcodes?transform=1');
|
748
|
637
|
$test->expect('{"barcodes":[{"id":1,"product_id":1,"hex":"00ff01","bin":"AP8B"}]}');
|
749
|
638
|
}
|