forked from jazkarta/obsolete-edx-sga
-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added test framework and test for studio.js
- Loading branch information
George Schneeloch
committed
Aug 28, 2015
1 parent
9894c1a
commit f73d503
Showing
4 changed files
with
349 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
(function(requirejs, define) { | ||
requirejs.config({ | ||
paths: { | ||
'jquery': 'js/bower/jquery/dist/jquery', | ||
'sinon': 'js/bower/sinon/lib/sinon', | ||
'URI': 'js/bower/URIjs/src/URI', | ||
'underscore': 'js/bower/underscore/underscore', | ||
'IPv6': 'js/bower/URIjs/src/IPv6', | ||
'punycode': 'js/bower/URIjs/src/punycode', | ||
'SecondLevelDomains': 'js/bower/URIjs/src/SecondLevelDomains' | ||
}, | ||
shim: { | ||
'underscore': { | ||
exports: "_" | ||
}, | ||
'sinon': { | ||
exports: "sinon" | ||
}, | ||
'URI': { | ||
exports: 'URI', | ||
deps: ['sinon'] | ||
} | ||
} | ||
}); | ||
|
||
define("main", [ | ||
'js/spec/test_studio' | ||
]); | ||
|
||
})(requirejs, define); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
define(["js/spec_helpers/ajax_helpers", "js/src/studio"], function(AjaxHelpers) { | ||
'use strict'; | ||
describe("studio.js", function() { | ||
describe("StaffGradedAssignmentXBlock", function() { | ||
it("saves the view", function() { | ||
// Spy on Ajax requests | ||
var requests = AjaxHelpers.requests(this); | ||
|
||
// Mock some arguments | ||
var fakeUrl = "/test_url/"; | ||
var element = $("<div>" + | ||
"<input type='hidden' name='one' value='1' />" + | ||
"<input type='hidden' name='two' value='2' />" + | ||
"<input type='hidden' name='three' value='3' /></div>"); | ||
var server = null; | ||
|
||
var runtime = { | ||
handlerUrl: function() { | ||
return fakeUrl; | ||
}, | ||
notify: function(type, state) { | ||
notifyStates[type] = state; | ||
} | ||
}; | ||
|
||
var XBlock = StaffGradedAssignmentXBlock(runtime, element, server); | ||
// Function expects this.runtime to exist | ||
XBlock.save = XBlock.save.bind({runtime: runtime}); | ||
|
||
var notifyStates = {}; | ||
|
||
// Execute the save | ||
XBlock.save(); | ||
|
||
// Verify the request was made | ||
AjaxHelpers.expectRequest( | ||
requests, 'POST', fakeUrl, JSON.stringify({ | ||
one: "1", | ||
two: "2", | ||
three: "3" | ||
}) | ||
); | ||
|
||
// Complete ajax request | ||
AjaxHelpers.respondWithJson(requests, {}); | ||
|
||
expect(notifyStates.save.state).toBe('end'); | ||
}); | ||
|
||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
// NOTE: copied from https://github.com/edx/edx-platform/blob/master/common/static/common/js/spec_helpers/ajax_helpers.js | ||
define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) { | ||
'use strict'; | ||
|
||
var fakeServer, fakeRequests, expectRequest, expectJsonRequest, expectPostRequest, expectJsonRequestURL, | ||
respondWithJson, respondWithError, respondWithTextError, respondWithNoContent; | ||
|
||
/* These utility methods are used by Jasmine tests to create a mock server or | ||
* get reference to mock requests. In either case, the cleanup (restore) is done with | ||
* an after function. | ||
* | ||
* This pattern is being used instead of the more common beforeEach/afterEach pattern | ||
* because we were seeing sporadic failures in the afterEach restore call. The cause of the | ||
* errors were that one test suite was incorrectly being linked as the parent of an unrelated | ||
* test suite (causing both suites' afterEach methods to be called). No solution for the root | ||
* cause has been found, but initializing sinon and cleaning it up on a method-by-method | ||
* basis seems to work. For more details, see STUD-1264. | ||
*/ | ||
|
||
/** | ||
* Get a reference to the mocked server, and respond | ||
* to all requests with the specified statusCode. | ||
*/ | ||
fakeServer = function (that, response) { | ||
var server = sinon.fakeServer.create(); | ||
that.after(function() { | ||
server.restore(); | ||
}); | ||
server.respondWith(response); | ||
return server; | ||
}; | ||
|
||
/** | ||
* Keep track of all requests to a fake server, and | ||
* return a reference to the Array. This allows tests | ||
* to respond for individual requests. | ||
*/ | ||
fakeRequests = function (that) { | ||
console.log(sinon); | ||
var requests = [], | ||
xhr = sinon.useFakeXMLHttpRequest(); | ||
xhr.onCreate = function(request) { | ||
requests.push(request); | ||
}; | ||
|
||
that.after(function() { | ||
xhr.restore(); | ||
}); | ||
|
||
return requests; | ||
}; | ||
|
||
expectRequest = function(requests, method, url, body, requestIndex) { | ||
var request; | ||
if (_.isUndefined(requestIndex)) { | ||
requestIndex = requests.length - 1; | ||
} | ||
request = requests[requestIndex]; | ||
expect(request.url).toEqual(url); | ||
expect(request.method).toEqual(method); | ||
expect(request.requestBody).toEqual(body); | ||
}; | ||
|
||
expectJsonRequest = function(requests, method, url, jsonRequest, requestIndex) { | ||
var request; | ||
if (_.isUndefined(requestIndex)) { | ||
requestIndex = requests.length - 1; | ||
} | ||
request = requests[requestIndex]; | ||
expect(request.url).toEqual(url); | ||
expect(request.method).toEqual(method); | ||
expect(JSON.parse(request.requestBody)).toEqual(jsonRequest); | ||
}; | ||
|
||
/** | ||
* Expect that a JSON request be made with the given URL and parameters. | ||
* @param requests The collected requests | ||
* @param expectedUrl The expected URL excluding the parameters | ||
* @param expectedParameters An object representing the URL parameters | ||
* @param requestIndex An optional index for the request (by default, the last request is used) | ||
*/ | ||
expectJsonRequestURL = function(requests, expectedUrl, expectedParameters, requestIndex) { | ||
var request, parameters; | ||
if (_.isUndefined(requestIndex)) { | ||
requestIndex = requests.length - 1; | ||
} | ||
request = requests[requestIndex]; | ||
expect(new URI(request.url).path()).toEqual(expectedUrl); | ||
parameters = new URI(request.url).query(true); | ||
delete parameters._; // Ignore the cache-busting argument | ||
expect(parameters).toEqual(expectedParameters); | ||
}; | ||
|
||
/** | ||
* Intended for use with POST requests using application/x-www-form-urlencoded. | ||
*/ | ||
expectPostRequest = function(requests, url, body, requestIndex) { | ||
var request; | ||
if (_.isUndefined(requestIndex)) { | ||
requestIndex = requests.length - 1; | ||
} | ||
request = requests[requestIndex]; | ||
expect(request.url).toEqual(url); | ||
expect(request.method).toEqual("POST"); | ||
expect(_.difference(request.requestBody.split('&'), body.split('&'))).toEqual([]); | ||
}; | ||
|
||
respondWithJson = function(requests, jsonResponse, requestIndex) { | ||
if (_.isUndefined(requestIndex)) { | ||
requestIndex = requests.length - 1; | ||
} | ||
requests[requestIndex].respond(200, | ||
{ 'Content-Type': 'application/json' }, | ||
JSON.stringify(jsonResponse)); | ||
}; | ||
|
||
respondWithError = function(requests, statusCode, jsonResponse, requestIndex) { | ||
if (_.isUndefined(requestIndex)) { | ||
requestIndex = requests.length - 1; | ||
} | ||
if (_.isUndefined(statusCode)) { | ||
statusCode = 500; | ||
} | ||
if (_.isUndefined(jsonResponse)) { | ||
jsonResponse = {}; | ||
} | ||
requests[requestIndex].respond(statusCode, | ||
{ 'Content-Type': 'application/json' }, | ||
JSON.stringify(jsonResponse) | ||
); | ||
}; | ||
|
||
respondWithTextError = function(requests, statusCode, textResponse, requestIndex) { | ||
if (_.isUndefined(requestIndex)) { | ||
requestIndex = requests.length - 1; | ||
} | ||
if (_.isUndefined(statusCode)) { | ||
statusCode = 500; | ||
} | ||
if (_.isUndefined(textResponse)) { | ||
textResponse = ""; | ||
} | ||
requests[requestIndex].respond(statusCode, | ||
{ 'Content-Type': 'text/plain' }, | ||
textResponse | ||
); | ||
}; | ||
|
||
respondWithNoContent = function(requests, requestIndex) { | ||
if (_.isUndefined(requestIndex)) { | ||
requestIndex = requests.length - 1; | ||
} | ||
requests[requestIndex].respond(204, | ||
{ 'Content-Type': 'application/json' }); | ||
}; | ||
|
||
return { | ||
'server': fakeServer, | ||
'requests': fakeRequests, | ||
'expectRequest': expectRequest, | ||
'expectJsonRequest': expectJsonRequest, | ||
'expectJsonRequestURL': expectJsonRequestURL, | ||
'expectPostRequest': expectPostRequest, | ||
'respondWithJson': respondWithJson, | ||
'respondWithError': respondWithError, | ||
'respondWithTextError': respondWithTextError, | ||
'respondWithNoContent': respondWithNoContent, | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
--- | ||
# JavaScript test suite description | ||
# | ||
# | ||
# To run all the tests and print results to the console: | ||
# | ||
# js-test-tool run TEST_SUITE --use-firefox | ||
# | ||
# where `TEST_SUITE` is this file. | ||
# | ||
# | ||
# To run the tests in your default browser ("dev mode"): | ||
# | ||
# js-test-tool dev TEST_SUITE | ||
# | ||
|
||
# Name of the test suite, used to construct | ||
# the URL from which pages are served. | ||
# | ||
# For example, if the suite name is "test_suite", | ||
# then: | ||
# | ||
# * /suite/test_suite | ||
# serves the test suite runner page | ||
# * /suite/test_suite/include/* | ||
# serves dependencies (src, spec, lib, and fixtures) | ||
# | ||
# Test suite names must be URL-encodable and unique | ||
# among suite descriptions passed to js-test-tool | ||
test_suite_name: edx_sga | ||
|
||
# Currently, the only supported test runner is Jasmine | ||
# See http://pivotal.github.io/jasmine/ | ||
# for the Jasmine documentation. | ||
test_runner: jasmine_requirejs | ||
|
||
# Path prepended to source files in the coverage report (optional) | ||
# For example, if the source path | ||
# is "src/source.js" (relative to this YAML file) | ||
# and the prepend path is "base/dir" | ||
# then the coverage report will show | ||
# "base/dir/src/source.js" | ||
prepend_path: static | ||
|
||
# Paths to library JavaScript files (optional) | ||
lib_paths: | ||
- js/bower | ||
|
||
# Paths to source JavaScript files | ||
src_paths: | ||
- js/src | ||
|
||
# Paths to spec (test) JavaScript files | ||
spec_paths: | ||
- js/spec | ||
- js/spec_helpers | ||
|
||
# Paths to fixture files (optional) | ||
# The fixture path will be set automatically when using jasmine-jquery. | ||
# (https://github.com/velesin/jasmine-jquery) | ||
# | ||
# You can then access fixtures using paths relative to | ||
# the test suite description: | ||
# | ||
# loadFixtures('path/to/fixture/fixture.html'); | ||
# | ||
#fixture_paths: | ||
# - js/fixture | ||
|
||
# Regular expressions used to exclude *.js files from | ||
# appearing in the test runner page. | ||
# Some test runners (like the jasmine runner) include files by default, | ||
# which means that they are loaded using a <script> tag in the test | ||
# runner page. When loading many files, this can be slow, so | ||
# exclude any files you don't need. | ||
# Note that not all runners behave the same way: for example, the | ||
# jasmine_requirejs runner does not include files using <script> tags | ||
# by default, and so will ignore this directive. | ||
#exclude_from_page: | ||
# - js/lib/ | ||
|
||
# Regular expression used to guarantee that a *.js file | ||
# is included in the test runner page. | ||
# If a file name matches both `exclude_from_page` and | ||
# `include_in_page`, the file WILL be included. | ||
# You can use this to exclude all files in a directory, | ||
# but make an exception for particular files. | ||
#include_in_page: | ||
# - js/lib/exclude/exception_.*\.js | ||
|
||
requirejs: | ||
paths: | ||
main: js/spec/main | ||
|
||
# Because require.js is responsible for loading all dependencies, we exclude | ||
# all files from being included in <script> tags | ||
exclude_from_page: | ||
- .* |