initial
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
<cfcomponent>
|
||||
|
||||
<cfset this.name = 'Taffy_testSuite' /> <!---uses the same application name as the api Application.cfc for scope sharing --->
|
||||
|
||||
<cfset this.appDirectory = getDirectoryFromPath(getCurrentTemplatePath())>
|
||||
<cfset this.parentDirectory = reReplace(this.appDirectory, "(.+[/\\])tests[/\\]$", "\1")>
|
||||
<cfset this.mappings = structNew()>
|
||||
<cfset this.mappings["/mxunit"] = this.parentDirectory & "testbox/system/compat/">
|
||||
<cfset this.mappings["/testbox"] = this.parentDirectory & "testbox/">
|
||||
<cfset this.mappings["/Hoth"] = this.parentDirectory & "Hoth/">
|
||||
<cfset this.mappings["/di1"] = this.parentDirectory & "di1/">
|
||||
<cfset this.mappings["/bugLog"] = this.parentDirectory & "BugLogHQ/">
|
||||
|
||||
<cfscript>
|
||||
//remove bugLogHQ Application.cfc so we can override datasource definition
|
||||
if (fileExists("#this.parentDirectory#/BugLogHQ/Application.cfc")) {
|
||||
fileDelete("#this.parentDirectory#/BugLogHQ/Application.cfc");
|
||||
}
|
||||
</cfscript>
|
||||
|
||||
<cffunction name="onRequestStart" returnType="void" access="public" output="false">
|
||||
<cfif NOT isDefined('application._taffy')>
|
||||
<cfset local.apiRootURL = getDirectoryFromPath(cgi.script_name) />
|
||||
<cfset local.apiRootURL = listDeleteAt(local.apiRootURL,listLen(local.apiRootURL,'/'),'/') />
|
||||
<cfhttp method="GET" url="http://#CGI.SERVER_NAME#:#CGI.SERVER_PORT##local.apiRootURL#/index.cfm" />
|
||||
</cfif>
|
||||
</cffunction>
|
||||
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,207 @@
|
||||
<cfcomponent hint="automatic test suite runner">
|
||||
|
||||
<cfset this.s_results = StructNew()>
|
||||
<cfset this.s_results.Errors = StructNew()>
|
||||
<cfset sep = createObject("java","java.lang.System").getProperty("file.separator")>
|
||||
|
||||
<cffunction name="run" access="public" hint="runs a directory of tests" returntype="any" output="false">
|
||||
<cfargument name="directory" required="true" hint="directory of tests to run">
|
||||
<cfargument name="componentPath" required="false" hint="the component path to put in front of all tests found (i.e. 'com.blah'). If no path is passed, we'll attempt to discover it ourselves" default="">
|
||||
<cfargument name="recurse" required="false" type="boolean" default="true" hint="whether to recurse down the directory tree">
|
||||
<cfargument name="excludes" required="false" default="" hint="list of Tests, in cfc notation, to exclude. uses ListContains so it's as greedy as possible. Currently does not support ant-style syntax or whole-directory filtering">
|
||||
<cfargument name="refreshCache" required="false" default="false" hint="flag to indicate whether or not to refresh the CF cache of CFCs. Maybe needed if any of the tests in the directory have not yet been compiled - to do: prove" />
|
||||
|
||||
<cfset var testResult = "">
|
||||
<cfset var files = "">
|
||||
<cfset var suite = createObject("component","mxunit.framework.TestSuite")>
|
||||
<cfset var i = 1>
|
||||
|
||||
<cfset arguments.directory = normalizeDirectory(arguments.directory)>
|
||||
|
||||
<cfif NOT len(arguments.componentPath)>
|
||||
<cfset arguments.componentPath = getComponentPath(arguments.directory, arguments.refreshCache)>
|
||||
</cfif>
|
||||
|
||||
<cfset files = getTests(arguments.directory,arguments.componentPath,arguments.recurse,trim(arguments.excludes)) />
|
||||
|
||||
<cfloop from="1" to="#ArrayLen(files)#" index="i">
|
||||
<cftry>
|
||||
<cfset suite.addAll(files[i])>
|
||||
|
||||
<cfcatch>
|
||||
<cfset this.s_results.Errors[files[i]] = cfcatch>
|
||||
</cfcatch>
|
||||
</cftry>
|
||||
</cfloop>
|
||||
|
||||
<cfset testResult = suite.run()>
|
||||
|
||||
<cfset testResult.mergeErrorsIntoTestResult(this.s_results.Errors)>
|
||||
|
||||
<cfreturn testResult>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="getTests" access="private" output="false">
|
||||
<cfargument name="directory" required="true" hint="directory of tests to run">
|
||||
<cfargument name="componentPath" required="true" hint="the component path to put in front of all tests found (i.e. 'com.blah')">
|
||||
<cfargument name="recurse" required="false" default="true" type="boolean" hint="whether to recurse down the directory tree">
|
||||
<cfargument name="excludes" required="false" default="" hint="ant-style syntax for excluding single files or directories">
|
||||
<cfset var q_tests = getDirectoryQuery(directory,recurse)>
|
||||
<cfset var a_tests = ArrayNew(1)>
|
||||
<cfset var testPath = "">
|
||||
|
||||
<cfloop query="q_tests">
|
||||
<cfset testPath = formatTestPath(arguments.directory, q_tests.directory & sep & q_tests.Name,arguments.componentPath)>
|
||||
|
||||
<cfif accept(testPath,arguments.excludes)>
|
||||
<cftry>
|
||||
<!---
|
||||
Compile first. This ensures that any new tests NOT found in the server cache get added.
|
||||
This may actually be quicker than searching the array and then conditionally compiling.
|
||||
Appears not to have much overhead, but, we should monitor anyway for large test runs.
|
||||
--->
|
||||
<cfset createObject("component","#testPath#") />
|
||||
<cfcatch type="any"><!--- no worries ---></cfcatch>
|
||||
</cftry>
|
||||
<cfset ArrayAppend(a_tests,testPath)>
|
||||
</cfif>
|
||||
</cfloop>
|
||||
<cfreturn a_tests>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="formatTestPath" access="private" output="false">
|
||||
<cfargument name="directory" required="true" hint="directory of tests to run">
|
||||
<cfargument name="fullFilePath">
|
||||
<cfargument name="componentPath" required="true" hint="the component path to put in front of all tests found (i.e. 'com.blah')">
|
||||
|
||||
<cfset var formatted = replaceNoCase(fullFilePath,directory,"")>
|
||||
<cfset formatted = reverse( replace(reverse(formatted),"cfc.","") )>
|
||||
<cfset formatted = componentPath & "." & formatted>
|
||||
<cfset formatted = reReplace(formatted, "(\\|/|\.){1,}" ,".","all")>
|
||||
<cfreturn formatted>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="getDirectoryQuery" access="private" returntype="query" output="false">
|
||||
<cfargument name="directory" required="true" hint="directory of tests to run">
|
||||
<cfargument name="recurse" type="boolean" required="false" default="true" hint="whether to recurse down the directory tree">
|
||||
<cfset var files = "">
|
||||
<cfset var runnerUtils = "">
|
||||
|
||||
<cfif not DirectoryExists(arguments.directory)>
|
||||
<cfthrow message="Directory #directory# does not exist">
|
||||
</cfif>
|
||||
|
||||
<cfdirectory action="list" directory="#arguments.directory#" name="files" recurse="#arguments.recurse#" filter="*.cfc">
|
||||
|
||||
<cfreturn files>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="getCatastrophicErrors" output="false">
|
||||
<cfreturn this.s_results.Errors>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="accept" hint="rudimentary initial implementation." access="private" output="false">
|
||||
<cfargument name="test" required="true">
|
||||
<cfargument name="excludes" required="true">
|
||||
|
||||
<cfset var testName = ListLast(arguments.test,".")>
|
||||
<cfset var thisExclude = "">
|
||||
|
||||
<cfif NOT reFindNoCase("^test",testName) AND NOT reFindNoCase("test$",testName)>
|
||||
<cfreturn false>
|
||||
</cfif>
|
||||
<cfif not len(excludes)>
|
||||
<cfreturn true>
|
||||
</cfif>
|
||||
|
||||
<cfset arguments.test = ListChangeDelims(arguments.test,"/",".")>
|
||||
<cfloop list="#excludes#" index="thisExclude" delimiters=",">
|
||||
<cfset thisExclude = replace(thisExclude,"\","/")>
|
||||
<cfif reFindNoCase("\b#thisExclude#\b",arguments.test)>
|
||||
<cfreturn false>
|
||||
</cfif>
|
||||
</cfloop>
|
||||
<cfreturn true>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="normalizeDirectory" hint="makes sure every directory has ending slashes" access="private" output="false">
|
||||
<cfargument name="Directory" type="string" required="true"/>
|
||||
<cfset var dir = createObject("java","java.io.File")>
|
||||
|
||||
<cfif not DirectoryExists(arguments.directory)>
|
||||
<cfset arguments.directory = expandPath(arguments.directory) />
|
||||
<cfif not DirectoryExists(arguments.directory)>
|
||||
<cfthrow message="Directory #directory# does not exist">
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
<cfset dir.init(arguments.directory)>
|
||||
<cfset arguments.directory = dir.getCanonicalPath()>
|
||||
<cfset arguments.directory = replaceList(arguments.directory,"/,\","#sep#,#sep#")>
|
||||
<cfset arguments.directory = arguments.directory & sep>
|
||||
<cfreturn arguments.directory>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="getComponentPath" access="remote" returntype="string" hint="Given a directory path, returns the corresponding CFC package according to CFMX" output="false">
|
||||
<cfargument name="path" type="string" required="true" />
|
||||
<cfargument name="refreshCache" type="boolean" required="false" default="false" />
|
||||
<cfscript>
|
||||
var explorer = createObject("component", "CFIDE.componentutils.cfcexplorer");
|
||||
var target = explorer.normalizePath(arguments.path);
|
||||
var cfcs = explorer.getcfcs(refreshCache); //true == refresh cache
|
||||
var cfc = "";
|
||||
var i = 1 ;
|
||||
var package = "";
|
||||
var cfcpath = "";
|
||||
|
||||
for(i = 1; i lte arraylen(cfcs); i = i+1){
|
||||
cfc = cfcs[i];
|
||||
//Assumes that CF always stores path info with fwd slash
|
||||
//and strip last element to get path.
|
||||
cfcpath = ListDeleteAt(cfc.path, listlen(cfc.path,"/"), "/");
|
||||
|
||||
//Array of structs. Doesn't seem possible to do binary search
|
||||
if(cfcpath eq target){
|
||||
|
||||
package = cfc.package;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return package;
|
||||
</cfscript>
|
||||
</cffunction>
|
||||
|
||||
|
||||
<cffunction name="getComponentPathx" access="remote" returntype="string" hint="Given a directory path, returns the corresponding CFC package" output="false">
|
||||
<cfargument name="path" type="string" required="true" />
|
||||
<cfargument name="refreshCache" type="boolean" required="false" default="false" />
|
||||
|
||||
<cfset var files = '' />
|
||||
<cfset var package = '' />
|
||||
|
||||
<cfdirectory action="list" type="file" name="files" directory="#arguments.path#" filter="*.cfc" />
|
||||
|
||||
<cfif files.recordCount>
|
||||
<cfset package = replace(normalizePath(files.directory), '/', '.', 'all') />
|
||||
</cfif>
|
||||
|
||||
<cfreturn package />
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="normalizePath" access="public" returntype="string" output="false">
|
||||
<cfargument name="path" type="string" required="true" />
|
||||
|
||||
<cfif not len(arguments.path)>
|
||||
<cfreturn arguments.path />
|
||||
</cfif>
|
||||
|
||||
<cfset arguments.path = replace(arguments.path, '\', '/', 'all') />
|
||||
|
||||
<cfif right(arguments.path, 1) eq '/'>
|
||||
<cfset arguments.path = left(arguments.path, len(arguments.path) - 1) />
|
||||
</cfif>
|
||||
|
||||
<cfreturn arguments.path />
|
||||
</cffunction>
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,92 @@
|
||||
<cfcomponent output="true">
|
||||
<cfsetting enablecfoutputonly="true" showdebugoutput="false">
|
||||
|
||||
<cffunction name="run" access="remote" output="true" returntype="void" hint="Generates and prints HTML, JUnit style XML, or XML data based on a directory of tests.">
|
||||
<cfargument name="type" type="string" hint="Specifies the type to run: TestCase(testcase) or Directory Path (dir)" required="true" />
|
||||
<cfargument name="value" type="string" hint="The value for the type: com.foo.MyTestCase or C:/my/tests/" required="true" />
|
||||
<cfargument name="packagename" type="string" hint="The package name for JUnitReportTask" required="false" default="mxunit.testresults" />
|
||||
<cfargument name="outputformat" type="string" hint="Valid Values: HTML,XML, or JUNITXML" required="false" default="junitxml" />
|
||||
<cfargument name="recurse" required="false" default="true" hint="whether to recurse down the directory tree">
|
||||
<cfargument name="excludes" required="false" default="" hint="List of files to exclude if type is DIR">
|
||||
<cfargument name="componentPath" required="false" hint="performance improver: pass the cfc-notation. See DirectoryTestSuite for details." default="">
|
||||
|
||||
<cfset var suite = createObject("component","mxunit.framework.TestSuite").TestSuite()/>
|
||||
<cfset var results = createObject("component","mxunit.framework.TestResult").TestResult()/>
|
||||
<cfscript>
|
||||
if(arguments.type is "testcase"){
|
||||
suite = createObject("component","mxunit.framework.TestSuite").TestSuite();
|
||||
suite.addAll(arguments.value);
|
||||
results = suite.run();
|
||||
}
|
||||
if(arguments.type is "dir"){
|
||||
//To Do: add args for recursion, includes, and excludes
|
||||
if(not isBoolean(arguments.recurse)){
|
||||
arguments.recurse = false;
|
||||
}
|
||||
|
||||
results = createObject("component","DirectoryTestSuite").run(directory=arguments.value, componentPath=arguments.componentPath, recurse=arguments.recurse, excludes=arguments.excludes);
|
||||
}
|
||||
//package name for JUnit reports
|
||||
results.setPackage(arguments.packagename);
|
||||
</cfscript>
|
||||
<!--- Read by Ant client and used to print summary to stdout --->
|
||||
<cfcookie name="mxunit_summary" value="#results.testRuns#,#results.testErrors#,#results.testFailures#,#results.totalExecutionTime#" />
|
||||
<!--- write the cookie first --->
|
||||
<cfset printResults(arguments.outputformat,results) />
|
||||
<cfreturn />
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="printResults" access="private">
|
||||
<cfargument name="type">
|
||||
<cfargument name="results">
|
||||
<cfoutput>
|
||||
<cfswitch expression="#type#">
|
||||
<cfcase value="html">
|
||||
#trim(arguments.results.getHTMLResults())#
|
||||
</cfcase>
|
||||
<cfcase value="xml">
|
||||
#trim(arguments.results.getXMLResults())#
|
||||
</cfcase>
|
||||
<cfcase value="junitxml">
|
||||
#trim(arguments.results.getJUnitXMLResults())#
|
||||
</cfcase>
|
||||
<cfdefaultcase>#trim(arguments.results.getJUnitXMLResults())#</cfdefaultcase>
|
||||
</cfswitch>
|
||||
</cfoutput>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="runFast" access="remote" output="true" returntype="void" hint="Generates and prints HTML, JUnit style XML, or XML data based on a directory of tests.">
|
||||
<cfargument name="type" type="string" hint="Specifies the type to run: TestCase(testcase) or Directory Path (dir)" required="true" />
|
||||
<cfargument name="value" type="string" hint="The value for the type: com.foo.MyTestCase or C:/my/tests/" required="true" />
|
||||
<cfargument name="packagename" type="string" hint="The package name for JUnitReportTask" required="false" default="mxunit.testresults" />
|
||||
<cfargument name="outputformat" type="string" hint="Valid Values: HTML,XML, or JUNITXML" required="false" default="junitxml" />
|
||||
<cfargument name="recurse" required="false" default="true" hint="whether to recurse down the directory tree">
|
||||
<cfargument name="excludes" required="false" default="" hint="List of files to exclude if type is DIR">
|
||||
<cfargument name="componentPath" required="false" hint="performance improver: pass the cfc-notation. See DirectoryTestSuite for details." default="">
|
||||
|
||||
<cfset var suite = createObject("component","mxunit.framework.TestSuite").TestSuite()/>
|
||||
<cfset var results = createObject("component","mxunit.framework.TestResult").TestResult()/>
|
||||
<cfscript>
|
||||
if(arguments.type is "testcase"){
|
||||
suite = createObject("component","mxunit.framework.TestSuite").TestSuite();
|
||||
suite.addAll(arguments.value);
|
||||
results = suite.run();
|
||||
}
|
||||
if(arguments.type is "dir"){
|
||||
//To Do: add args for recursion, includes, and excludes
|
||||
if(not isBoolean(arguments.recurse)){
|
||||
arguments.recurse = false;
|
||||
}
|
||||
|
||||
results = createObject("component","DirectoryTestSuite").run(directory=arguments.value, componentPath=arguments.componentPath, recurse=arguments.recurse, excludes=arguments.excludes);
|
||||
}
|
||||
//package name for JUnit reports
|
||||
results.setPackage(arguments.packagename);
|
||||
</cfscript>
|
||||
<!--- Read by Ant client and used to print summary to stdout --->
|
||||
<cfcookie name="mxunit_summary" value="#results.testRuns#,#results.testErrors#,#results.testFailures#,#results.totalExecutionTime#" />
|
||||
<!--- write the cookie first
|
||||
<cfset printResults(arguments.outputformat,results) /> --->
|
||||
<cfreturn />
|
||||
</cffunction>
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1 @@
|
||||
<cfcomponent extends="mxunit.framework.RemoteFacade"></cfcomponent>
|
||||
@@ -0,0 +1,22 @@
|
||||
<cfcomponent extends="base">
|
||||
|
||||
<cffunction name="setup">
|
||||
<cfset reloadFramework()>
|
||||
</cffunction>
|
||||
|
||||
<cfscript>
|
||||
function beforeTests(){
|
||||
variables.taffy = createObject("component","taffy.tests.Application");
|
||||
makePublic(variables.taffy, "getBeanFactory");
|
||||
variables.factory = variables.taffy.getBeanFactory();
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resourcesConflict'), 'taffy.tests.resourcesConflict', expandPath('/taffy/tests/resourcesConflict'), true, variables.taffy);
|
||||
|
||||
}
|
||||
|
||||
function test_conflicting_URIs_get_skipped() {
|
||||
assertTrue(checkIfOneSkippedRessourceContainsExpectedException("errorCode", "taffy.resources.DuplicateUriPattern"), "Conflicting URIs not showing in errors");
|
||||
}
|
||||
</cfscript>
|
||||
|
||||
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,645 @@
|
||||
<cfcomponent extends="base">
|
||||
|
||||
<cffunction name="setup">
|
||||
<cfset reloadFramework()>
|
||||
</cffunction>
|
||||
|
||||
<cfscript>
|
||||
function beforeTests(){
|
||||
variables.taffy = createObject("component","taffy.tests.Application");
|
||||
makePublic(variables.taffy, "getBeanFactory");
|
||||
variables.factory = variables.taffy.getBeanFactory();
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resources'), 'taffy.tests.resources', expandPath('/taffy/tests/resources'), true );
|
||||
}
|
||||
|
||||
function test_properly_notifies_unimplemented_mimes(){
|
||||
makePublic(variables.taffy, "mimeSupported");
|
||||
// debug(variables.taffy);
|
||||
// debug(application);
|
||||
assertFalse(taffy.mimeSupported("DoesNotExist"), "When given a mime type that should not exist, Taffy reported that it did.");
|
||||
}
|
||||
|
||||
function test_properly_notifies_implemented_mimes(){
|
||||
makePublic(variables.taffy, "mimeSupported");
|
||||
makePublic(variables.taffy, "inspectMimeTypes");
|
||||
variables.taffy.inspectMimeTypes('taffy.core.nativeJsonSerializer', variables.taffy.getBeanFactory());
|
||||
assertTrue(taffy.mimeSupported("json"));
|
||||
assertTrue(taffy.mimeSupported("text/json"));
|
||||
assertTrue(taffy.mimeSupported("application/json"));
|
||||
}
|
||||
|
||||
function test_returns_access_control_expose_headers_header(){
|
||||
local.result = apiCall("get", "/echo/foo.json", "");
|
||||
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "Access-Control-Expose-Headers"));
|
||||
debug(local.result.responseHeader["Access-Control-Expose-Headers"]);
|
||||
assertTrue(findNoCase("Etag", local.result.responseHeader["Access-Control-Expose-Headers"]));
|
||||
}
|
||||
|
||||
function test_returns_etag_header(){
|
||||
//both requests should yield the same etag header
|
||||
local.result = apiCall("get", "/echo/foo.json", "");
|
||||
local.result2 = apiCall("get", "/echo/foo.json", "");
|
||||
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "Etag"));
|
||||
assertTrue(structKeyExists(local.result2.responseHeader, "Etag"));
|
||||
assertEquals(local.result2.responseHeader.etag, local.result.responseHeader.etag);
|
||||
}
|
||||
|
||||
function test_returns_304_when_not_modified(){
|
||||
local.result = apiCall("get", "/echo/foo.json", "");
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "Etag"));
|
||||
|
||||
local.h = {};
|
||||
local.h['if-none-match'] = local.result.responseHeader.etag;
|
||||
local.result = apiCall("get", "/echo/foo.json", "", local.h);
|
||||
debug(local.result);
|
||||
assertEquals(304, val(local.result.responseHeader.status_code));
|
||||
}
|
||||
|
||||
function test_json_result_is_json(){
|
||||
local.result = apiCall ("get","/echo/2.json","bar=foo");
|
||||
// debug(local.result);
|
||||
assertTrue(isJson(local.result.fileContent), "Expected JSON content back but was not able to identify it as such.");
|
||||
}
|
||||
|
||||
function test_custom_status_is_returned(){
|
||||
local.result = apiCall("get", "/echo/1.json?foo=bar", "");
|
||||
// debug(local.result);
|
||||
// debug(application);
|
||||
assertEquals(999, local.result.responseHeader.status_code, "Expected status code 999 but got something else.");
|
||||
}
|
||||
|
||||
function test_custom_headers_work(){
|
||||
local.result = apiCall("get", "/echo/-1.json", "");
|
||||
// debug(local.result);
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "x-dude"), "Expected response header `x-dude` but it was not included.");
|
||||
}
|
||||
|
||||
function test_global_headers_work(){
|
||||
local.result = apiCall("get", "/echo/1.json", "");
|
||||
// debug(local.result);
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "x-foo-globalheader"), "Expected response header `x-foo-globalheader` but it was not included.");
|
||||
}
|
||||
|
||||
function test_deserializer_inspection_finds_all_content_types(){
|
||||
makePublic(variables.taffy, "getSupportedContentTypes");
|
||||
local.result = variables.taffy.getSupportedContentTypes("taffy.core.baseDeserializer");
|
||||
// debug(local.result);
|
||||
assertTrue(structKeyExists(local.result, "application/x-www-form-urlencoded"));
|
||||
local.result = variables.taffy.getSupportedContentTypes("taffy.core.nativeJsonDeserializer");
|
||||
// debug(local.result);
|
||||
assertTrue(structKeyExists(local.result, "application/json"));
|
||||
assertTrue(structKeyExists(local.result, "text/json"));
|
||||
assertTrue(structKeyExists(local.result, "application/x-www-form-urlencoded"));
|
||||
}
|
||||
|
||||
function test_deserializer_support_detection_works(){
|
||||
makePublic(variables.taffy, "contentTypeIsSupported");
|
||||
// debug(application._taffy.contentTypes);
|
||||
assertTrue(variables.taffy.contentTypeIsSupported("application/json"));
|
||||
assertTrue(variables.taffy.contentTypeIsSupported("application/json;v=1"));
|
||||
assertFalse(variables.taffy.contentTypeIsSupported("application/does-not-exist"));
|
||||
}
|
||||
|
||||
function test_uri_regexes_are_correct(){
|
||||
makePublic(variables.taffy, "convertURItoRegex");
|
||||
|
||||
local.result = taffy.convertURItoRegex("/a/{abc}/b");
|
||||
// debug(local.result);
|
||||
assertEquals( "^/a/([^\/]+)/b((?:\.)[^\.\?\/]+)?\/?$", local.result["uriregex"], "Resulted regex did not match expected. (assert 1)");
|
||||
assertEquals( 1, arrayLen(local.result["tokens"]), "assert 2" );
|
||||
assertEquals( "abc", local.result["tokens"][1], "assert 3" );
|
||||
|
||||
local.result2 = taffy.convertURItoRegex("/a/{abc}");
|
||||
// debug(local.result2);
|
||||
assertEquals( "^/a/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$", local.result2["uriregex"], "Resulted regex did not match expected.");
|
||||
assertEquals( 1, arrayLen(local.result2["tokens"]) );
|
||||
assertEquals( "abc", local.result2["tokens"][1] );
|
||||
|
||||
//custom regexes for tokens
|
||||
local.result3 = taffy.convertURItoRegex("/a/{b:[a-z]+(?:42){1}}");
|
||||
// debug(local.result3);
|
||||
assertEquals( "^/a/([a-z]+(?:42){1})((?:\.)[^\.\?\/]+)?\/?$", local.result3["uriregex"], "Resulted regex did not match expected. (assert 7)");
|
||||
assertEquals( 1, arrayLen(local.result3["tokens"]), "assert 8" );
|
||||
assertEquals( "b", local.result3["tokens"][1], "assert 9" );
|
||||
|
||||
local.result4 = taffy.convertURItoRegex("/a/{b:[0-4]{1,7}(?:aaa){1}}/c/{d:\d+}");
|
||||
// debug(local.result4);
|
||||
assertEquals( "^/a/([0-4]{1,7}(?:aaa){1})/c/(\d+)((?:\.)[^\.\?\/]+)?\/?$", local.result4["uriregex"], "Resulted regex did not match expected. (assert 10)");
|
||||
assertEquals( 2, arrayLen(local.result4["tokens"]), "assert 11" );
|
||||
assertEquals( "b", local.result4["tokens"][1], "assert 12" );
|
||||
assertEquals( "d", local.result4["tokens"][2], "assert 13" );
|
||||
}
|
||||
|
||||
function test_uri_matching_works_with_extension(){
|
||||
makePublic(variables.taffy, "matchURI");
|
||||
local.result = variables.taffy.matchURI("/echo/3.json");
|
||||
// debug(local.result);
|
||||
assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
|
||||
}
|
||||
|
||||
function test_uri_matching_works_without_extension(){
|
||||
makePublic(variables.taffy, "matchURI");
|
||||
local.result = variables.taffy.matchURI("/echo/3");
|
||||
// debug(local.result);
|
||||
assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
|
||||
}
|
||||
|
||||
function test_uri_matching_works_with_trailing_slash_with_extension(){
|
||||
makePublic(variables.taffy, "matchURI");
|
||||
local.result = variables.taffy.matchURI("/echo/3.json/");
|
||||
// debug(local.result);
|
||||
assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
|
||||
}
|
||||
|
||||
function test_uri_matching_works_with_trailing_slash_without_extension(){
|
||||
makePublic(variables.taffy, "matchURI");
|
||||
local.result = variables.taffy.matchURI("/echo/3/");
|
||||
// debug(local.result);
|
||||
assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
|
||||
}
|
||||
|
||||
function test_uri_matching_is_sorted_so_static_URIs_take_priority_over_tokens(){
|
||||
makePublic(variables.taffy, "matchURI");
|
||||
local.result = variables.taffy.matchURI("/echo/3");
|
||||
// debug(local.result);
|
||||
assertEquals('^/echo/(?:(?:([^\/\.]+)(?:\.)([a-za-z0-9]+))\/?|([^\/\.]+))((?:\.)[^\.\?\/]+)?\/?$', local.result);
|
||||
local.result = variables.taffy.matchURI("/echo/towel");
|
||||
// debug(local.result);
|
||||
assertEquals('^/echo/towel((?:\.)[^\.\?\/]+)?\/?$', local.result);
|
||||
}
|
||||
|
||||
function test_request_parsing_works(){
|
||||
makePublic(variables.taffy,"buildRequestArguments");
|
||||
local.result = variables.taffy.buildRequestArguments(
|
||||
regex = '/echo/([^\/\.]+)$',
|
||||
tokenNamesArray = listToArray("id"),
|
||||
uri = '/echo/16',
|
||||
queryString = 'foo=bar&bar=foo',
|
||||
headers = structNew()
|
||||
);
|
||||
// debug(local.result);
|
||||
assertTrue(structKeyExists(local.result, "foo") && local.result.foo == "bar", "Missing or incorrect value for key `foo`.");
|
||||
assertTrue(structKeyExists(local.result, "bar") && local.result.bar == "foo", "Missing or incorrect value for key `bar`.");
|
||||
assertTrue(structKeyExists(local.result, "id") && local.result.id == 16, "Missing or incorrect value for key `id`.");
|
||||
}
|
||||
|
||||
function test_properly_decodes_urlEncoded_put_request_body(){
|
||||
local.result = apiCall("put", "/echo/99.json", "foo=bar&check=mate");
|
||||
// debug(local.result);
|
||||
if (!isJson(local.result.fileContent)){
|
||||
// debug(local.result.fileContent);
|
||||
fail("Result was not JSON");
|
||||
return local.result.fileContent;
|
||||
}
|
||||
local.result = deserializeJSON(local.result.fileContent);
|
||||
assertTrue(structKeyExists(local.result, "foo") && local.result.foo == "bar", "Missing or incorrect value for key `foo`.");
|
||||
assertTrue(structKeyExists(local.result, "check") && local.result.check == "mate", "Missing or incorrect value for key `check`.");
|
||||
}
|
||||
|
||||
function test_properly_decodes_json_put_request_body(){
|
||||
local.result = apiCall("put", "/echo/99.json", '{"foo":"bar"}');
|
||||
// debug(local.result);
|
||||
if (!isJson(local.result.fileContent)){
|
||||
fail("Result was not JSON");
|
||||
return;
|
||||
}
|
||||
local.result = deserializeJSON(local.result.fileContent);
|
||||
// debug(local.result);
|
||||
assertTrue(structKeyExists(local.result, "foo") && local.result.foo == "bar", "Missing or incorrect value for key `foo`.");
|
||||
}
|
||||
|
||||
function test_properly_decodes_json_post_request_body(){
|
||||
local.result = apiCall("post", "/echo/99.json", '{"foo":"bar"}');
|
||||
// debug(local.result);
|
||||
if (!isJson(local.result.fileContent)){
|
||||
fail("Result was not JSON");
|
||||
return;
|
||||
}
|
||||
local.result = deserializeJSON(local.result.fileContent);
|
||||
// debug(local.result);
|
||||
assertTrue(structKeyExists(local.result, "foo") && local.result.foo == "bar", "Missing or incorrect value for key `foo`.");
|
||||
}
|
||||
|
||||
function test_returns_error_when_requested_mime_not_supported(){
|
||||
local.h = structNew();
|
||||
local.h['Accept'] = "application/NOPE";
|
||||
local.result = apiCall ("get","/echo/2","foo=bar", local.h);
|
||||
// debug(local.result);
|
||||
assertEquals(400, local.result.responseHeader.status_code);
|
||||
assertEquals("Requested mime type is not supported (application/NOPE)", local.result.responseHeader.explanation);
|
||||
}
|
||||
|
||||
function test_extension_takes_precedence_over_accept_header(){
|
||||
local.headers = structNew();
|
||||
local.headers["Accept"] = "text/xml";
|
||||
local.result = apiCall("get","/echo/2.json","foo=bar",local.headers);
|
||||
// debug(local.result);
|
||||
assertEquals(999, local.result.responseHeader.status_code);
|
||||
assertTrue(isJson(local.result.fileContent));
|
||||
}
|
||||
|
||||
function test_allows_regex_as_final_url_value(){
|
||||
makePublic(variables.taffy, "buildRequestArguments");
|
||||
local.headers = structNew();
|
||||
local.headers.Accept = "application/json";
|
||||
local.tokenArray = arrayNew(1);
|
||||
arrayAppend(local.tokenArray, "id");
|
||||
local.result = variables.taffy.buildRequestArguments(
|
||||
"^/echo/([a-zA-Z0-9_\-\.\+]+@[a-zA-Z0-9_\-\.]+\.?[a-zA-Z]+)((?:\.)[^\.\?]+)?$",
|
||||
local.tokenArray,
|
||||
"/echo/foo@bar.com",
|
||||
"",
|
||||
local.headers
|
||||
);
|
||||
// debug(local.result);
|
||||
assertTrue(local.result._taffy_mime eq "json", "Did not detect desired return format correctly.");
|
||||
|
||||
//full integration test for a@b.c.json
|
||||
local.result = apiCall("get", "/echo_regex/12345.json", "", {});
|
||||
// debug(local.result);
|
||||
assert(isJson(local.result.fileContent), "response was not json");
|
||||
local.response = deserializeJSON(local.result.fileContent);
|
||||
assertEquals("12345", local.response.id);
|
||||
|
||||
//full integration test for a@b.c (no .json, but with headers)
|
||||
local.result = apiCall("get", "/echo_regex/12345", "", local.headers);
|
||||
// debug(local.result);
|
||||
assert(isJson(local.result.fileContent), "response was not json");
|
||||
local.response = deserializeJSON(local.result.fileContent);
|
||||
assertEquals("12345", local.response.id);
|
||||
}
|
||||
|
||||
function test_returns_405_for_unimplemented_verbs(){
|
||||
local.result = apiCall("delete", "/echo/2.json", "foo=bar");
|
||||
// debug(local.result);
|
||||
assertEquals(405, local.result.responseHeader.status_code);
|
||||
}
|
||||
|
||||
function test_test_onTaffyRequest_allow(){
|
||||
local.result = apiCall("get","/echo/12.json","refuse=false");
|
||||
// debug(local.result);
|
||||
assertEquals(999,local.result.responseHeader.status_code);
|
||||
}
|
||||
|
||||
function test_onTaffyRequest_deny(){
|
||||
local.result = apiCall("get","/echo/12.json","refuse=true");
|
||||
// debug(local.result);
|
||||
assertEquals(405,local.result.responseHeader.status_code);
|
||||
}
|
||||
|
||||
function test_getCacheKey_customBehavior() {
|
||||
local.result = variables.taffy.getCacheKey(
|
||||
"EchoMember",
|
||||
{ "foo": "bar" },
|
||||
"/echo/12.json"
|
||||
);
|
||||
|
||||
assertEquals("echomember_foo", local.result);
|
||||
}
|
||||
|
||||
function test_getCacheKey_defaultBehavior() {
|
||||
local.args = {
|
||||
cfc: "EchoMember",
|
||||
requestArguments: { "default": true },
|
||||
matchedURI: "/echo/12.json"
|
||||
};
|
||||
|
||||
local.result = variables.taffy.getCacheKey(argumentCollection = local.args);
|
||||
|
||||
// ACF and Lucee generate hash code differently
|
||||
assertEquals("/echo/12.json_#local.args.requestArguments.hashCode()#", local.result);
|
||||
}
|
||||
|
||||
function test_external_file_request_passes_through(){
|
||||
local.result = getUrl('http://#CGI.SERVER_NAME#:#CGI.SERVER_PORT##replace(cgi.script_name, "/tests/tests/run.cfm", "/tests/someFolder/someOtherFile.cfm")#');
|
||||
debug(local.result);
|
||||
assertTrue(findNoCase('woot', local.result.fileContent), "Was not able to get the DMZ file.");
|
||||
}
|
||||
|
||||
function test_tunnel_PUT_through_POST(){
|
||||
var local = {};
|
||||
|
||||
local.headers["X-HTTP-Method-Override"] = "PUT";
|
||||
local.result = apiCall("post","/echo/tunnel/12.json","", local.headers);
|
||||
// debug(local.result);
|
||||
assertEquals(200,local.result.responseHeader.status_code);
|
||||
|
||||
local.deserializedContent = deserializeJSON( local.result.fileContent );
|
||||
// debug( local.deserializedContent );
|
||||
assertEquals("put", local.deserializedContent.actualMethod);
|
||||
}
|
||||
|
||||
function test_tunnel_DELETE_through_POST(){
|
||||
var local = {};
|
||||
|
||||
local.headers["X-HTTP-Method-Override"] = "DELETE";
|
||||
local.result = apiCall("post","/echo/tunnel/12.json","", local.headers);
|
||||
// debug(local.result);
|
||||
assertEquals(200,local.result.responseHeader.status_code);
|
||||
|
||||
local.deserializedContent = deserializeJSON( local.result.fileContent );
|
||||
// debug( local.deserializedContent );
|
||||
assertEquals("delete", local.deserializedContent.actualMethod);
|
||||
}
|
||||
|
||||
function test_put_body_is_mime_content(){
|
||||
var local = {};
|
||||
|
||||
local.result = apiCall(
|
||||
"put",
|
||||
"/echo/12.json",
|
||||
'{"foo":"The quick brown fox jumped over the lazy dog."}'
|
||||
);
|
||||
// debug(local.result);
|
||||
assertEquals(200,local.result.responseHeader.status_code);
|
||||
|
||||
local.deserializedContent = deserializeJSON( local.result.fileContent );
|
||||
// debug( local.deserializedContent );
|
||||
|
||||
// The service response should contain only the ID parameter, and not anything parsed from the body
|
||||
assertEquals("foo,id,password,username", listSort(structKeylist(local.deserializedContent), "textnocase"));
|
||||
assertEquals(12, local.deserializedContent["id"]);
|
||||
assertEquals("The quick brown fox jumped over the lazy dog.", local.deserializedContent["foo"]);
|
||||
}
|
||||
|
||||
function test_put_body_is_url_encoded_params(){
|
||||
var local = {};
|
||||
local.result = apiCall(
|
||||
"put",
|
||||
"/echo/12.json",
|
||||
"foo=yankee&bar=hotel&baz=foxtrot"
|
||||
);
|
||||
// debug(local.result);
|
||||
assertEquals(200,local.result.responseHeader.status_code);
|
||||
|
||||
local.deserializedContent = deserializeJSON( local.result.fileContent );
|
||||
// debug( local.deserializedContent );
|
||||
|
||||
// The service response should contain the ID parameter and all parsed form fields from the body
|
||||
local.sortedKeys = listSort(structKeylist(local.deserializedContent), "textnocase");
|
||||
//because apparently railo includes fieldnames when ACF doesn't...
|
||||
assertTrue("bar,baz,foo,id,password,username" eq local.sortedKeys or "bar,baz,fieldnames,foo,id,password,username" eq local.sortedKeys);
|
||||
assertEquals(12, local.deserializedContent["id"]);
|
||||
assertEquals("yankee", local.deserializedContent["foo"]);
|
||||
assertEquals("hotel", local.deserializedContent["bar"]);
|
||||
assertEquals("foxtrot", local.deserializedContent["baz"]);
|
||||
}
|
||||
|
||||
function test_get_queryString_keys_without_values_returns_empty_string() {
|
||||
makePublic(variables.taffy, "buildRequestArguments");
|
||||
|
||||
var returnedArguments = variables.taffy.buildRequestArguments(
|
||||
regex = "^/testResource/$",
|
||||
tokenNamesArray = [],
|
||||
uri = "/testResource/",
|
||||
queryString = "keyOne=valueOne&keyTwo=&keyThree=valueThree",
|
||||
headers = {}
|
||||
);
|
||||
|
||||
assertEquals("", returnedArguments["keyTwo"]);
|
||||
}
|
||||
|
||||
function test_returns_allow_header_for_405(){
|
||||
local.result = apiCall("delete","/echo/12.json","");
|
||||
// debug(local.result);
|
||||
assertEquals(405,local.result.responseHeader.status_code);
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
|
||||
}
|
||||
|
||||
function test_returns_allow_header_for_get_200(){
|
||||
local.result = apiCall("get","/echo/tunnel/12.json","");
|
||||
// debug(local.result);
|
||||
assertEquals(200,local.result.responseHeader.status_code);
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
|
||||
}
|
||||
|
||||
function test_returns_allow_header_for_post_201(){
|
||||
local.result = apiCall("post","/echo/tunnel/12.json","");
|
||||
// debug(local.result);
|
||||
assertEquals(201,local.result.responseHeader.status_code);
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
|
||||
}
|
||||
|
||||
function test_returns_allow_header_for_put_200(){
|
||||
local.result = apiCall("put","/echo/tunnel/12.json","");
|
||||
// debug(local.result);
|
||||
assertEquals(200,local.result.responseHeader.status_code);
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
|
||||
}
|
||||
|
||||
function test_returns_allow_header_for_delete_200(){
|
||||
local.result = apiCall("delete","/echo/tunnel/12.json","");
|
||||
// debug(local.result);
|
||||
assertEquals(200,local.result.responseHeader.status_code);
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "allow"),"Expected ALLOW header, but couldn't find it");
|
||||
}
|
||||
|
||||
function test_can_pass_data_from_onTaffyRequest_to_resource(){
|
||||
local.result = apiCall("get", "/echo/dude.json", "hulk=smash");
|
||||
// debug(local.result);
|
||||
local.body = deserializeJSON(local.result.fileContent);
|
||||
assertTrue(structKeyExists(local.body, "dataFromOTR"));
|
||||
assertTrue(local.body.dataFromOTR eq "who let the hulk out?!");
|
||||
}
|
||||
|
||||
function test_reload_on_every_request_setting_works(){
|
||||
application._taffy.settings.reloadOnEveryRequest = false;
|
||||
local.result = apiCall("get", "/echo/dude.json", "");
|
||||
// debug(local.result);
|
||||
assertFalse(structKeyExists(local.result.responseheader, "X-TAFFY-RELOADED"), "Expected reload header to be missing, but it was sent.");
|
||||
application._taffy.settings.reloadOnEveryRequest = true;
|
||||
local.result2 = apiCall("get", "/echo/dude.json", "");
|
||||
// debug(local.result2);
|
||||
assertTrue(structKeyExists(local.result2.responseheader, "X-TAFFY-RELOADED"), "Expected reload header to be sent, but it was missing.");
|
||||
}
|
||||
|
||||
function test_returns_error_when_resource_throws_exception(){
|
||||
local.result = apiCall("get", "/throwException.json", "");
|
||||
// debug(local.result);
|
||||
assertEquals(500, local.result.responseHeader.status_code);
|
||||
assertTrue( isJson( local.result.fileContent ), "Response body was not json" );
|
||||
}
|
||||
|
||||
function test_basic_auth_credentials_found(){
|
||||
local.result = apiCall("get", "/basicauth.json", "", {}, "Towel:42");
|
||||
// debug(local.result);
|
||||
assertTrue(isJson(local.result.fileContent));
|
||||
local.data = deserializeJSON(local.result.fileContent);
|
||||
assertTrue(structKeyExists(local.data, "username"));
|
||||
assertEquals("Towel", local.data.username);
|
||||
assertTrue(structKeyExists(local.data, "password"));
|
||||
assertEquals("42", local.data.password);
|
||||
}
|
||||
|
||||
function test_getHostname_returns_not_blank(){
|
||||
local.hostname = variables.taffy.getHostname();
|
||||
// debug(local.hostname);
|
||||
assertNotEquals( "", local.hostname );
|
||||
}
|
||||
|
||||
function test_envConfig_is_applied(){
|
||||
// debug( application._taffy.settings.reloadPassword );
|
||||
assertEquals( "dontpanic", application._taffy.settings.reloadPassword );
|
||||
}
|
||||
|
||||
function test_use_endpointURLParam_in_GET(){
|
||||
local.result = apiCall('get','?#application._taffy.settings.endpointURLParam#=/echo/2606.json','');
|
||||
|
||||
// debug(local.result);
|
||||
assertEquals(999,val(local.result.statusCode));
|
||||
}
|
||||
|
||||
function test_use_endpointURLParam_in_POST(){
|
||||
local.result = apiCall('post','?#application._taffy.settings.endpointURLParam#=/echo/2606.json','bar=foo');
|
||||
|
||||
// debug(local.result);
|
||||
assertEquals(200,val(local.result.statusCode));
|
||||
}
|
||||
|
||||
function test_use_endpointURLParam_in_PUT(){
|
||||
local.result = apiCall('put','?#application._taffy.settings.endpointURLParam#=/echo/2606.json','bar=foo');
|
||||
|
||||
// debug(local.result);
|
||||
assertEquals(200,val(local.result.statusCode));
|
||||
}
|
||||
|
||||
function test_use_endpointURLParam_in_DELETE(){
|
||||
local.result = apiCall('delete','?#application._taffy.settings.endpointURLParam#=/echo/tunnel/2606.json','');
|
||||
|
||||
// debug(local.result);
|
||||
assertEquals(200,val(local.result.statusCode));
|
||||
}
|
||||
|
||||
function test_allows_dashboard_when_enabled(){
|
||||
var restore = application._taffy.settings.disableDashboard;
|
||||
application._taffy.settings.disableDashboard = false;
|
||||
local.result = apiCall("get", "/", "");
|
||||
// debug(local.result);
|
||||
assertEquals(200, val(local.result.statusCode));
|
||||
|
||||
application._taffy.settings.disableDashboard = restore;
|
||||
}
|
||||
|
||||
function test_returns_403_at_root_when_dashboard_disabled_with_no_redirect(){
|
||||
var restore = application._taffy.settings.disableDashboard;
|
||||
application._taffy.settings.disableDashboard = true;
|
||||
local.result = apiCall("get", "/", "");
|
||||
// debug(local.result);
|
||||
assertEquals(403, val(local.result.statusCode));
|
||||
|
||||
application._taffy.settings.disableDashboard = restore;
|
||||
}
|
||||
|
||||
function test_returns_302_at_root_when_dashboard_disabled_with_redirect(){
|
||||
var restore1 = application._taffy.settings.disableDashboard;
|
||||
var restore2 = application._taffy.settings.disabledDashboardRedirect;
|
||||
application._taffy.settings.disableDashboard = true;
|
||||
application._taffy.settings.disabledDashboardRedirect = 'https://google.com';
|
||||
local.result = apiCall("get", "/", "");
|
||||
// debug(local.result);
|
||||
assertEquals(302, val(local.result.statusCode));
|
||||
assertTrue(structKeyExists(local.result.responseHEader, "location"));
|
||||
assertEquals(application._taffy.settings.disabledDashboardRedirect, local.result.responseHeader.location);
|
||||
|
||||
application._taffy.settings.disableDashboard = restore1;
|
||||
application._taffy.settings.disabledDashboardRedirect = restore2;
|
||||
}
|
||||
|
||||
function test_properly_returns_wrapped_jsonp(){
|
||||
application._taffy.settings.jsonp = "callback";
|
||||
local.result = apiCall("get", "/echo/dude.json?callback=zomg", '');
|
||||
// debug(local.result);
|
||||
assertEquals('zomg(', left(local.result.fileContent, 5), "Does not begin with call to jsonp callback");
|
||||
assertEquals(");", right(local.result.fileContent, 2), "Does not end with `);`");
|
||||
}
|
||||
|
||||
function test_properly_handles_arbitrary_cors_headers(){
|
||||
//see: https://github.com/atuttle/Taffy/issues/144
|
||||
application._taffy.settings.allowCrossDomain = true;
|
||||
local.h = { "Access-Control-Request-Headers" = "goat, pigeon, man-bear-pig", "Origin":"http://#cgi.server_name#/"};
|
||||
local.result = apiCall("get", "/echo/dude.json", "", local.h);
|
||||
//debug(local.result);
|
||||
assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "goat");
|
||||
assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "pigeon");
|
||||
assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "man-bear-pig");
|
||||
}
|
||||
|
||||
function test_properly_handles_arbitrary_cors_headers_on_error(){
|
||||
//see: https://github.com/atuttle/Taffy/issues/159
|
||||
application._taffy.settings.allowCrossDomain = true;
|
||||
local.h = { "Access-Control-Request-Headers" = "goat, pigeon, man-bear-pig", "Origin":"http://#cgi.server_name#/"};
|
||||
local.result = apiCall("get", "/throwException.json", "", local.h);
|
||||
// debug(local.result);
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "Access-Control-Allow-Origin"));
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "Access-Control-Allow-Methods"));
|
||||
assertTrue(structKeyExists(local.result.responseHeader, "Access-Control-Allow-Headers"));
|
||||
assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "goat");
|
||||
assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "pigeon");
|
||||
assertTrue(local.result.responseHeader["Access-Control-Allow-Headers"] contains "man-bear-pig");
|
||||
}
|
||||
|
||||
function test_non_struct_json_body_sent_to_resource_as_underscore_body(){
|
||||
//see: https://github.com/atuttle/Taffy/issues/169
|
||||
local.result = apiCall("post", "/echo/5", "[1,2,3]");
|
||||
// debug(local.result);
|
||||
local.response = deserializeJSON(local.result.fileContent);
|
||||
assertTrue(structKeyExists(local.response, "_body"));
|
||||
assertTrue(isArray(local.response._body));
|
||||
assertTrue(arrayLen(local.response._body) == 3);
|
||||
}
|
||||
|
||||
function test_comma_delim_list_of_uris_for_alias(){
|
||||
|
||||
//works with /echo_alias/{ID}
|
||||
local.result = apiCall("get", "/echo_alias/4", "");
|
||||
//debug(local.result);
|
||||
|
||||
assertEquals(200, val(local.result.statusCode));
|
||||
assertEquals(serializeJSON({ID="4"}), local.result.fileContent);
|
||||
|
||||
//works with /echo_alias
|
||||
local.result = apiCall("get", "/echo_alias", "");
|
||||
// debug(local.result);
|
||||
assertEquals(200, val(local.result.statusCode));
|
||||
assertEquals(serializeJSON({ID="0"}), local.result.fileContent);
|
||||
|
||||
//works with /echo_alias/ (trailing slash)
|
||||
local.result = apiCall("get", "/echo_alias/", "");
|
||||
// debug(local.result);
|
||||
assertEquals(200, val(local.result.statusCode));
|
||||
assertEquals(serializeJSON({ID="0"}), local.result.fileContent);
|
||||
|
||||
//works with /echo_alias?ID=x
|
||||
local.result = apiCall("get", "/echo_alias", "ID=2");
|
||||
// debug(local.result);
|
||||
assertEquals(200, val(local.result.statusCode));
|
||||
assertEquals(serializeJSON({ID="2"}), local.result.fileContent);
|
||||
}
|
||||
</cfscript>
|
||||
|
||||
|
||||
<cffunction name="test_can_upload_a_file">
|
||||
<cfset var local = structNew() />
|
||||
<cfset local.apiRootURL = getDirectoryFromPath(cgi.script_name) />
|
||||
<cfset local.apiRootURL = listDeleteAt(local.apiRootURL,listLen(local.apiRootURL,'/'),'/') />
|
||||
<cfhttp
|
||||
url="http://#cgi.server_name#:#cgi.server_port##local.apiRootURL#/index.cfm/upload"
|
||||
method="post"
|
||||
result="local.uploadResult">
|
||||
<cfhttpparam type="file" name="img" file="#expandPath('/taffy/tests/tests/upload.png')#" />
|
||||
</cfhttp>
|
||||
<!--- <cfset debug(local.uploadResult) /> --->
|
||||
<cfset assertTrue(local.uploadResult.statusCode eq "200 OK", "Did not return status 200") />
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="test_throws_exception_when_ressource_uri_doesnt_begin_with_forward_slash">
|
||||
<cfset assertTrue(checkIfOneSkippedRessourceContainsExpectedException("detail", "The URI (uriWithoutForwardSlash) for `uriDoesntBeginWithForwardSlash` should begin with a forward slash."), "Uri without forward slash not showing in errors")>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="test_throws_exception_when_alias_ressource_uri_doesnt_begin_with_forward_slash">
|
||||
<cfset assertTrue(checkIfOneSkippedRessourceContainsExpectedException("detail", "The URI (uriAliasWithoutFowardSlash) for `uriAliasDoesntBeginWithForwardSlash` should begin with a forward slash."), "Uri alias without forward slash not showing in errors")>
|
||||
</cffunction>
|
||||
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,94 @@
|
||||
component extends="base" {
|
||||
|
||||
|
||||
function setup(){
|
||||
reloadFramework();
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
reloadFramework();
|
||||
}
|
||||
|
||||
function beforeTests(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
function test_loads_directory_named_resources() {
|
||||
// Setup external factory to read resource directory. Ignore resources that were designed to cause errors.
|
||||
local.config = {
|
||||
exclude = ["uriDoesnt","uriAliasDoesnt","conflict"]
|
||||
};
|
||||
|
||||
local.beanFactory = createObject("component", "di1.ioc").init(["/taffy/tests/resources"], local.config);
|
||||
|
||||
|
||||
// Setup Taffy with new bean factory to use and call 'onApplicationStart' to properly initialize.
|
||||
local.taffy = createObject("component","taffy.tests.Application");
|
||||
|
||||
makePublic(local.taffy, "getExternalBeanFactory");
|
||||
makePublic(local.taffy, "getBeanListFromExternalFactory");
|
||||
|
||||
injectMethod(local.taffy, this, "_getVariables", "getVariables");
|
||||
|
||||
local.vars = local.taffy.getVariables();
|
||||
local.vars.framework.beanFactory = local.beanFactory;
|
||||
|
||||
local.taffy.onApplicationStart();
|
||||
|
||||
|
||||
// Grab the resource list and compare.
|
||||
local.resourceList = local.taffy.getBeanListFromExternalFactory(local.taffy.getExternalBeanFactory());
|
||||
|
||||
structDelete(local.vars.framework, "beanFactory");
|
||||
|
||||
local.taffy.onApplicationStart();
|
||||
|
||||
debug("Available resources from external factory: '" & replace(local.resourceList, ",", ", ", "all") & "'");
|
||||
assert(listLen(local.resourceList) gt 0, "No resources were loaded from the external factory.");
|
||||
}
|
||||
|
||||
|
||||
function test_loads_explicit_named_resources() {
|
||||
// Setup external factory to read resource directory. Ignore resources that were designed to cause errors.
|
||||
local.config = {
|
||||
exclude = ["uriDoesnt","uriAliasDoesnt","conflict"],
|
||||
omitDirectoryAliases = true
|
||||
};
|
||||
|
||||
local.beanFactory = createObject("component", "di1.ioc").init(["/taffy/tests/resources"], local.config);
|
||||
|
||||
|
||||
// Setup Taffy with new bean factory to use and call 'onApplicationStart' to properly initialize.
|
||||
local.taffy = createObject("component","taffy.tests.Application");
|
||||
|
||||
makePublic(local.taffy, "getExternalBeanFactory");
|
||||
makePublic(local.taffy, "getBeanListFromExternalFactory");
|
||||
|
||||
injectMethod(local.taffy, this, "_getVariables", "getVariables");
|
||||
|
||||
local.vars = local.taffy.getVariables();
|
||||
|
||||
local.vars.framework.beanFactory = local.beanFactory;
|
||||
|
||||
local.taffy.onApplicationStart();
|
||||
|
||||
|
||||
// Grab the resource list and compare.
|
||||
debug(local.beanFactory.getBeanInfo());
|
||||
local.resourceList = local.taffy.getBeanListFromExternalFactory(local.taffy.getExternalBeanFactory());
|
||||
|
||||
structDelete(local.vars.framework, "beanFactory");
|
||||
local.taffy.onApplicationStart();
|
||||
|
||||
debug("Available resources from external factory: '" & replace(local.resourceList, ",", ", ", "all") & "'");
|
||||
|
||||
//THIS TEST CURRENTLY FAILING DUE TO https://github.com/atuttle/Taffy/issues/276
|
||||
//assert(listLen(local.resourceList) gt 0, "No resources were loaded from the external factory.");
|
||||
}
|
||||
|
||||
|
||||
private function _getVariables(){
|
||||
return variables;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<cfcomponent extends="base">
|
||||
<cfscript>
|
||||
|
||||
function setup() {
|
||||
reloadFramework();
|
||||
}
|
||||
|
||||
|
||||
function beforeTests(){
|
||||
request["_testsRunning"] = true;
|
||||
variables.taffy = createObject("component","taffy.tests.Application");
|
||||
makePublic(variables.taffy, "getBeanFactory");
|
||||
variables.factory = variables.taffy.getBeanFactory();
|
||||
//debug(variables.factory);
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resources'), 'taffy.tests.resources', expandPath('/taffy/tests/resources'), true, variables.taffy);
|
||||
}
|
||||
|
||||
function test_throws_on_getBean_not_exists(){
|
||||
var local = {};
|
||||
local.nonExistentBean = "does_not_exist";
|
||||
|
||||
try{
|
||||
local.result = variables.factory.getBean(local.nonExistentBean);
|
||||
fail("Expected 'Bean Not Found' exception to be thrown, but none was.");
|
||||
} catch (Taffy.Factory.BeanNotFound e) {
|
||||
//debug(e);
|
||||
assertTrue(findNoCase('not found', e.message) gt 0, "TaffyFactory exception message did not contain the words 'not found'.");
|
||||
}
|
||||
}
|
||||
|
||||
function test_autowires_properties_in_beans(){
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resources'), 'taffy.tests.resources', expandPath('/taffy/tests/resources'), true );
|
||||
local.bean = variables.factory.getBean( 'EchoMember' );
|
||||
// debug(local.bean);
|
||||
assertTrue( structKeyExists(local.bean, "dependency1") );
|
||||
assertFalse( isSimpleValue(local.bean.dependency1) );
|
||||
}
|
||||
|
||||
function test_autowires_setters_in_beans(){
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resources'), 'taffy.tests.resources', expandPath('/taffy/tests/resources'), true );
|
||||
local.bean = variables.factory.getBean( 'EchoRegexMember' );
|
||||
// debug(local.bean);
|
||||
assertTrue( structKeyExists(local.bean, "dependency2") );
|
||||
assertFalse( isSimpleValue(local.bean.dependency2) );
|
||||
}
|
||||
|
||||
function test_autowires_properties_in_transients(){
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resources'), 'taffy.tests.resources', expandPath('/taffy/tests/resources'), true );
|
||||
local.bean = variables.factory.getBean( 'CustomJsonSerializer' );
|
||||
// debug(local.bean);
|
||||
assertTrue( structKeyExists(local.bean, "dependency1") );
|
||||
assertFalse( isSimpleValue(local.bean.dependency1) );
|
||||
}
|
||||
|
||||
function test_autowires_setters_in_transients(){
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resources'), 'taffy.tests.resources', expandPath('/taffy/tests/resources'), true );
|
||||
local.bean = variables.factory.getBean( 'CustomJsonSerializer' );
|
||||
// debug(local.bean);
|
||||
assertTrue( structKeyExists(local.bean, "dependency2") );
|
||||
assertFalse( isSimpleValue(local.bean.dependency2) );
|
||||
}
|
||||
|
||||
function test_skips_resources_with_errors(){
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resourcesError'), 'taffy.tests.resourcesError', expandPath('/taffy/tests/resourcesError'), true );
|
||||
// debug(variables.taffy.status);
|
||||
assertTrue(structKeyExists(variables.taffy.status, "skippedResources"));
|
||||
}
|
||||
|
||||
function test_lists_skipped_resources(){
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resourcesError'), 'taffy.tests.resourcesError', expandPath('/taffy/tests/resourcesError'), true, variables.taffy);
|
||||
debug(variables.taffy.status);
|
||||
assertTrue(structKeyExists(variables.taffy.status, "skippedResources"));
|
||||
assertTrue( arrayLen(variables.taffy.status.skippedResources) gt 0 );
|
||||
}
|
||||
|
||||
function test_clears_skipped_resources_on_reload(){
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resourcesError'), 'taffy.tests.resourcesError', expandPath('/taffy/tests/resourcesError'), true, variables.taffy );
|
||||
// debug(variables.taffy.status);
|
||||
assertTrue(structKeyExists(variables.taffy.status, "skippedResources"));
|
||||
assertTrue( arrayLen(variables.taffy.status.skippedResources) gt 0 );
|
||||
|
||||
variables.factory.loadBeansFromPath( expandPath('/taffy/tests/resources'), 'taffy.tests.resources', expandPath('/taffy/tests/resources'), true, variables.taffy );
|
||||
// debug(variables.taffy.status);
|
||||
assertTrue(structKeyExists(variables.taffy.status, "skippedResources"));
|
||||
assertTrue( ArrayLen(variables.taffy.status.skippedResources) eq 0, "Expected skipped resources array to be empty but it wasn't" );
|
||||
}
|
||||
|
||||
function test_treats_CRCs_as_transients(){
|
||||
var local = {};
|
||||
//this resource+method explicitly sets response status of 999
|
||||
local.result = apiCall("get", "/echo/2.json", "foo=bar");
|
||||
// debug(local.result);
|
||||
assertEquals(999, local.result.responseHeader.status_code);
|
||||
//this resource+method usees the default response status => 200=passing test, 999=failing test
|
||||
local.result = apiCall("get", "/echo/tunnel/2.json", "foo=bar");
|
||||
// debug(local.result);
|
||||
assertEquals(200, local.result.responseHeader.status_code);
|
||||
}
|
||||
|
||||
</cfscript>
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,63 @@
|
||||
<cfcomponent extends="base">
|
||||
<cfscript>
|
||||
|
||||
function test_hoth(){
|
||||
var mockHoth = getMockBox().createMock(className="Hoth.HothTracker", callLogging=true);
|
||||
var hothAdapter = '';
|
||||
var fakeError = {};
|
||||
var callLog = {};
|
||||
//setup the behaviors we're expecting the adapter to run
|
||||
//mockHoth.track('{struct}');
|
||||
mockHoth.$('track', true);
|
||||
//create hoth adapter to test
|
||||
hothAdapter = createObject("component", "taffy.bonus.LogToHoth").init(
|
||||
"Taffy.examples.api_Hoth.resources.HothConfig",
|
||||
mockHoth
|
||||
);
|
||||
|
||||
//fake error
|
||||
fakeError.message = "This is a test error";
|
||||
fakeError.detail = "Rubber Baby Buggy Bumper";
|
||||
hothAdapter.saveLog(fakeError);
|
||||
|
||||
callLog = mockHoth.$callLog();
|
||||
debug(callLog);
|
||||
assertTrue(structKeyExists(callLog, "track"), "should call track method");
|
||||
assertTrue(isStruct(callLog.track[1][1]), "args should be a struct");
|
||||
assertEquals(callLog.track[1][1].message, fakeError.message);
|
||||
|
||||
}
|
||||
|
||||
function test_BugLogHQ(){
|
||||
var blhqSettings = { bugLogListener = "http://#cgi.server_name#:#cgi.server_port#/tests/BugLogHQ/listeners/bugLogListenerREST.cfm" };
|
||||
var mockBLHQ = new bugLog.client.bugLogService(argumentCollection=blhqSettings);
|
||||
var blhqAdapter = '';
|
||||
var fakeError = {};
|
||||
fakeError.message = "This is a test error";
|
||||
fakeError.detail = "Rubber Baby Buggy Bumper";
|
||||
|
||||
if (structKeyExists(server, "coldfusion") && structKeyExists(server.coldfusion, "productversion")) {
|
||||
if (val(listFirst(server.coldfusion.productversion)) < 11) {
|
||||
//datasource definition will only work on CF11+
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mockBLHQ.init(argumentCollection=blhqSettings);
|
||||
|
||||
blhqAdapter = createObject("component", "taffy.bonus.LogToBugLogHQ").init(
|
||||
config=blhqSettings,
|
||||
tracker=mockBLHQ
|
||||
);
|
||||
|
||||
//fake error
|
||||
fakeError.message = "This is a test error";
|
||||
fakeError.detail = "Rubber Baby Buggy Bumper";
|
||||
blhqAdapter.saveLog(fakeError);
|
||||
|
||||
|
||||
}
|
||||
|
||||
</cfscript>
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,40 @@
|
||||
<cfcomponent extends="base">
|
||||
<cfscript>
|
||||
function setup(){
|
||||
variables.serializer = createObject("component", "taffy.core.baseSerializer");
|
||||
}
|
||||
|
||||
function test_setData_getData(){
|
||||
variables.serializer.setData(10);
|
||||
assertEquals(10, variables.serializer.getData());
|
||||
}
|
||||
|
||||
function test_noData_returns_empty_rep_obj(){
|
||||
local.result = variables.serializer.noData();
|
||||
local.meta = getMetaData(local.result);
|
||||
// debug(local.meta);
|
||||
// debug(local.result.getData());
|
||||
assertEquals('taffy.core.baseSerializer', local.meta.fullname);
|
||||
assertEquals("", local.result.getData());
|
||||
}
|
||||
|
||||
function test_withStatus_getStatus(){
|
||||
variables.serializer.withStatus(42);
|
||||
assertEquals(42, variables.serializer.getStatus());
|
||||
}
|
||||
|
||||
function test_withStatus_getStatusText(){
|
||||
variables.serializer.withStatus(404, "Not Found");
|
||||
assertEquals("Not Found", variables.serializer.getStatusText());
|
||||
variables.serializer.withStatus(418);
|
||||
assertEquals("I'm a teapot", variables.serializer.getStatusText());
|
||||
}
|
||||
|
||||
function test_withHeaders_getHeaders(){
|
||||
local.h = {};
|
||||
local.h['x-dude'] = 'dude!';
|
||||
variables.serializer.withHeaders(local.h);
|
||||
assertEquals(true, structKeyExists(variables.serializer.getHeaders(), "x-dude"));
|
||||
}
|
||||
</cfscript>
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,50 @@
|
||||
component extends="base" {
|
||||
|
||||
|
||||
|
||||
function beforeTests(){
|
||||
variables.taffy = createObject("component","taffy.tests.Application");
|
||||
variables.resource = createObject("component", "taffy.core.resource");
|
||||
}
|
||||
|
||||
function test_representationOf_returns_repClass(){
|
||||
application._taffy.settings.serializer = "taffy.core.nativeJsonSerializer";
|
||||
makePublic(variables.resource, "representationOf");
|
||||
local.result = variables.resource.representationOf(10);
|
||||
local.meta = getMetadata(local.result);
|
||||
// debug(local.meta);
|
||||
assertEquals(true, eventuallyInherits(local.meta, 'taffy.core.baseSerializer'));
|
||||
}
|
||||
|
||||
function test_queryToArray_respects_column_case(){
|
||||
makePublic(variables.resource, "queryToArray");
|
||||
local.before = QueryNew("Foo,Bar");
|
||||
queryAddRow(local.before);
|
||||
querySetCell(local.before, "Foo", 42, 1);
|
||||
querySetCell(local.before, "Bar", "fubar", 1);
|
||||
// debug(local.before);
|
||||
local.after = variables.resource.queryToArray(local.before);
|
||||
// debug(local.after);
|
||||
local.keyList = structKeyList(local.after[1]);
|
||||
local.serialized = serializeJSON(local.after);
|
||||
// debug(local.serialized);
|
||||
|
||||
assertTrue( (local.keyList eq "Foo,Bar" or local.keyList eq "Bar,Foo"), 'column name case is not as expected');
|
||||
assertTrue( (local.serialized eq '[{"Foo":42,"Bar":"fubar"}]') or (local.serialized eq '[{"Bar":"fubar","Foo":42}]') );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* recursive method used to check entire inheritance tree to find that a certain parent class exists somewhere within it */
|
||||
private boolean function eventuallyInherits(required struct md, required string class) {
|
||||
if (structKeyExists(md, "fullname") && md.fullname eq class) {
|
||||
return true;
|
||||
} else {
|
||||
if (structKeyExists(md, "extends")) {
|
||||
return eventuallyInherits(md.extends, class);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<cfcomponent extends="mxunit.framework.TestCase">
|
||||
|
||||
<cffunction name="apiCall" access="private" output="false">
|
||||
<cfargument name="method" type="string"/>
|
||||
<cfargument name="uri" type="string"/>
|
||||
<cfargument name="query" type="string"/>
|
||||
<cfargument name="headers" type="struct" default="#structNew()#" />
|
||||
<cfargument name="basicauth" type="string" default="" />
|
||||
|
||||
<cfset var local = structNew() />
|
||||
<cfset local.apiRootURL = getDirectoryFromPath(cgi.script_name) />
|
||||
<cfset local.apiRootURL = listDeleteAt(local.apiRootURL,listLen(local.apiRootURL,'/'),'/') />
|
||||
|
||||
<cfset local.args = {} />
|
||||
<cfset local.args.method = arguments.method />
|
||||
<cfset local.args.redirect = false />
|
||||
<cfset local.args.result = "local.result" />
|
||||
<cfset local.args.charset = "utf-8" />
|
||||
<cfif len(arguments.basicauth)>
|
||||
<cfset local.args.username = listFirst(arguments.basicauth, ":") />
|
||||
<cfset local.args.password = listRest(arguments.basicAuth, ":") />
|
||||
</cfif>
|
||||
<cfset local.args.url = "http://#CGI.SERVER_NAME#:#CGI.SERVER_PORT##local.apiRootURL#/index.cfm#arguments.uri#" />
|
||||
|
||||
<cfif lcase(arguments.method) eq "put" or lcase(arguments.method) eq "post">
|
||||
<cfhttp attributeCollection="#local.args#">
|
||||
<cfif isJson(query)>
|
||||
<cfhttpparam type="header" name="Content-Type" value="text/json" />
|
||||
<cfelse>
|
||||
<cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded" />
|
||||
</cfif>
|
||||
<cfhttpparam type="body" value="#arguments.query#" />
|
||||
|
||||
<!--- Add arbitrary headers to request --->
|
||||
<cfloop item="local.header" collection="#arguments.headers#">
|
||||
<cfhttpparam type="header" name="#local.header#" value="#arguments.headers[local.header]#" />
|
||||
</cfloop>
|
||||
</cfhttp>
|
||||
<cfelse>
|
||||
<cfif find('?',local.args.url)>
|
||||
<cfset local.args.url = '#local.args.url##arguments.query#' />
|
||||
<cfelse>
|
||||
<cfset local.args.url = '#local.args.url#?#arguments.query#' />
|
||||
</cfif>
|
||||
<cfhttp attributeCollection="#local.args#">
|
||||
<!--- Add arbitrary headers to request --->
|
||||
<cfloop item="local.header" collection="#arguments.headers#">
|
||||
<cfhttpparam type="header" name="#local.header#" value="#arguments.headers[local.header]#" />
|
||||
</cfloop>
|
||||
</cfhttp>
|
||||
</cfif>
|
||||
<cfreturn local.result />
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="getUrl" access="private" output="false">
|
||||
<cfargument name="url" type="string" required="true" />
|
||||
<cfhttp method="get" url="#arguments.url#" result="local.result" />
|
||||
<cfreturn local.result />
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="checkIfOneSkippedRessourceContainsExpectedException" access="private" output="false" returntype="boolean">
|
||||
<cfargument name="exceptionAttributeName" type="string" required="true" />
|
||||
<cfargument name="expectedValue" type="string" required="true" />
|
||||
<cfset var skippedRessource = "">
|
||||
<cfset var expectedExceptionAttributeValueFound = 0>
|
||||
|
||||
<cfloop array="#application._taffy.status.skippedResources#" index="skippedRessource">
|
||||
<cfset expectedExceptionAttributeValueFound = structKeyExists(skippedRessource.exception, arguments.exceptionAttributeName) and skippedRessource.exception[arguments.exceptionAttributeName] is arguments.expectedValue>
|
||||
<cfif expectedExceptionAttributeValueFound>
|
||||
<cfbreak>
|
||||
</cfif>
|
||||
</cfloop>
|
||||
|
||||
<cfreturn expectedExceptionAttributeValueFound>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="reloadFramework" access="private">
|
||||
<cfset local.apiRootURL = getDirectoryFromPath(cgi.script_name) />
|
||||
<cfset local.apiRootURL = listDeleteAt(local.apiRootURL,listLen(local.apiRootURL,'/'),'/') />
|
||||
<cfhttp method="GET" url="http://#CGI.SERVER_NAME#:#CGI.SERVER_PORT##local.apiRootURL#/index.cfm?#application._taffy.settings.reloadkey#=#application._taffy.settings.reloadPassword#" />
|
||||
</cffunction>
|
||||
|
||||
</cfcomponent>
|
||||
@@ -0,0 +1,10 @@
|
||||
<cfsetting requesttimeout="600" />
|
||||
|
||||
<cfinvoke component="mxunit.runner.DirectoryTestSuite"
|
||||
method="run"
|
||||
directory="#expandPath('/Taffy/tests/tests')#"
|
||||
componentPath="Taffy.tests.tests"
|
||||
recurse="true"
|
||||
returnvariable="results" />
|
||||
|
||||
<cfoutput> #results.getResultsOutput('extjs')# </cfoutput>
|
||||
@@ -0,0 +1,19 @@
|
||||
<cfsetting showdebugoutput="false" />
|
||||
<cfscript>
|
||||
testsDir = expandPath('/Taffy/tests/tests');
|
||||
componentPath = 'Taffy.tests.tests';
|
||||
|
||||
suite = createObject('mxunit.framework.TestSuite');
|
||||
files = createObject('mxunit.runner.DirectoryTestSuite').getTests(directory=testsDir, componentPath=componentPath);
|
||||
|
||||
for (i = 1; i <= arrayLen(files); i++){
|
||||
suite.addAll(files[i]);
|
||||
}
|
||||
|
||||
tests = suite.suites();
|
||||
|
||||
for (t in tests){
|
||||
tests[t] = tests[t].methods;
|
||||
}
|
||||
</cfscript>
|
||||
<cfcontent reset="true" type="application/json; charset=UTF-8" /><cfoutput>#serializeJson(tests)#</cfoutput><cfabort/>
|
||||
@@ -0,0 +1,46 @@
|
||||
<cfparam name="url.reporter" default="simple" type="variablename">
|
||||
<cfset plainText = url.reporter IS "text" OR url.reporter IS "mintext">
|
||||
<cfsetting requesttimeout="150" enablecfoutputonly="#plainText#">
|
||||
<cfif plainText>
|
||||
<cfcontent type="text/plain">
|
||||
</cfif>
|
||||
|
||||
<strong>Test Environment</strong>:
|
||||
<cfif server.coldfusion.productname contains "ColdFusion">
|
||||
<cfoutput>Adobe ColdFusion #server.coldfusion.productversion#</cfoutput>
|
||||
<cfelseif structKeyExists(server, "lucee")>
|
||||
<cfoutput>Lucee #server.lucee.version#</cfoutput>
|
||||
<cfelseif structKeyExists(server, "railo")>
|
||||
<cfoutput>Railo #server.railo.version#</cfoutput>
|
||||
<cfelse>
|
||||
<cfoutput>#server.coldfusion.productname#</cfoutput>
|
||||
</cfif>
|
||||
<cfoutput> on #server.os.name# #server.os.version#</cfoutput>
|
||||
<cfset system = createObject("java", "java.lang.System")>
|
||||
<cfoutput> running Java #system.getProperty("java.version")#
|
||||
|
||||
</cfoutput>
|
||||
|
||||
|
||||
<cfset bundles=[]>
|
||||
<cfdirectory action="list" directory="#getDirectoryFromPath(getCurrentTemplatePath())#" name="files">
|
||||
<cfloop query="files">
|
||||
<cfif left(getFileFromPath(files.name), 4) IS "Test">
|
||||
<cfset arrayAppend(bundles, "Taffy.tests.tests." & replace(getFileFromPath(files.name), ".cfc", ""))>
|
||||
|
||||
</cfif>
|
||||
</cfloop>
|
||||
<cfset r = new testbox.system.TestBox(reporter=url.reporter, bundles=bundles)>
|
||||
<cfsavecontent variable="resultOutput"><cfoutput>#r.run()#</cfoutput></cfsavecontent>
|
||||
<cfoutput>#trim(resultOutput)#</cfoutput>
|
||||
<cfset resultObject = r.getResult()>
|
||||
<cfset errors = resultObject.getTotalFail() + resultObject.getTotalError()>
|
||||
<cfif errors GT 0>
|
||||
<cfheader statuscode="500" statustext="Tests Failed">
|
||||
</cfif>
|
||||
|
||||
<cfif NOT plainText>
|
||||
<cfoutput>
|
||||
<a href="run.cfm?ts=#GetTickCount()#">ReRun</a>
|
||||
</cfoutput>
|
||||
</cfif>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
Reference in New Issue
Block a user