api de gestion de ticket, basé sur php-crud-api. Le but est de décorrélé les outils de gestion des données, afin
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Tests.php 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. <?php
  2. require_once(__DIR__ . '/TestBase.php');
  3. require_once(__DIR__ . '/Api.php');
  4. abstract class Tests extends TestBase
  5. {
  6. public function testListPosts()
  7. {
  8. $test = new Api($this);
  9. $test->get('/posts');
  10. $test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"],[2,1,2,"It works!"]]}}');
  11. }
  12. public function testListPostColumns()
  13. {
  14. $test = new Api($this);
  15. $test->get('/posts?columns=id,content');
  16. $test->expect('{"posts":{"columns":["id","content"],"records":[[1,"blog started"],[2,"It works!"]]}}');
  17. }
  18. public function testListPostsWithTransform()
  19. {
  20. $test = new Api($this);
  21. $test->get('/posts?transform=1');
  22. $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!"}]}');
  23. }
  24. public function testReadPost()
  25. {
  26. $test = new Api($this);
  27. $test->get('/posts/2');
  28. $test->expect('{"id":2,"user_id":1,"category_id":2,"content":"It works!"}');
  29. }
  30. public function testReadPosts()
  31. {
  32. $test = new Api($this);
  33. $test->get('/posts/1,2');
  34. $test->expect('[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":2,"user_id":1,"category_id":2,"content":"It works!"}]');
  35. }
  36. public function testReadPostColumns()
  37. {
  38. $test = new Api($this);
  39. $test->get('/posts/2?columns=id,content');
  40. $test->expect('{"id":2,"content":"It works!"}');
  41. }
  42. public function testAddPost()
  43. {
  44. $test = new Api($this);
  45. $test->post('/posts','{"user_id":1,"category_id":1,"content":"test"}');
  46. $test->expect('3');
  47. }
  48. public function testEditPost()
  49. {
  50. $test = new Api($this);
  51. $test->put('/posts/3','{"user_id":1,"category_id":1,"content":"test (edited)"}');
  52. $test->expect('1');
  53. $test->get('/posts/3');
  54. $test->expect('{"id":3,"user_id":1,"category_id":1,"content":"test (edited)"}');
  55. }
  56. public function testEditPostColumnsMissingField()
  57. {
  58. $test = new Api($this);
  59. $test->put('/posts/3?columns=id,content','{"content":"test (edited 2)"}');
  60. $test->expect('1');
  61. $test->get('/posts/3');
  62. $test->expect('{"id":3,"user_id":1,"category_id":1,"content":"test (edited 2)"}');
  63. }
  64. public function testEditPostColumnsExtraField()
  65. {
  66. $test = new Api($this);
  67. $test->put('/posts/3?columns=id,content','{"user_id":2,"content":"test (edited 3)"}');
  68. $test->expect('1');
  69. $test->get('/posts/3');
  70. $test->expect('{"id":3,"user_id":1,"category_id":1,"content":"test (edited 3)"}');
  71. }
  72. public function testEditPostWithUtf8Content()
  73. {
  74. $utf8 = json_encode('Hello world, Καλημέρα κόσμε, コンニチハ');
  75. $test = new Api($this);
  76. $test->put('/posts/2','{"content":'.$utf8.'}');
  77. $test->expect('1');
  78. $test->get('/posts/2');
  79. $test->expect('{"id":2,"user_id":1,"category_id":2,"content":'.$utf8.'}');
  80. }
  81. public function testEditPostWithUtf8ContentWithPost()
  82. {
  83. $utf8 = '€ Hello world, Καλημέρα κόσμε, コンニチハ';
  84. $url_encoded = urlencode($utf8);
  85. $json_encoded = json_encode($utf8);
  86. $test = new Api($this);
  87. $test->put('/posts/2','content='.$url_encoded);
  88. $test->expect('1');
  89. $test->get('/posts/2');
  90. $test->expect('{"id":2,"user_id":1,"category_id":2,"content":'.$json_encoded.'}');
  91. }
  92. public function testDeletePost()
  93. {
  94. $test = new Api($this);
  95. $test->delete('/posts/3');
  96. $test->expect('1');
  97. $test->get('/posts/3');
  98. $test->expect(false,'Not found (object)');
  99. }
  100. public function testAddPostWithPost()
  101. {
  102. $test = new Api($this);
  103. $test->post('/posts','user_id=1&category_id=1&content=test');
  104. $test->expect('4');
  105. }
  106. public function testEditPostWithPost()
  107. {
  108. $test = new Api($this);
  109. $test->put('/posts/4','user_id=1&category_id=1&content=test+(edited)');
  110. $test->expect('1');
  111. $test->get('/posts/4');
  112. $test->expect('{"id":4,"user_id":1,"category_id":1,"content":"test (edited)"}');
  113. }
  114. public function testDeletePostWithPost()
  115. {
  116. $test = new Api($this);
  117. $test->delete('/posts/4');
  118. $test->expect('1');
  119. $test->get('/posts/4');
  120. $test->expect(false,'Not found (object)');
  121. }
  122. public function testListWithPaginate()
  123. {
  124. $test = new Api($this);
  125. for ($i=1;$i<=10;$i++) {
  126. $test->post('/posts','{"user_id":1,"category_id":1,"content":"#'.$i.'"}');
  127. $test->expect(4+$i);
  128. }
  129. $test->get('/posts?page=2,2&order=id');
  130. $test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[5,1,1,"#1"],[6,1,1,"#2"]],"results":11}}');
  131. }
  132. public function testListWithPaginateInMultipleOrder()
  133. {
  134. $test = new Api($this);
  135. $test->get('/posts?page=1,2&order[]=category_id,asc&order[]=id,desc');
  136. $test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[14,1,1,"#10"],[12,1,1,"#8"]],"results":11}}');
  137. }
  138. public function testListWithPaginateInDescendingOrder()
  139. {
  140. $test = new Api($this);
  141. $test->get('/posts?page=2,2&order=id,desc');
  142. $test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[11,1,1,"#7"],[10,1,1,"#6"]],"results":11}}');
  143. }
  144. public function testListWithPaginateLastPage()
  145. {
  146. $test = new Api($this);
  147. $test->get('/posts?page=3,5&order=id');
  148. $test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[14,1,1,"#10"]],"results":11}}');
  149. }
  150. public function testListExampleFromReadmeFullRecord()
  151. {
  152. $test = new Api($this);
  153. $test->get('/posts?filter=id,eq,1');
  154. $test->expect('{"posts":{"columns":["id","user_id","category_id","content"],"records":[[1,1,1,"blog started"]]}}');
  155. }
  156. public function testListExampleFromReadmeWithExclude()
  157. {
  158. $test = new Api($this);
  159. $test->get('/posts?exclude=id&filter=id,eq,1');
  160. $test->expect('{"posts":{"columns":["user_id","category_id","content"],"records":[[1,1,"blog started"]]}}');
  161. }
  162. public function testListExampleFromReadme()
  163. {
  164. $test = new Api($this);
  165. $test->get('/posts?include=categories,tags,comments&filter=id,eq,1');
  166. $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"]]}}');
  167. }
  168. public function testListExampleFromReadmeWithTransform()
  169. {
  170. $test = new Api($this);
  171. $test->get('/posts?include=categories,tags,comments&filter=id,eq,1&transform=1');
  172. $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"}]}');
  173. }
  174. public function testListExampleFromReadmeWithTransformWithExclude()
  175. {
  176. $test = new Api($this);
  177. $test->get('/posts?include=categories,tags,comments&exclude=comments.message&filter=id,eq,1&transform=1');
  178. $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"}]}');
  179. }
  180. public function testEditCategoryWithBinaryContent()
  181. {
  182. $binary = base64_encode("\0abc\0\n\r\b\0");
  183. $base64url = rtrim(strtr($binary, '+/', '-_'), '=');
  184. $test = new Api($this);
  185. $test->put('/categories/2','{"icon":"'.$base64url.'"}');
  186. $test->expect('1');
  187. $test->get('/categories/2');
  188. $test->expect('{"id":2,"name":"article","icon":"'.$binary.'"}');
  189. }
  190. public function testEditCategoryWithNull()
  191. {
  192. $test = new Api($this);
  193. $test->put('/categories/2','{"icon":null}');
  194. $test->expect('1');
  195. $test->get('/categories/2');
  196. $test->expect('{"id":2,"name":"article","icon":null}');
  197. }
  198. public function testEditCategoryWithBinaryContentWithPost()
  199. {
  200. $binary = base64_encode("€ \0abc\0\n\r\b\0");
  201. $base64url = rtrim(strtr($binary, '+/', '-_'), '=');
  202. $test = new Api($this);
  203. $test->put('/categories/2','icon='.$base64url);
  204. $test->expect('1');
  205. $test->get('/categories/2');
  206. $test->expect('{"id":2,"name":"article","icon":"'.$binary.'"}');
  207. }
  208. public function testListCategoriesWithBinaryContent()
  209. {
  210. $test = new Api($this);
  211. $test->get('/categories');
  212. $test->expect('{"categories":{"columns":["id","name","icon"],"records":[[1,"announcement",null],[2,"article","4oKsIABhYmMACg1cYgA="]]}}');
  213. }
  214. public function testEditCategoryWithNullWithPost()
  215. {
  216. $test = new Api($this);
  217. $test->put('/categories/2','icon__is_null');
  218. $test->expect('1');
  219. $test->get('/categories/2');
  220. $test->expect('{"id":2,"name":"article","icon":null}');
  221. }
  222. public function testAddPostFailure()
  223. {
  224. $test = new Api($this);
  225. $test->post('/posts','{"user_id":"a","category_id":1,"content":"tests"}');
  226. $test->expect('null');
  227. }
  228. public function testOptionsRequest()
  229. {
  230. $test = new Api($this);
  231. $test->options('/posts/2');
  232. $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);
  233. }
  234. public function testHidingPasswordColumn()
  235. {
  236. $test = new Api($this);
  237. $test->get('/users?filter=id,eq,1&transform=1');
  238. $test->expect('{"users":[{"id":1,"username":"user1","location":null}]}');
  239. }
  240. public function testValidatorErrorMessage()
  241. {
  242. $test = new Api($this);
  243. $test->put('/posts/1','{"category_id":"a"}');
  244. $test->expect(false,'{"category_id":"must be numeric"}');
  245. }
  246. public function testSanitizerToStripTags()
  247. {
  248. $test = new Api($this);
  249. $test->put('/categories/2','{"name":"<script>alert();</script>"}');
  250. $test->expect('1');
  251. $test->get('/categories/2');
  252. $test->expect('{"id":2,"name":"alert();","icon":null}');
  253. }
  254. public function testErrorOnInvalidJson()
  255. {
  256. $test = new Api($this);
  257. $test->post('/posts','{"}');
  258. $test->expect(false,'Not found (input)');
  259. }
  260. public function testErrorOnDuplicatePrimaryKey()
  261. {
  262. $test = new Api($this);
  263. $test->post('/posts','{"id":1,"user_id":1,"category_id":1,"content":"blog started (duplicate)"}');
  264. $test->expect('null');
  265. }
  266. public function testErrorOnFailingForeignKeyConstraint()
  267. {
  268. $test = new Api($this);
  269. $test->post('/posts','{"user_id":3,"category_id":1,"content":"fk constraint"}');
  270. $test->expect('null');
  271. }
  272. public function testMissingIntermediateTable()
  273. {
  274. $test = new Api($this);
  275. $test->get('/users?include=posts,tags');
  276. $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"]]}}');
  277. }
  278. public function testEditUserPassword()
  279. {
  280. $test = new Api($this);
  281. $test->put('/users/1','{"password":"testtest"}');
  282. $test->expect('1');
  283. }
  284. public function testEditUserLocation()
  285. {
  286. $test = new Api($this);
  287. $test->put('/users/1','{"location":"POINT(30 20)"}');
  288. $test->expect('1');
  289. $test->get('/users/1?columns=id,location');
  290. if ($this->getEngineName()=='SQLServer') {
  291. $test->expect('{"id":1,"location":"POINT (30 20)"}');
  292. } else {
  293. $test->expect('{"id":1,"location":"POINT(30 20)"}');
  294. }
  295. }
  296. public function testListUserLocations()
  297. {
  298. $test = new Api($this);
  299. $test->get('/users?columns=id,location');
  300. if ($this->getEngineName()=='SQLServer') {
  301. $test->expect('{"users":{"columns":["id","location"],"records":[[1,"POINT (30 20)"]]}}');
  302. } else {
  303. $test->expect('{"users":{"columns":["id","location"],"records":[[1,"POINT(30 20)"]]}}');
  304. }
  305. }
  306. public function testEditUserWithId()
  307. {
  308. if ($this->getEngineName()!='SQLServer') {
  309. $test = new Api($this);
  310. $test->put('/users/1','{"id":2,"password":"testtest2"}');
  311. $test->expect('1');
  312. $test->get('/users/1?columns=id,username,password');
  313. $test->expect('{"id":1,"username":"user1","password":"testtest2"}');
  314. }
  315. }
  316. public function testReadOtherUser()
  317. {
  318. $test = new Api($this);
  319. $test->get('/users/2');
  320. $test->expect(false,'Not found (object)');
  321. }
  322. public function testEditOtherUser()
  323. {
  324. $test = new Api($this);
  325. $test->put('/users/2','{"password":"testtest"}');
  326. $test->expect('0');
  327. }
  328. public function testFilterCategoryOnNullIcon()
  329. {
  330. $test = new Api($this);
  331. $test->get('/categories?filter[]=icon,is,null&transform=1');
  332. $test->expect('{"categories":[{"id":1,"name":"announcement","icon":null},{"id":2,"name":"alert();","icon":null}]}');
  333. }
  334. public function testFilterCategoryOnNotNullIcon()
  335. {
  336. $test = new Api($this);
  337. $test->get('/categories?filter[]=icon,nis,null&transform=1');
  338. $test->expect('{"categories":[]}');
  339. }
  340. public function testFilterPostsNotIn()
  341. {
  342. $test = new Api($this);
  343. $test->get('/posts?filter[]=id,nin,1,2,3,4,7,8,9,10,11,12,13,14&transform=1');
  344. $test->expect('{"posts":[{"id":5,"user_id":1,"category_id":1,"content":"#1"},{"id":6,"user_id":1,"category_id":1,"content":"#2"}]}');
  345. }
  346. public function testFilterPostsBetween()
  347. {
  348. $test = new Api($this);
  349. $test->get('/posts?filter[]=id,bt,5,6&transform=1');
  350. $test->expect('{"posts":[{"id":5,"user_id":1,"category_id":1,"content":"#1"},{"id":6,"user_id":1,"category_id":1,"content":"#2"}]}');
  351. }
  352. public function testFilterPostsNotBetween()
  353. {
  354. $test = new Api($this);
  355. $test->get('/posts?filter[]=id,nbt,2,13&transform=1');
  356. $test->expect('{"posts":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":14,"user_id":1,"category_id":1,"content":"#10"}]}');
  357. }
  358. public function testColumnsWithTable()
  359. {
  360. $test = new Api($this);
  361. $test->get('/posts?columns=posts.content&filter=id,eq,1&transform=1');
  362. $test->expect('{"posts":[{"content":"blog started"}]}');
  363. }
  364. public function testColumnsWithTableWildcard()
  365. {
  366. $test = new Api($this);
  367. $test->get('/posts?columns=posts.*&filter=id,eq,1&transform=1');
  368. $test->expect('{"posts":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"}]}');
  369. }
  370. public function testColumnsOnInclude()
  371. {
  372. $test = new Api($this);
  373. $test->get('/posts?include=categories&columns=categories.name&filter=id,eq,1&transform=1');
  374. $test->expect('{"posts":[{"category_id":1,"categories":[{"id":1,"name":"announcement"}]}]}');
  375. }
  376. public function testFilterOnRelationAnd()
  377. {
  378. $test = new Api($this);
  379. $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');
  380. $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"]]}}');
  381. }
  382. public function testFilterOnRelationOr()
  383. {
  384. $test = new Api($this);
  385. $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');
  386. $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"]]}}');
  387. }
  388. public function testColumnsOnWrongInclude()
  389. {
  390. $test = new Api($this);
  391. $test->get('/posts?include=categories&columns=categories&filter=id,eq,1&transform=1');
  392. $test->expect('{"posts":[{"category_id":1,"categories":[{"id":1}]}]}');
  393. }
  394. public function testColumnsOnImplicitJoin()
  395. {
  396. $test = new Api($this);
  397. $test->get('/posts?include=tags&columns=posts.id,tags.name&filter=id,eq,1&transform=1');
  398. $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"}]}]}]}');
  399. }
  400. public function testSpatialFilterWithin()
  401. {
  402. if (static::$capabilities & self::GIS) {
  403. $test = new Api($this);
  404. $test->get('/users?columns=id,username&filter=location,swi,POINT(30 20)');
  405. $test->expect('{"users":{"columns":["id","username"],"records":[[1,"user1"]]}}');
  406. }
  407. }
  408. public function testAddPostsWithNonExistingCategory()
  409. {
  410. $test = new Api($this);
  411. $test->post('/posts','[{"user_id":1,"category_id":1,"content":"tests"},{"user_id":1,"category_id":15,"content":"tests"}]');
  412. $test->expect('null');
  413. $test->get('/posts?columns=content&filter=content,eq,tests');
  414. $test->expect('{"posts":{"columns":["content"],"records":[]}}');
  415. }
  416. public function testAddPosts()
  417. {
  418. $test = new Api($this);
  419. $test->post('/posts','[{"user_id":1,"category_id":1,"content":"tests"},{"user_id":1,"category_id":1,"content":"tests"}]');
  420. $test->expectAny();
  421. $test->get('/posts?columns=content&filter=content,eq,tests');
  422. $test->expect('{"posts":{"columns":["content"],"records":[["tests"],["tests"]]}}');
  423. }
  424. public function testListEvents()
  425. {
  426. $test = new Api($this);
  427. $test->get('/events?columns=datetime');
  428. $test->expect('{"events":{"columns":["datetime"],"records":[["2016-01-01 13:01:01"]]}}');
  429. }
  430. public function testIncrementEventVisitors()
  431. {
  432. $test = new Api($this);
  433. $test->patch('/events/1','{"visitors":11}');
  434. $test->expect('1');
  435. $test->get('/events/1');
  436. $test->expect('{"id":1,"name":"Launch","datetime":"2016-01-01 13:01:01","visitors":11}');
  437. }
  438. public function testIncrementEventVisitorsWithZero()
  439. {
  440. $test = new Api($this);
  441. $test->patch('/events/1','{"visitors":0}');
  442. $test->expect('1');
  443. $test->get('/events/1');
  444. $test->expect('{"id":1,"name":"Launch","datetime":"2016-01-01 13:01:01","visitors":11}');
  445. }
  446. public function testDecrementEventVisitors()
  447. {
  448. $test = new Api($this);
  449. $test->patch('/events/1','{"visitors":-5}');
  450. $test->expect('1');
  451. $test->get('/events/1');
  452. $test->expect('{"id":1,"name":"Launch","datetime":"2016-01-01 13:01:01","visitors":6}');
  453. }
  454. public function testListTagUsage()
  455. {
  456. $test = new Api($this);
  457. $test->get('/tag_usage');
  458. $test->expect('{"tag_usage":{"columns":["name","count"],"records":[["funny",2],["important",2]]}}');
  459. }
  460. public function testUpdateMultipleTags()
  461. {
  462. $test = new Api($this);
  463. $test->get('/tags?transform=1');
  464. $test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
  465. $test->put('/tags/1,2','[{"name":"funny"},{"name":"important"}]');
  466. $test->expect('[1,1]');
  467. }
  468. public function testUpdateMultipleTagsTooManyIds()
  469. {
  470. $test = new Api($this);
  471. $test->put('/tags/1,2,3','[{"name":"funny!!!"},{"name":"important"}]');
  472. $test->expect(false,'Not found (subject)');
  473. $test->get('/tags?transform=1');
  474. $test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
  475. }
  476. public function testUpdateMultipleTagsWithoutFields()
  477. {
  478. $test = new Api($this);
  479. $test->put('/tags/1,2','[{"name":"funny!!!"},{}]');
  480. $test->expect('null');
  481. $test->get('/tags?transform=1');
  482. $test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
  483. }
  484. public function testDeleteMultipleTags()
  485. {
  486. $test = new Api($this);
  487. $test->post('/tags','[{"name":"extra"},{"name":"more"}]');
  488. $test->expect('[3,4]');
  489. $test->delete('/tags/3,4');
  490. $test->expect('[1,1]');
  491. $test->get('/tags?transform=1');
  492. $test->expect('{"tags":[{"id":1,"name":"funny"},{"id":2,"name":"important"}]}');
  493. }
  494. public function testListProducts()
  495. {
  496. $test = new Api($this);
  497. $test->get('/products?columns=id,name,price&transform=1');
  498. $test->expect('{"products":[{"id":1,"name":"Calculator","price":"23.01"}]}');
  499. }
  500. public function testListProductsProperties()
  501. {
  502. $test = new Api($this);
  503. $test->get('/products?columns=id,properties&transform=1');
  504. if (static::$capabilities & self::JSON) {
  505. $test->expect('{"products":[{"id":1,"properties":{"depth":false,"model":"TRX-120","width":100,"height":null}}]}');
  506. } else {
  507. $test->expect('{"products":[{"id":1,"properties":"{\"depth\":false,\"model\":\"TRX-120\",\"width\":100,\"height\":null}"}]}');
  508. }
  509. }
  510. public function testReadProductProperties()
  511. {
  512. $test = new Api($this);
  513. $test->get('/products/1?columns=id,properties');
  514. if (static::$capabilities & self::JSON) {
  515. $test->expect('{"id":1,"properties":{"depth":false,"model":"TRX-120","width":100,"height":null}}');
  516. } else {
  517. $test->expect('{"id":1,"properties":"{\"depth\":false,\"model\":\"TRX-120\",\"width\":100,\"height\":null}"}');
  518. }
  519. }
  520. public function testWriteProductProperties()
  521. {
  522. $test = new Api($this);
  523. if (static::$capabilities & self::JSON) {
  524. $test->put('/products/1','{"properties":{"depth":false,"model":"TRX-120","width":100,"height":123}}');
  525. } else {
  526. $test->put('/products/1','{"properties":"{\"depth\":false,\"model\":\"TRX-120\",\"width\":100,\"height\":123}"}');
  527. }
  528. $test->expect('1');
  529. $test->get('/products/1?columns=id,properties');
  530. if (static::$capabilities & self::JSON) {
  531. $test->expect('{"id":1,"properties":{"depth":false,"model":"TRX-120","width":100,"height":123}}');
  532. } else {
  533. $test->expect('{"id":1,"properties":"{\"depth\":false,\"model\":\"TRX-120\",\"width\":100,\"height\":123}"}');
  534. }
  535. }
  536. public function testAddProducts()
  537. {
  538. $test = new Api($this);
  539. if (static::$capabilities & self::JSON) {
  540. $test->post('/products','{"name":"Laptop","price":"1299.99","properties":{}}');
  541. } else {
  542. $test->post('/products','{"name":"Laptop","price":"1299.99","properties":"{}"}');
  543. }
  544. $test->expect('2');
  545. $test->get('/products/2?columns=id,created_at,deleted_at');
  546. $test->expect('{"id":2,"created_at":"2013-12-11 10:09:08","deleted_at":null}');
  547. }
  548. public function testSoftDeleteProducts()
  549. {
  550. $test = new Api($this);
  551. $test->delete('/products/1,2');
  552. $test->expect('[1,1]');
  553. $test->get('/products?columns=id,deleted_at');
  554. $test->expect('{"products":{"columns":["id","deleted_at"],"records":[[1,"2013-12-11 11:10:09"],[2,"2013-12-11 11:10:09"]]}}');
  555. }
  556. public function testVarBinaryBarcodes()
  557. {
  558. $test = new Api($this);
  559. $test->get('/barcodes?transform=1');
  560. $test->expect('{"barcodes":[{"id":1,"product_id":1,"hex":"00ff01","bin":"AP8B"}]}');
  561. }
  562. }