X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=testing%2Fqunit%2Funit-tests.js;h=476e1459aeb789693bdcce4ab3e301867ab18398;hb=15a32ab1123375e1a52c319fca71ab8d02c58261;hp=c16b8c916a8676ed17b29ad01ec5766ba3fa5d53;hpb=acfa0e6c1ccbbaa00025b209272c46b386588d48;p=matches%2FMCTX3420.git diff --git a/testing/qunit/unit-tests.js b/testing/qunit/unit-tests.js index c16b8c9..476e145 100644 --- a/testing/qunit/unit-tests.js +++ b/testing/qunit/unit-tests.js @@ -2,70 +2,141 @@ * MCTX3420 2013 - Remote pressurised can experiment. * Unit testing for the server API. * These unit tests use the QUnit unit testing framework. - * @requires QUnit and jQuery + * @requires QUnit, jQuery, and base64.js * @date 28/8/13 * @author Jeremy Tan */ -var api = location.protocol + "//" + location.host + "/api/"; +//Namespace ut + +ut = {}; +ut.api = location.protocol + "//" + location.host + "/api/"; +ut.controlcb = $.Deferred(); /** - * Sends an AJAX query to the API + * Sends a synchronous AJAX query to the API + * A synchronous request makes it easier for unit testing. * @param {string} module The name of the module to be queried - * @param {Object} opts Object containing parameters to pass to module - * @param {function} callback Function that receives JSON data - * @param {string} username Optional - * @param {string} password Required if username specified - * @returns JSON data + * @param {Object} opts Object holding the parameters, username, password and + * callback. The parameters should be an object of key/value + * pairs. + * @returns jqXHR object (but calls callback with JSON data, or null on AJAX error) */ -function query(module, opts, callback, username, password) { - function buildQuery(opts) { - var result = "?"; - var first = true; - - for (key in opts) { - if (!first) - result += "&"; - else - first = false; - result += encodeURIComponent(key) + - (opts.key ? "=" + encodeURIComponent(opts.key) : ""); - } - return result; - } +function query(module, opts) { + var queryurl = ut.api + module; - var queryurl = api + module; - if (opts) - queryurl += buildQuery(opts); + var authfunc; + if (opts.username) { + authfunc = function(xhr) { + xhr.setRequestHeader("Authorization", + "Basic " + base64.encode(opts.username + ":" + opts.password)); + }; + } - $.ajax({ + return $.ajax({ url: queryurl, type: 'GET', dataType: 'json', - beforeSend: !username ? undefined : function (xhr) { - xhr.setRequestHeader("Authorization", - "Basic " + btoa(username + ":" + password)); - } - }).done(callback) + data: opts.params, + beforeSend: authfunc, + async: false + }).done(opts.callback) .fail(function(jqXHR) { - if (jqXHR.status === 400) { - callback($.parseJSON(jqXHR.responseText)); - } else { - callback({status:-999, - description: jqXHR.status.toString() + " " + jqXHR.responseText}); - } + ok(false, "Request failed: " + jqXHR.status.toString() + " " + jqXHR.statusText); + opts.callback(null); }); } -QUnit.test("API Existence", function () { - stop(); //????? - query("test", undefined, function(data) { - equal(parseInt(data.status, 10), -1, "Nonexistent module"); //Magic numbers! - start(); - }); +QUnit.module("API basics"); +QUnit.test("API Existence (identify)", function () { + query("identify", {params : {actuators : true, sensors : true}, + callback : function(data) { + ok(data.status > 0, "Return status"); + ok(data.description !== undefined, data.description); + ok(data.build_date !== undefined, data.build_date); + ok(data.api_version !== undefined, "API version: " + data.api_version); + ok(data.sensors !== undefined, "Sensors list"); + ok(data.actuators !== undefined, "Actuators list"); + + var sl = "Sensors: ", al = "Actuators: "; + for (var id in data.sensors) { + sl += id + ":" + data.sensors[id] + " "; + } + for (var id in data.actuators) { + al += id + ":" + data.actuators[id] + " "; + } + ok(sl, sl); + ok(al, al); + }}); +}); - /*query("version", undefined, function (data) { - assert.equal(data.status, 0); - });*/ - +QUnit.test("Invalid module", function () { + query("dontexist", {callback : function(data) { + ok(data.status < 0); + }}); +}); + +QUnit.module("Sensors"); +QUnit.test("Existence", function() { + query("identify", {params : {sensors : 1}, callback : function(data) { + ok(data.status > 0, "Identification"); + var hasSensor = false; + for (var id in data.sensors) { + hasSensor = true; + query("sensors", {params : {id : id}, callback : function(data) { + ok(data.status > 0, "Sensor " + id); + ok(data.data !== undefined, "Data field existence"); + var result = "Data: "; + for (var i = 0; i < data.data.length; i++) { + result += data.data[i][0] + ":" + data.data[i][1] + ", "; + } + ok(true, result); + }}); + } + ok(hasSensor, "Has at least one sensor"); + }}); + +}); + +QUnit.test("Invalid sensor ids", function() { + query("sensors", {params : {id : ""}, callback : function(data) { + ok(data.status < 0, "No id"); + }}); + query("sensors", {params : {id : 999}, callback : function(data) { + ok(data.status < 0, "Id too large"); + }}); + query("sensors", {params : {id : "-1"}, callback : function(data) { + ok(data.status < 0, "Negative id"); + }}); +}); + +QUnit.module("Controls and access"); +QUnit.asyncTest("Setting actuator value", function () { + $.when(ut.controlcb).done(function () { + start(); + var key; + + query("control", {params : {action : "start", force : true}, + username : $("#username").val(), password : $("#password").val(), + async : false, + callback : function(data) { + ok(data.status > 0, "Gaining access key"); + ok(data.key, "Access key - " + data.key); + key = data.key; + }}); + query("control", {params : {action : "set", id : 0, + username : $("#username").val(), password : $("#password").val(), + value : 200, key : key}, + callback : function(data) { + ok(data.status > 0, "Setting actuator"); + ok(true, data.description); + }}); + }); +}); + +$(document).ready(function(){ + $("#control").submit(function () { + ut.controlcb.resolve(); + return false; + }); }); \ No newline at end of file