PageRenderTime 10ms CodeModel.GetById 2ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 1ms

/tests/tests/TestCore.cfc

http://github.com/atuttle/Taffy
ColdFusion CFScript | 614 lines | 437 code | 93 blank | 84 comment | 18 complexity | b1fa3abc3f69e9392f53d086e071dbc8 MD5 | raw file
  1<cfcomponent extends="base">
  2
  3	<cffunction name="setup">
  4		<cfset reloadFramework()>
  5	</cffunction>
  6
  7	<cfscript>
  8		function beforeTests(){
  9			variables.taffy = createObject("component","taffy.tests.Application");
 10			makePublic(variables.taffy, "getBeanFactory");
 11			variables.factory = variables.taffy.getBeanFactory();
 12			variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resources'), 'taffy.tests.resources', expandPath('/taffy/tests/resources'), true );
 13		}
 14
 15		function test_properly_notifies_unimplemented_mimes(){
 16			makePublic(variables.taffy, "mimeSupported");
 17			// debug(variables.taffy);
 18			// debug(application);
 19			assertFalse(taffy.mimeSupported("DoesNotExist"), "When given a mime type that should not exist, Taffy reported that it did.");
 20		}
 21
 22		function test_properly_notifies_implemented_mimes(){
 23			makePublic(variables.taffy, "mimeSupported");
 24			makePublic(variables.taffy, "inspectMimeTypes");
 25			variables.taffy.inspectMimeTypes('taffy.core.nativeJsonSerializer', variables.taffy.getBeanFactory());
 26			assertTrue(taffy.mimeSupported("json"));
 27			assertTrue(taffy.mimeSupported("text/json"));
 28			assertTrue(taffy.mimeSupported("application/json"));
 29		}
 30
 31		function test_returns_etag_header(){
 32			//both requests should yeild the same etag header
 33			local.result = apiCall("get", "/echo/foo.json", "");
 34			local.result2 = apiCall("get", "/echo/foo.json", "");
 35
 36			assertTrue(structKeyExists(local.result.responseHeader, "Etag"));
 37			assertTrue(structKeyExists(local.result2.responseHeader, "Etag"));
 38			assertEquals(local.result2.responseHeader.etag, local.result.responseHeader.etag);
 39		}
 40
 41		function test_returns_304_when_not_modified(){
 42			local.result = apiCall("get", "/echo/foo.json", "");
 43			assertTrue(structKeyExists(local.result.responseHeader, "Etag"));
 44
 45			local.h = {};
 46			local.h['if-none-match'] = local.result.responseHeader.etag;
 47			local.result = apiCall("get", "/echo/foo.json", "", local.h);
 48			debug(local.result);
 49			assertEquals(304, val(local.result.responseHeader.status_code));
 50		}
 51
 52		function test_json_result_is_json(){
 53			local.result = apiCall ("get","/echo/2.json","bar=foo");
 54			// debug(local.result);
 55			assertTrue(isJson(local.result.fileContent), "Expected JSON content back but was not able to identify it as such.");
 56		}
 57
 58		function test_custom_status_is_returned(){
 59			local.result = apiCall("get", "/echo/1.json?foo=bar", "");
 60			// debug(local.result);
 61			// debug(application);
 62			assertEquals(999, local.result.responseHeader.status_code, "Expected status code 999 but got something else.");
 63		}
 64
 65		function test_custom_headers_work(){
 66			local.result = apiCall("get", "/echo/-1.json", "");
 67			// debug(local.result);
 68			assertTrue(structKeyExists(local.result.responseHeader, "x-dude"), "Expected response header `x-dude` but it was not included.");
 69		}
 70
 71		function test_global_headers_work(){
 72			local.result = apiCall("get", "/echo/1.json", "");
 73			// debug(local.result);
 74			assertTrue(structKeyExists(local.result.responseHeader, "x-foo-globalheader"), "Expected response header `x-foo-globalheader` but it was not included.");
 75		}
 76
 77		function test_deserializer_inspection_finds_all_content_types(){
 78			makePublic(variables.taffy, "getSupportedContentTypes");
 79			local.result = variables.taffy.getSupportedContentTypes("taffy.core.baseDeserializer");
 80			// debug(local.result);
 81			assertTrue(structKeyExists(local.result, "application/x-www-form-urlencoded"));
 82			local.result = variables.taffy.getSupportedContentTypes("taffy.core.nativeJsonDeserializer");
 83			// debug(local.result);
 84			assertTrue(structKeyExists(local.result, "application/json"));
 85			assertTrue(structKeyExists(local.result, "text/json"));
 86			assertTrue(structKeyExists(local.result, "application/x-www-form-urlencoded"));
 87		}
 88
 89		function test_deserializer_support_detection_works(){
 90			makePublic(variables.taffy, "contentTypeIsSupported");
 91			// debug(application._taffy.contentTypes);
 92			assertTrue(variables.taffy.contentTypeIsSupported("application/json"));
 93			assertTrue(variables.taffy.contentTypeIsSupported("application/json;v=1"));
 94			assertFalse(variables.taffy.contentTypeIsSupported("application/does-not-exist"));
 95		}
 96
 97		function test_uri_regexes_are_correct(){
 98			makePublic(variables.taffy, "convertURItoRegex");
 99
100			local.result = taffy.convertURItoRegex("/a/{abc}/b");
101			// debug(local.result);
102			assertEquals( "^/a/([^\/]+)/b((?:\.)[^\.\?\/]+)?\/?$", local.result["uriregex"], "Resulted regex did not match expected. (assert 1)");
103			assertEquals( 1, arrayLen(local.result["tokens"]), "assert 2" );
104			assertEquals( "abc", local.result["tokens"][1], "assert 3" );
105
106			local.result2 = taffy.convertURItoRegex("/a/{abc}");
107			// debug(local.result2);
108			assertEquals( "^/a/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$", local.result2["uriregex"], "Resulted regex did not match expected.");
109			assertEquals( 1, arrayLen(local.result2["tokens"]) );
110			assertEquals( "abc", local.result2["tokens"][1] );
111
112			//custom regexes for tokens
113			local.result3 = taffy.convertURItoRegex("/a/{b:[a-z]+(?:42){1}}");
114			// debug(local.result3);
115			assertEquals( "^/a/([a-z]+(?:42){1})((?:\.)[^\.\?\/]+)?\/?$", local.result3["uriregex"], "Resulted regex did not match expected. (assert 7)");
116			assertEquals( 1, arrayLen(local.result3["tokens"]), "assert 8" );
117			assertEquals( "b", local.result3["tokens"][1], "assert 9" );
118
119			local.result4 = taffy.convertURItoRegex("/a/{b:[0-4]{1,7}(?:aaa){1}}/c/{d:\d+}");
120			// debug(local.result4);
121			assertEquals( "^/a/([0-4]{1,7}(?:aaa){1})/c/(\d+)((?:\.)[^\.\?\/]+)?\/?$", local.result4["uriregex"], "Resulted regex did not match expected. (assert 10)");
122			assertEquals( 2, arrayLen(local.result4["tokens"]), "assert 11" );
123			assertEquals( "b", local.result4["tokens"][1], "assert 12" );
124			assertEquals( "d", local.result4["tokens"][2], "assert 13" );
125		}
126
127		function test_uri_matching_works_with_extension(){
128			makePublic(variables.taffy, "matchURI");
129			local.result = variables.taffy.matchURI("/echo/3.json");
130			// debug(local.result);
131			assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
132		}
133
134		function test_uri_matching_works_without_extension(){
135			makePublic(variables.taffy, "matchURI");
136			local.result = variables.taffy.matchURI("/echo/3");
137			// debug(local.result);
138			assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
139		}
140
141		function test_uri_matching_works_with_trailing_slash_with_extension(){
142			makePublic(variables.taffy, "matchURI");
143			local.result = variables.taffy.matchURI("/echo/3.json/");
144			// debug(local.result);
145			assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
146		}
147
148		function test_uri_matching_works_with_trailing_slash_without_extension(){
149			makePublic(variables.taffy, "matchURI");
150			local.result = variables.taffy.matchURI("/echo/3/");
151			// debug(local.result);
152			assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
153		}
154
155		function test_uri_matching_is_sorted_so_static_URIs_take_priority_over_tokens(){
156			makePublic(variables.taffy, "matchURI");
157			local.result = variables.taffy.matchURI("/echo/3");
158			// debug(local.result);
159			assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
160			local.result = variables.taffy.matchURI("/echo/towel");
161			// debug(local.result);
162			assertEquals('^/echo/towel((?:\.)[^\.\?\/]+)?\/?$', local.result);
163		}
164
165		function test_request_parsing_works(){
166			makePublic(variables.taffy,"buildRequestArguments");
167			local.result = variables.taffy.buildRequestArguments(
168				regex = '/echo/([^\/\.]+)$',
169				tokenNamesArray = listToArray("id"),
170				uri = '/echo/16',
171				queryString = 'foo=bar&bar=foo',
172				headers = structNew()
173			);
174			// debug(local.result);
175			assertTrue(structKeyExists(local.result, "foo") && local.result.foo == "bar", "Missing or incorrect value for key `foo`.");
176			assertTrue(structKeyExists(local.result, "bar") && local.result.bar == "foo", "Missing or incorrect value for key `bar`.");
177			assertTrue(structKeyExists(local.result, "id") && local.result.id == 16, "Missing or incorrect value for key `id`.");
178		}
179
180		function test_properly_decodes_urlEncoded_put_request_body(){
181			local.result = apiCall("put", "/echo/99.json", "foo=bar&check=mate");
182			// debug(local.result);
183			if (!isJson(local.result.fileContent)){
184				// debug(local.result.fileContent);
185				fail("Result was not JSON");
186				return local.result.fileContent;
187			}
188			local.result = deserializeJSON(local.result.fileContent);
189			assertTrue(structKeyExists(local.result, "foo") && local.result.foo == "bar", "Missing or incorrect value for key `foo`.");
190			assertTrue(structKeyExists(local.result, "check") && local.result.check == "mate", "Missing or incorrect value for key `check`.");
191		}
192
193		function test_properly_decodes_json_put_request_body(){
194			local.result = apiCall("put", "/echo/99.json", '{"foo":"bar"}');
195			// debug(local.result);
196			if (!isJson(local.result.fileContent)){
197				fail("Result was not JSON");
198				return;
199			}
200			local.result = deserializeJSON(local.result.fileContent);
201			// debug(local.result);
202			assertTrue(structKeyExists(local.result, "foo") && local.result.foo == "bar", "Missing or incorrect value for key `foo`.");
203		}
204
205		function test_properly_decodes_json_post_request_body(){
206			local.result = apiCall("post", "/echo/99.json", '{"foo":"bar"}');
207			// debug(local.result);
208			if (!isJson(local.result.fileContent)){
209				fail("Result was not JSON");
210				return;
211			}
212			local.result = deserializeJSON(local.result.fileContent);
213			// debug(local.result);
214			assertTrue(structKeyExists(local.result, "foo") && local.result.foo == "bar", "Missing or incorrect value for key `foo`.");
215		}
216
217		function test_returns_error_when_requested_mime_not_supported(){
218			local.h = structNew();
219			local.h['Accept'] = "application/NOPE";
220			local.result = apiCall ("get","/echo/2","foo=bar", local.h);
221			// debug(local.result);
222			assertEquals(400, local.result.responseHeader.status_code);
223			assertEquals("Requested mime type is not supported (application/NOPE)", local.result.responseHeader.explanation);
224		}
225
226		function test_extension_takes_precedence_over_accept_header(){
227			local.headers = structNew();
228			local.headers["Accept"] = "text/xml";
229			local.result = apiCall("get","/echo/2.json","foo=bar",local.headers);
230			// debug(local.result);
231			assertEquals(999, local.result.responseHeader.status_code);
232			assertTrue(isJson(local.result.fileContent));
233		}
234
235		function test_allows_regex_as_final_url_value(){
236			makePublic(variables.taffy, "buildRequestArguments");
237			local.headers = structNew();
238			local.headers.Accept = "application/json";
239			local.tokenArray = arrayNew(1);
240			arrayAppend(local.tokenArray, "id");
241			local.result = variables.taffy.buildRequestArguments(
242				"^/echo/([a-zA-Z0-9_\-\.\+]+@[a-zA-Z0-9_\-\.]+\.?[a-zA-Z]+)((?:\.)[^\.\?]+)?$",
243				local.tokenArray,
244				"/echo/foo@bar.com",
245				"",
246				local.headers
247			);
248			// debug(local.result);
249			assertTrue(local.result._taffy_mime eq "json", "Did not detect desired return format correctly.");
250
251			//full integration test for a@b.c.json
252			local.result = apiCall("get", "/echo_regex/12345.json", "", {});
253			// debug(local.result);
254			assert(isJson(local.result.fileContent), "response was not json");
255			local.response = deserializeJSON(local.result.fileContent);
256			assertEquals("12345", local.response.id);
257
258			//full integration test for a@b.c (no .json, but with headers)
259			local.result = apiCall("get", "/echo_regex/12345", "", local.headers);
260			// debug(local.result);
261			assert(isJson(local.result.fileContent), "response was not json");
262			local.response = deserializeJSON(local.result.fileContent);
263			assertEquals("12345", local.response.id);
264		}
265
266		function test_returns_405_for_unimplemented_verbs(){
267			local.result = apiCall("delete", "/echo/2.json", "foo=bar");
268			// debug(local.result);
269			assertEquals(405, local.result.responseHeader.status_code);
270		}
271
272		function test_test_onTaffyRequest_allow(){
273			local.result = apiCall("get","/echo/12.json","refuse=false");
274			// debug(local.result);
275			assertEquals(999,local.result.responseHeader.status_code);
276		}
277
278		function test_onTaffyRequest_deny(){
279			local.result = apiCall("get","/echo/12.json","refuse=true");
280			// debug(local.result);
281			assertEquals(405,local.result.responseHeader.status_code);
282		}
283
284		function test_external_file_request_passes_through(){
285			local.result = getUrl('http://#CGI.SERVER_NAME#:#CGI.SERVER_PORT##replace(cgi.script_name, "/tests/tests/run.cfm", "/tests/someFolder/someOtherFile.cfm")#');
286			debug(local.result);
287			assertTrue(findNoCase('woot', local.result.fileContent), "Was not able to get the DMZ file.");
288		}
289
290		function test_tunnel_PUT_through_POST(){
291			var local = {};
292
293			local.headers["X-HTTP-Method-Override"] = "PUT";
294			local.result = apiCall("post","/echo/tunnel/12.json","", local.headers);
295			// debug(local.result);
296			assertEquals(200,local.result.responseHeader.status_code);
297
298			local.deserializedContent = deserializeJSON( local.result.fileContent );
299			// debug( local.deserializedContent );
300			assertEquals("put", local.deserializedContent.actualMethod);
301		}
302
303		function test_tunnel_DELETE_through_POST(){
304			var local = {};
305
306			local.headers["X-HTTP-Method-Override"] = "DELETE";
307			local.result = apiCall("post","/echo/tunnel/12.json","", local.headers);
308			// debug(local.result);
309			assertEquals(200,local.result.responseHeader.status_code);
310
311			local.deserializedContent = deserializeJSON( local.result.fileContent );
312			// debug( local.deserializedContent );
313			assertEquals("delete", local.deserializedContent.actualMethod);
314		}
315
316		function test_put_body_is_mime_content(){
317			var local = {};
318
319			local.result = apiCall(
320				"put",
321				"/echo/12.json",
322				'{"foo":"The quick brown fox jumped over the lazy dog."}'
323			);
324			// debug(local.result);
325			assertEquals(200,local.result.responseHeader.status_code);
326
327			local.deserializedContent = deserializeJSON( local.result.fileContent );
328			// debug( local.deserializedContent );
329
330			// The service response should contain only the ID parameter, and not anything parsed from the body
331			assertEquals("foo,id,password,username", listSort(structKeylist(local.deserializedContent), "textnocase"));
332			assertEquals(12, local.deserializedContent["id"]);
333			assertEquals("The quick brown fox jumped over the lazy dog.", local.deserializedContent["foo"]);
334		}
335
336		function test_put_body_is_url_encoded_params(){
337			var local = {};
338			local.result = apiCall(
339				"put",
340				"/echo/12.json",
341				"foo=yankee&bar=hotel&baz=foxtrot"
342			);
343			// debug(local.result);
344			assertEquals(200,local.result.responseHeader.status_code);
345
346			local.deserializedContent = deserializeJSON( local.result.fileContent );
347			// debug( local.deserializedContent );
348
349			// The service response should contain the ID parameter and all parsed form fields from the body
350			local.sortedKeys = listSort(structKeylist(local.deserializedContent), "textnocase");
351			//because apparently railo includes fieldnames when ACF doesn't...
352			assertTrue("bar,baz,foo,id,password,username" eq local.sortedKeys or "bar,baz,fieldnames,foo,id,password,username" eq local.sortedKeys);
353			assertEquals(12, local.deserializedContent["id"]);
354			assertEquals("yankee", local.deserializedContent["foo"]);
355			assertEquals("hotel", local.deserializedContent["bar"]);
356			assertEquals("foxtrot", local.deserializedContent["baz"]);
357		}
358
359		function test_get_queryString_keys_without_values_returns_empty_string() {
360			makePublic(variables.taffy, "buildRequestArguments");
361
362			var returnedArguments = variables.taffy.buildRequestArguments(
363				regex = "^/testResource/$",
364				tokenNamesArray = [],
365				uri = "/testResource/",
366				queryString = "keyOne=valueOne&keyTwo=&keyThree=valueThree",
367				headers = {}
368			);
369
370			assertEquals("", returnedArguments["keyTwo"]);
371		}
372
373		function test_returns_allow_header_for_405(){
374			local.result = apiCall("delete","/echo/12.json","");
375			// debug(local.result);
376			assertEquals(405,local.result.responseHeader.status_code);
377			assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
378		}
379
380		function test_returns_allow_header_for_get_200(){
381			local.result = apiCall("get","/echo/tunnel/12.json","");
382			// debug(local.result);
383			assertEquals(200,local.result.responseHeader.status_code);
384			assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
385		}
386
387		function test_returns_allow_header_for_post_201(){
388			local.result = apiCall("post","/echo/tunnel/12.json","");
389			// debug(local.result);
390			assertEquals(201,local.result.responseHeader.status_code);
391			assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
392		}
393
394		function test_returns_allow_header_for_put_200(){
395			local.result = apiCall("put","/echo/tunnel/12.json","");
396			// debug(local.result);
397			assertEquals(200,local.result.responseHeader.status_code);
398			assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
399		}
400
401		function test_returns_allow_header_for_delete_200(){
402			local.result = apiCall("delete","/echo/tunnel/12.json","");
403			// debug(local.result);
404			assertEquals(200,local.result.responseHeader.status_code);
405			assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
406		}
407
408		function test_can_pass_data_from_onTaffyRequest_to_resource(){
409			local.result = apiCall("get", "/echo/dude.json", "hulk=smash");
410			// debug(local.result);
411			local.body = deserializeJSON(local.result.fileContent);
412			assertTrue(structKeyExists(local.body, "dataFromOTR"));
413			assertTrue(local.body.dataFromOTR eq "who let the hulk out?!");
414		}
415
416		function test_reload_on_every_request_setting_works(){
417			application._taffy.settings.reloadOnEveryRequest = false;
418			local.result = apiCall("get", "/echo/dude.json", "");
419			// debug(local.result);
420			assertFalse(structKeyExists(local.result.responseheader, "X-TAFFY-RELOADED"), "Expected reload header to be missing, but it was sent.");
421			application._taffy.settings.reloadOnEveryRequest = true;
422			local.result2 = apiCall("get", "/echo/dude.json", "");
423			// debug(local.result2);
424			assertTrue(structKeyExists(local.result2.responseheader, "X-TAFFY-RELOADED"), "Expected reload header to be sent, but it was missing.");
425		}
426
427		function test_returns_error_when_resource_throws_exception(){
428			local.result = apiCall("get", "/throwException.json", "");
429			// debug(local.result);
430			assertEquals(500, local.result.responseHeader.status_code);
431			assertTrue( isJson( local.result.fileContent ), "Response body was not json" );
432		}
433
434		function test_basic_auth_credentials_found(){
435			local.result = apiCall("get", "/basicauth.json", "", {}, "Towel:42");
436			// debug(local.result);
437			assertTrue(isJson(local.result.fileContent));
438			local.data = deserializeJSON(local.result.fileContent);
439			assertTrue(structKeyExists(local.data, "username"));
440			assertEquals("Towel", local.data.username);
441			assertTrue(structKeyExists(local.data, "password"));
442			assertEquals("42", local.data.password);
443		}
444
445		function test_getHostname_returns_not_blank(){
446			local.hostname = variables.taffy.getHostname();
447			// debug(local.hostname);
448			assertNotEquals( "", local.hostname );
449		}
450
451		function test_envConfig_is_applied(){
452			// debug( application._taffy.settings.reloadPassword );
453			assertEquals( "dontpanic", application._taffy.settings.reloadPassword );
454		}
455
456		function test_use_endpointURLParam_in_GET(){
457			local.result = apiCall('get','?#application._taffy.settings.endpointURLParam#=/echo/2606.json','');
458
459			// debug(local.result);
460			assertEquals(999,val(local.result.statusCode));
461		}
462
463		function test_use_endpointURLParam_in_POST(){
464			local.result = apiCall('post','?#application._taffy.settings.endpointURLParam#=/echo/2606.json','bar=foo');
465
466			// debug(local.result);
467			assertEquals(200,val(local.result.statusCode));
468		}
469
470		function test_use_endpointURLParam_in_PUT(){
471			local.result = apiCall('put','?#application._taffy.settings.endpointURLParam#=/echo/2606.json','bar=foo');
472
473			// debug(local.result);
474			assertEquals(200,val(local.result.statusCode));
475		}
476
477		function test_use_endpointURLParam_in_DELETE(){
478			local.result = apiCall('delete','?#application._taffy.settings.endpointURLParam#=/echo/tunnel/2606.json','');
479
480			// debug(local.result);
481			assertEquals(200,val(local.result.statusCode));
482		}
483
484		function test_allows_dashboard_when_enabled(){
485			var restore = application._taffy.settings.disableDashboard;
486			application._taffy.settings.disableDashboard = false;
487			local.result = apiCall("get", "/", "");
488			// debug(local.result);
489			assertEquals(200, val(local.result.statusCode));
490
491			application._taffy.settings.disableDashboard = restore;
492		}
493
494		function test_returns_403_at_root_when_dashboard_disabled_with_no_redirect(){
495			var restore = application._taffy.settings.disableDashboard;
496			application._taffy.settings.disableDashboard = true;
497			local.result = apiCall("get", "/", "");
498			// debug(local.result);
499			assertEquals(403, val(local.result.statusCode));
500
501			application._taffy.settings.disableDashboard = restore;
502		}
503
504		function test_returns_302_at_root_when_dashboard_disabled_with_redirect(){
505			var restore1 = application._taffy.settings.disableDashboard;
506			var restore2 = application._taffy.settings.disabledDashboardRedirect;
507			application._taffy.settings.disableDashboard = true;
508			application._taffy.settings.disabledDashboardRedirect = 'http://google.com';
509			local.result = apiCall("get", "/", "");
510			// debug(local.result);
511			assertEquals(302, val(local.result.statusCode));
512			assertTrue(structKeyExists(local.result.responseHEader, "location"));
513			assertEquals(application._taffy.settings.disabledDashboardRedirect, local.result.responseHeader.location);
514
515			application._taffy.settings.disableDashboard = restore1;
516			application._taffy.settings.disabledDashboardRedirect = restore2;
517		}
518
519		function test_properly_returns_wrapped_jsonp(){
520			application._taffy.settings.jsonp = "callback";
521			local.result = apiCall("get", "/echo/dude.json?callback=zomg", '');
522			// debug(local.result);
523			assertEquals('zomg(', left(local.result.fileContent, 5), "Does not begin with call to jsonp callback");
524			assertEquals(");", right(local.result.fileContent, 2), "Does not end with `);`");
525		}
526
527		function test_properly_handles_arbitrary_cors_headers(){
528			//see: https://github.com/atuttle/Taffy/issues/144
529			application._taffy.settings.allowCrossDomain = true;
530			local.h = { "Access-Control-Request-Headers" = "goat, pigeon, man-bear-pig", "Origin":"http://#cgi.server_name#/"};
531			local.result = apiCall("get", "/echo/dude.json", "", local.h);
532			//debug(local.result);
533			assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "goat");
534			assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "pigeon");
535			assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "man-bear-pig");
536		}
537
538		function test_properly_handles_arbitrary_cors_headers_on_error(){
539			//see: https://github.com/atuttle/Taffy/issues/159
540			application._taffy.settings.allowCrossDomain = true;
541			local.h = { "Access-Control-Request-Headers" = "goat, pigeon, man-bear-pig", "Origin":"http://#cgi.server_name#/"};
542			local.result = apiCall("get", "/throwException.json", "", local.h);
543			// debug(local.result);
544			assertTrue(structKeyExists(local.result.responseHeader, "Access-Control-Allow-Origin"));
545			assertTrue(structKeyExists(local.result.responseHeader, "Access-Control-Allow-Methods"));
546			assertTrue(structKeyExists(local.result.responseHeader, "Access-Control-Allow-Headers"));
547			assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "goat");
548			assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "pigeon");
549			assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "man-bear-pig");
550		}
551
552		function test_non_struct_json_body_sent_to_resource_as_underscore_body(){
553			//see: https://github.com/atuttle/Taffy/issues/169
554			local.result = apiCall("post", "/echo/5", "[1,2,3]");
555			// debug(local.result);
556			local.response = deserializeJSON(local.result.fileContent);
557			assertTrue(structKeyExists(local.response, "_body"));
558			assertTrue(isArray(local.response._body));
559			assertTrue(arrayLen(local.response._body) == 3);
560		}
561
562		function test_comma_delim_list_of_uris_for_alias(){
563
564			//works with /echo_alias/{ID}
565			local.result = apiCall("get", "/echo_alias/4", "");
566			//debug(local.result);
567
568			assertEquals(200, val(local.result.statusCode));
569			assertEquals(serializeJSON({ID="4"}), local.result.fileContent);
570
571			//works with /echo_alias
572			local.result = apiCall("get", "/echo_alias", "");
573			// debug(local.result);
574			assertEquals(200, val(local.result.statusCode));
575			assertEquals(serializeJSON({ID="0"}), local.result.fileContent);
576
577			//works with /echo_alias/ (trailing slash)
578			local.result = apiCall("get", "/echo_alias/", "");
579			// debug(local.result);
580			assertEquals(200, val(local.result.statusCode));
581			assertEquals(serializeJSON({ID="0"}), local.result.fileContent);
582
583			//works with /echo_alias?ID=x
584			local.result = apiCall("get", "/echo_alias", "ID=2");
585			// debug(local.result);
586			assertEquals(200, val(local.result.statusCode));
587			assertEquals(serializeJSON({ID="2"}), local.result.fileContent);
588		}
589	</cfscript>
590
591
592	<cffunction name="test_can_upload_a_file">
593		<cfset var local = structNew() />
594		<cfset local.apiRootURL	= getDirectoryFromPath(cgi.script_name) />
595		<cfset local.apiRootURL	= listDeleteAt(local.apiRootURL,listLen(local.apiRootURL,'/'),'/') />
596		<cfhttp
597			url="http://#cgi.server_name#:#cgi.server_port##local.apiRootURL#/index.cfm/upload"
598			method="post"
599			result="local.uploadResult">
600			<cfhttpparam type="file" name="img" file="#expandPath('/taffy/tests/tests/upload.png')#" />
601		</cfhttp>
602		<!--- <cfset debug(local.uploadResult) /> --->
603		<cfset assertTrue(local.uploadResult.statusCode eq "200 OK", "Did not return status 200") />
604	</cffunction>
605
606	<cffunction name="test_throws_exception_when_ressource_uri_doesnt_begin_with_forward_slash">
607		<cfset assertTrue(checkIfOneSkippedRessourceContainsExpectedException("detail", "The URI (uriWithoutForwardSlash) for `uriDoesntBeginWithForwardSlash` should begin with a forward slash."), "Uri without forward slash not showing in errors")>
608	</cffunction>
609
610	<cffunction name="test_throws_exception_when_alias_ressource_uri_doesnt_begin_with_forward_slash">
611		<cfset assertTrue(checkIfOneSkippedRessourceContainsExpectedException("detail", "The URI (uriAliasWithoutFowardSlash) for `uriAliasDoesntBeginWithForwardSlash` should begin with a forward slash."), "Uri alias without forward slash not showing in errors")>
612	</cffunction>
613
614</cfcomponent>