PageRenderTime 51ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/test/k.test.php

http://github.com/troelskn/konstrukt
PHP | 360 lines | 242 code | 4 blank | 114 comment | 2 complexity | 61eb244e945fac8210eddf1f1427e690 MD5 | raw file
  1. <?php
  2. error_reporting(E_ALL | E_STRICT);
  3. set_include_path(dirname(__FILE__) . PATH_SEPARATOR . dirname(__FILE__) . '/../lib/' . PATH_SEPARATOR . get_include_path());
  4. require_once dirname(__FILE__) . '/../vendor/autoload.php';
  5. // You need to have simpletest in your include_path
  6. require_once 'simpletest/unit_tester.php';
  7. if (realpath($_SERVER['SCRIPT_FILENAME']) == __FILE__) {
  8. require_once 'simpletest/autorun.php';
  9. }
  10. require_once '../lib/konstrukt/konstrukt.inc.php';
  11. require_once 'support/mocks.inc.php';
  12. class TestOfGlobalsAccess extends UnitTestCase {
  13. function setUp() {
  14. $this->GET = $_GET;
  15. $_GET = array();
  16. }
  17. function tearDown() {
  18. $_GET = $this->GET;
  19. }
  20. function test_undo_magic_quotes_if_present() {
  21. $g = new k_adapter_SafeGlobalsAccess(new k_charset_Latin1CharsetStrategy(), true);
  22. $_GET = array(
  23. 'name' => "O\\'Reilly"
  24. );
  25. $this->assertEqual($g->query(), array('name' => "O'Reilly"));
  26. }
  27. function test_doesnt_undo_magic_quotes_if_not_present() {
  28. $g = new k_adapter_SafeGlobalsAccess(new k_charset_Latin1CharsetStrategy(), false);
  29. $_GET = array(
  30. 'name' => "O\\'Reilly"
  31. );
  32. $this->assertEqual($g->query(), array('name' => "O\\'Reilly"));
  33. }
  34. function test_unmagic_on_deep_array_doesnt_crash_runtime() {
  35. $g = new k_adapter_SafeGlobalsAccess(new k_charset_Latin1CharsetStrategy(), true);
  36. eval("\$_GET = " . str_repeat("array(", 1024) . "\"O\\\\'Reilly\"" . str_repeat(")", 1024) . ";");
  37. $g->query(); // Note: A failing test will produce a Fatal Error and halt the suite
  38. }
  39. function test_mixed_case_key_doesnt_get_conflated() {
  40. $g = new k_adapter_SafeGlobalsAccess(new k_charset_Latin1CharsetStrategy(), true);
  41. $_GET = array(
  42. 'foo' => "42",
  43. 'Foo' => "1337"
  44. );
  45. $this->assertEqual($g->query(), array('foo' => "42", 'Foo' => "1337"));
  46. }
  47. }
  48. class TestOfFileUpload extends UnitTestCase {
  49. function test_files_array() {
  50. $files = array(
  51. 'userfile' => array(
  52. 'name' => 'test.pdf',
  53. 'tmp_name' => 'tmp85937457',
  54. 'size' => '1024',
  55. 'type' => 'application/pdf',
  56. 'error' => 0,
  57. )
  58. );
  59. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost', 'SCRIPT_NAME' => '', 'REQUEST_URI' => ''), array(), array(), $files);
  60. $http = new k_HttpRequest(null, null, new k_DefaultIdentityLoader(), null, null, $glob);
  61. $files = $http->file();
  62. $this->assertTrue(is_array($files));
  63. $file = $http->file('userfile');
  64. $this->assertEqual($file->name(), 'test.pdf');
  65. $this->assertEqual($file->type(), 'application/pdf');
  66. $this->assertEqual($file->size(), '1024');
  67. $this->assertEqual($file->key(), 'userfile');
  68. }
  69. function test_normalizing_files_array_when_multiple_files() {
  70. $files = array(
  71. 'userfile' => array(
  72. 'name' => array(
  73. 'test.pdf',
  74. 'test.doc',
  75. ),
  76. 'tmp_name' => array(
  77. 'tmp85937457',
  78. 'tmp45937457',
  79. ),
  80. 'size' => array(
  81. '1024',
  82. '2048',
  83. ),
  84. 'type' => array(
  85. 'application/pdf',
  86. 'application/ms-word',
  87. ),
  88. 'error' => array(
  89. 0,
  90. 0,
  91. )
  92. )
  93. );
  94. $expected = array(
  95. 'userfile' => array(
  96. array(
  97. 'name' => 'test.pdf',
  98. 'tmp_name' => 'tmp85937457',
  99. 'size' => '1024',
  100. 'type' => 'application/pdf',
  101. 'error' => 0,
  102. ),
  103. array(
  104. 'name' => 'test.doc',
  105. 'tmp_name' => 'tmp45937457',
  106. 'size' => '2048',
  107. 'type' => 'application/ms-word',
  108. 'error' => 0,
  109. )
  110. )
  111. );
  112. $g = new k_adapter_SafeGlobalsAccess(new k_charset_Latin1CharsetStrategy(), true);
  113. $normalized = $g->normalizeFiles($files);
  114. $this->assertEqual($expected, $normalized);
  115. }
  116. function test_saving_an_uploaded_file() {
  117. $files = array(
  118. 'userfile' => array(
  119. 'name' => 'test.pdf',
  120. 'tmp_name' => 'tmp85937457',
  121. 'size' => '1024',
  122. 'type' => 'application/pdf',
  123. 'error' => 0,
  124. )
  125. );
  126. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost', 'SCRIPT_NAME' => '', 'REQUEST_URI' => ''), array(), array(), $files);
  127. $file_access = new k_adapter_MockUploadedFileAccess();
  128. $http = new k_HttpRequest(null, null, new k_DefaultIdentityLoader(), null, null, $glob, null, null, $file_access);
  129. $http->file('userfile')->writeTo('/dev/null');
  130. $this->assertEqual(array(array('tmp85937457', '/dev/null')), $file_access->actions);
  131. }
  132. }
  133. class TestOfDispatching extends UnitTestCase {
  134. function test_root_gives_request_uri_as_subspace() {
  135. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost'));
  136. $http = new k_HttpRequest('', '/foo/bar', new k_DefaultIdentityLoader(), null, null, $glob);
  137. $this->assertEqual($http->subspace(), "/foo/bar");
  138. }
  139. function test_first_component_has_root_subspace() {
  140. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost'));
  141. $http = new k_HttpRequest('', '/foo/bar', new k_DefaultIdentityLoader(), null, null, $glob);
  142. $components = new k_DefaultComponentCreator();
  143. $root = $components->create('test_CircularComponent', $http);
  144. $this->assertEqual($root->subspace(), "foo/bar");
  145. }
  146. function test_dispatch() {
  147. $expected = "Dispatching:
  148. name: ''
  149. next: 'foo'
  150. subtype: ''
  151. url: '/web2.0/'
  152. Dispatching:
  153. name: 'foo'
  154. next: 'bar'
  155. subtype: ''
  156. url: '/web2.0/foo'
  157. Dispatching:
  158. name: 'bar'
  159. next: 'cux'
  160. subtype: ''
  161. url: '/web2.0/foo/bar'
  162. Dispatching:
  163. name: 'cux'
  164. next: ''
  165. subtype: ''
  166. url: '/web2.0/foo/bar/cux'
  167. Executing
  168. ";
  169. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost'));
  170. $http = new k_HttpRequest('/web2.0', '/web2.0/foo/bar/cux', new k_DefaultIdentityLoader(), null, null, $glob);
  171. $components = new k_DefaultComponentCreator();
  172. $root = $components->create('test_CircularComponent', $http);
  173. $result = $root->dispatch();
  174. $this->assertEqual($result, $expected);
  175. $http = new k_HttpRequest('/web2.0', '/web2.0/foo/bar/cux/', new k_DefaultIdentityLoader(), null, null, $glob);
  176. $components = new k_DefaultComponentCreator();
  177. $root = $components->create('test_CircularComponent', $http);
  178. $result = $root->dispatch();
  179. $this->assertEqual($result, $expected);
  180. }
  181. function test_subtype_doesnt_affect_dispatch() {
  182. $expected = "Dispatching:
  183. name: ''
  184. next: 'foo'
  185. subtype: ''
  186. url: '/web2.0/'
  187. Dispatching:
  188. name: 'foo'
  189. next: 'bar'
  190. subtype: 'ninja'
  191. url: '/web2.0/foo.ninja'
  192. Dispatching:
  193. name: 'bar'
  194. next: ''
  195. subtype: ''
  196. url: '/web2.0/foo.ninja/bar'
  197. Executing
  198. ";
  199. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost'));
  200. $http = new k_HttpRequest('/web2.0', '/foo.ninja/bar', new k_DefaultIdentityLoader(), null, null, $glob);
  201. $components = new k_DefaultComponentCreator();
  202. $root = $components->create('test_CircularComponent', $http);
  203. $result = $root->dispatch();
  204. $this->assertEqual($expected, $result);
  205. }
  206. }
  207. class TestOfHttpRequest extends UnitTestCase {
  208. function createHttp($headers) {
  209. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'example.org'), $headers);
  210. return new k_HttpRequest('', '', new k_DefaultIdentityLoader(), null, null, $glob);
  211. }
  212. function test_negotiate_returns_first_match_from_accept_header() {
  213. $request = $this->createHttp(array('accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'));
  214. $this->assertEqual($request->negotiateContentType(array('text/html','application/xhtml+xml','application/xml')), 'text/html');
  215. }
  216. function test_negotiate_returns_match_with_highest_rank_from_accept_header() {
  217. $request = $this->createHttp(array('accept' => 'text/html;q=0.1,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'));
  218. $this->assertEqual($request->negotiateContentType(array('text/html','application/xhtml+xml','application/xml')), 'application/xhtml+xml');
  219. }
  220. function test_negotiate_returns_candidate_with_exact_match() {
  221. $request = $this->createHttp(array('accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'));
  222. $this->assertEqual($request->negotiateContentType(array('application/xml')), 'application/xml');
  223. }
  224. function test_negotiate_returns_candidate_with_partial_match() {
  225. $request = $this->createHttp(array('accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'));
  226. $this->assertEqual($request->negotiateContentType(array('application/*')), 'application/*');
  227. }
  228. function test_negotiate_returns_first_candidate_on_no_header() {
  229. $request = $this->createHttp(array('accept' => ''));
  230. $this->assertEqual($request->negotiateContentType(array('text/html')), 'text/html');
  231. }
  232. function test_user_override_overrides_accept_header() {
  233. $request = $this->createHttp(array('accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'));
  234. $this->assertEqual($request->negotiateContentType(array('text/html', 'foo/bar'), 'foo/bar'), 'foo/bar');
  235. }
  236. function test_negotiate_simple_subtype_interpreted_as_major_type() {
  237. $request = $this->createHttp(array('accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'));
  238. $this->assertEqual($request->negotiateContentType(array('text/html', 'foo'), 'foo'), 'foo');
  239. }
  240. function test_negotiate_internet_explorer_headerline() {
  241. $request = $this->createHttp(array('accept' => 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*'));
  242. $this->assertEqual($request->negotiateContentType(array('text/html')), 'text/html');
  243. }
  244. function test_negotiate_returns_first_match_when_no_ranking() {
  245. $request = $this->createHttp(array('accept' => 'application/json, text/javascript, */*'));
  246. $this->assertEqual($request->negotiateContentType(array('text/html','application/json')), 'application/json');
  247. }
  248. }
  249. class TestOfHttpResponse extends UnitTestCase {
  250. function test_404_response_should_output_custom_content_if_any() {
  251. $output = new k_adapter_DummyOutputAccess();
  252. $response = new k_HtmlResponse("I didn't find it");
  253. $response->setStatus(404);
  254. $response->out($output);
  255. $this->assertEqual(404, $output->http_response_code);
  256. $this->assertEqual("I didn't find it", $output->body);
  257. }
  258. }
  259. class TestOfContentTypeDispathing extends UnitTestCase {
  260. function createComponent($method, $headers = array()) {
  261. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost', 'REQUEST_METHOD' => $method), $headers);
  262. $http = new k_HttpRequest('', '/', new k_DefaultIdentityLoader(), null, null, $glob);
  263. $components = new k_DefaultComponentCreator();
  264. return $components->create('test_ContentTypeComponent', $http);
  265. }
  266. function test_posting_with_a_content_type_calls_specific_handler() {
  267. $root = $this->createComponent('post', array('content-type' => 'application/json'));
  268. $this->assertEqual("postJson called", $root->dispatch());
  269. }
  270. function test_post_multipart() {
  271. $root = $this->createComponent('post', array('content-type' => 'multipart/form-data; boundary=---------------------------1991290281749441721928095653'));
  272. $this->assertEqual("postMultipart called", $root->dispatch());
  273. }
  274. function test_posting_without_a_content_type_fails_with_not_acceptable_when_there_is_at_least_one_candidate() {
  275. $root = $this->createComponent('post');
  276. try {
  277. $root->dispatch();
  278. $this->fail("Expected exception not caught");
  279. } catch (k_NotAcceptable $ex) {
  280. $this->pass();
  281. }
  282. }
  283. function test_putting_without_a_content_type_fails_with_not_implemented_when_there_are_no_candidates() {
  284. $root = $this->createComponent('put');
  285. try {
  286. $root->dispatch();
  287. $this->fail("Expected exception not caught");
  288. } catch (k_NotImplemented $ex) {
  289. $this->pass();
  290. }
  291. }
  292. function test_a_content_type_with_explicit_charset_utf8_is_treated_transparently() {
  293. $root = $this->createComponent('post', array('content-type' => 'application/json; charset=utf-8'));
  294. $this->assertEqual("postJson called", $root->dispatch());
  295. }
  296. function test_a_content_type_with_explicit_charset_other_than_utf8_raises_an_error() {
  297. $root = $this->createComponent('post', array('content-type' => 'application/json; charset=iso-8859-1'));
  298. try {
  299. $root->dispatch();
  300. $this->fail("Expected exception");
  301. } catch (k_UnsupportedContentTypeCharsetException $ex) {
  302. $this->pass("Exception caught");
  303. }
  304. }
  305. }
  306. class TestOfLanguageLoading {
  307. function createComponent($method, $headers = array()) {
  308. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost', 'REQUEST_METHOD' => $method), $headers);
  309. $language_loader = new test_LanguageLoader();
  310. $http = new k_HttpRequest('', '/', new k_DefaultIdentityLoader(), $language_loader, null, $glob);
  311. $components = new k_DefaultComponentCreator();
  312. return $components->create('test_ContentTypeComponent', $http);
  313. }
  314. function test_that_a_language_is_loaded() {
  315. $component = $this->createComponent('get');
  316. $language = $component->language();
  317. $this->assertTrue($language instanceof k_Language);
  318. }
  319. }
  320. class TestOfTranslatorLoading {
  321. function createComponent($method, $headers = array()) {
  322. $glob = new k_adapter_MockGlobalsAccess(array(), array(), array('SERVER_NAME' => 'localhost', 'REQUEST_METHOD' => $method), $headers);
  323. $translator_loader = new test_TranslatorLoader();
  324. $http = new k_HttpRequest('', '/', new k_DefaultIdentityLoader(), null, $translator_loader, $glob);
  325. $components = new k_DefaultComponentCreator();
  326. return $components->create('test_ContentTypeComponent', $http);
  327. }
  328. function test_that_a_translator_is_loaded() {
  329. $component = $this->createComponent('get');
  330. $translator = $component->language();
  331. $this->assertTrue($translator instanceof k_Translator);
  332. }
  333. }