diff --git a/.gitignore b/.gitignore
index e8b5f53..4d80206 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ client/dialclient
server/dialserver
server/tests/run_tests
client/report.html
+node_modules/*
diff --git a/server/tests/js_tests/libs/dialClient.js b/server/tests/js_tests/libs/dialClient.js
new file mode 100644
index 0000000..ba2509b
--- /dev/null
+++ b/server/tests/js_tests/libs/dialClient.js
@@ -0,0 +1,407 @@
+"use strict";
+
+var ssdp = require("node-ssdp"),
+ httpRequest = require("request"),
+ Q = require("q");
+
+var Client = ssdp.Client,
+ client = new Client();
+
+var servers = []; // Persist discovered servers
+
+function discover() {
+ servers = []; // Re-initialize persisted servers
+ var dialServers = {};
+ // On M-Search response
+ client.on("response", function (headers) {
+ if(dialServers[headers.USN] === undefined) { //Resolve duplicates by USN
+ dialServers[headers.USN] = {
+ location : headers.LOCATION,
+ host : headers.LOCATION.split("http://")[1].split(":")[0],
+ ST : headers.ST
+ };
+ if(headers.WAKEUP) {
+ var wakeup = headers.WAKEUP;
+ dialServers[headers.USN].mac = wakeup.split(";")[0].split("=")[1];
+ dialServers[headers.USN].timeout = wakeup.split(";")[1].split("=")[1];
+ }
+
+ servers.push(dialServers[headers.USN]);
+ }
+ });
+
+ // Send M-Search request
+ client.search("urn:dial-multiscreen-org:service:dial:1");
+
+ return new Q.Promise(function (resolve) {
+ setTimeout(function () {
+ client.stop();
+ return resolve(servers);
+ }, 5000);
+ });
+}
+
+function getApplicationStatus(host, app, clientDialVer) {
+ clientDialVer = clientDialVer || "2.1"; // To test backward compatibility
+
+ return new Q()
+ .then(constructAppResourceUrl.bind(null, host, app))
+ .then(function (appResourceUrl) {
+ appResourceUrl += clientDialVer === "2.1" ? "?clientDialVer='2.1'" : "";
+ return appResourceUrl;
+ })
+ .then(function (appResourceUrl) {
+ return new Q.Promise(function (resolve, reject) {
+ // Get application status
+ return httpRequest({
+ url: appResourceUrl,
+ method: "GET",
+ timeout: 6000
+ }, function handleResponse(error, response, body) {
+ if(!error) {
+ // Check for correct header and status code
+ var statusCode = response.statusCode;
+ var contentType = response.headers["content-type"];
+ if(statusCode !== 200) {
+ return reject(new Error("Expected statusCode 200 while querying app status but got " + statusCode));
+ }
+ // TODO: Remove application/xml from accepted types
+ if(contentType.indexOf("text/xml") === -1 && contentType.indexOf("application/xml") === -1) {
+ return reject(new Error("Expected MIME type 'text/xml' while querying app status but got " + contentType));
+ }
+ // Extract fields from body
+ try {
+ if(body.indexOf("xmlns") === -1 || body.indexOf("name") === -1 || body.indexOf("state") === -1) {
+ return reject(new Error("One or more required fields were not present in the application status response"));
+ }
+ var parsedResponse = {
+ "xmlns" : body.split("xmlns=")[1].split(" ")[0].split(">")[0].replace(/\"/g, ""),
+ "name" : body.split("")[1].split("")[0].replace(/\s/g, ""),
+ "state" : body.split("")[1].split("")[0].replace(/\s/g, "")
+ };
+
+ if(body.indexOf("dialVer") !== -1) {
+ parsedResponse.dialVer = body.split("dialVer=")[1].split(" ")[0].split(">")[0].replace(/\s/g, "").replace(/\"/g, "");
+ }
+ if(body.indexOf("allowStop") !== -1) {
+ parsedResponse.allowStop = body.split("")[0].replace(/\s/g, "").replace(/\"/g, "");
+ }
+ if(body.indexOf("")[0].replace(/\"/g, "");
+ if(parsedResponse.rel !== "run") {
+ return reject(new Error("link rel is not 'run' in the application status response"));
+ }
+ parsedResponse.href = body.split("href=")[1].split(" ")[0].split("/>")[0].replace(/\s/g, "").replace(/\"/g, "");
+ }
+ if(body.indexOf("") !== -1) {
+ parsedResponse.additionalData = body.split("")[1].split("")[0].replace(/\s/g, "");
+ }
+ if(parsedResponse.xmlns !== "urn:dial-multiscreen-org:schemas:dial") {
+ return reject(new Error("xmlns is not 'urn:dial-multiscreen-org:schemas:dial' in the app status response " + parsedResponse.xmlns));
+ }
+
+ return resolve(parsedResponse);
+ }
+ catch (err) {
+ return reject(new Error("There was a problem extracting fields from app status. Status returned : " + body));
+ }
+ }
+ return Q.reject(new Error("Error getting app status " + error));
+ });
+ });
+ });
+}
+
+function launchApplication(host, app, payload) {
+ return new Q()
+ .then(constructAppResourceUrl.bind(null, host, app))
+ .then(function (appResourceUrl) {
+ var request = {
+ url: appResourceUrl,
+ method: "POST",
+ timeout: 6000,
+ headers: {
+ // TODO: Remove host header
+ "Host" : appResourceUrl.split("http://")[1].split("/")[0],
+ // TODO: Check charset
+ "Content-Type" : "text/plain;charset=\"utf-8\""
+ }
+ };
+ if(!payload) {
+ // Set Content-Length: 0
+ request.headers["Content-Length"] = 0;
+ }
+ else {
+ // Set the payload
+ request.body = payload;
+ }
+ return new Q.Promise(function (resolve, reject) {
+ return httpRequest(request, function handleResponse(error, response) {
+ if(!error) {
+ return resolve(response.statusCode);
+ }
+ return reject(new Error("Error launching application " + error));
+ });
+ });
+ });
+}
+
+function stopApplication(host, app) {
+ return new Q()
+ .then(constructAppResourceUrl.bind(null, host, app))
+ .then(function (appResourceUrl) {
+ return getApplicationStatus(host, app)
+ .then(function (response) {
+ if(response.href) {
+ return appResourceUrl + "/" + response.href; // Construct Application Instance Url
+ }
+ return Q.reject(new Error("Could not get instance href from application status to construct Application Instance Url"));
+ });
+ })
+ .then(function (appResourceUrl) {
+ var request = {
+ url: appResourceUrl,
+ method: "DELETE",
+ timeout: 6000,
+ // TODO: Remove host header
+ headers: {"Host" : appResourceUrl.split("http://")[1].split("/")[0]}
+ };
+ return new Q.Promise(function (resolve, reject) {
+ return httpRequest(request, function handleResponse(error, response) {
+ if(!error) {
+ return resolve(response.statusCode);
+ }
+ return reject(new Error("Error stopping application " + error));
+ });
+ });
+ });
+}
+
+function hideApplication(host, app) {
+ return new Q()
+ .then(constructAppResourceUrl.bind(null, host, app))
+ .then(function (appResourceUrl) {
+ return getApplicationStatus(host, app)
+ .then(function (response) {
+ if(response.href) {
+ return appResourceUrl + "/" + response.href + "/hide"; // Construct Application Instance Url
+ }
+ return Q.reject(new Error("Could not get instance href from application status to construct Application Instance Url"));
+ });
+ })
+ .then(function (appResourceUrl) {
+ var request = {
+ url: appResourceUrl,
+ method: "POST",
+ timeout: 6000,
+ // TODO: Remove host header
+ headers: {"Host" : appResourceUrl.split("http://")[1].split("/")[0]}
+ };
+ return new Q.Promise(function (resolve, reject) {
+ return httpRequest(request, function handleResponse(error, response) {
+ if(!error) {
+ return resolve(response.statusCode);
+ }
+ return reject(new Error("Error hiding application " + error));
+ });
+ });
+ });
+}
+
+function stopApplicationInstance(instanceUrl) {
+ return new Q()
+ .then(function () {
+ var request = {
+ url: instanceUrl,
+ method: "DELETE",
+ timeout: 6000,
+ // TODO: Remove host header
+ headers: {"Host" : instanceUrl.split("http://")[1].split("/")[0]}
+ };
+ return new Q.Promise(function (resolve, reject) {
+ return httpRequest(request, function handleResponse(error, response) {
+ if(!error) {
+ return resolve(response.statusCode);
+ }
+ return reject(new Error("Error stopping application " + error));
+ });
+ });
+ });
+}
+
+function hideApplicationInstance(instanceUrl) {
+ return new Q()
+ .then(function () {
+ var request = {
+ url: instanceUrl,
+ method: "POST",
+ timeout: 6000,
+ // TODO: Remove host header
+ headers: {"Host" : instanceUrl.split("http://")[1].split("/")[0]}
+ };
+ return new Q.Promise(function (resolve, reject) {
+ return httpRequest(request, function handleResponse(error, response) {
+ if(!error) {
+ return resolve(response.statusCode);
+ }
+ return reject(new Error("Error hiding application " + error));
+ });
+ });
+ });
+}
+
+function constructAppResourceUrl(host, appName) {
+ if(host === undefined) {
+ return Q.reject(new Error("Host address is required to construct Application Resource URL"));
+ }
+ if(appName === undefined) {
+ return Q.reject(new Error("Application name is required to construct Application Resource URL"));
+ }
+
+ return new Q()
+ .then(getAppsUrl.bind(null, host))
+ .then(function (appUrl) {
+ return appUrl.replace(/\/+$/, "") + "/" + appName;
+ });
+}
+
+function getAppsUrl(host) {
+ if(host === undefined) {
+ return Q.reject(new Error("Host is required to query for Application-URL"));
+ }
+ // Check if value is persisted
+ var found = false;
+ var appUrl;
+ servers.forEach(function (server) {
+ if(server.host === host && server.appUrl !== undefined) {
+ found = true;
+ appUrl = server.appUrl;
+ }
+ });
+
+ if(found) {
+ return appUrl;
+ }
+
+ // If value is not persisted
+ return new Q()
+ .then(getLocation.bind(null, host))
+ .then(function (location) {
+ return new Q.Promise(function (resolve, reject) {
+ return httpRequest({
+ url: location,
+ method: "GET",
+ timeout: 6000
+ }, function handleResponse(error, response) {
+ if(!error && response.statusCode === 200) {
+ return resolve(response.headers["application-url"]);
+ }
+ else if(!error) {
+ return reject(new Error("Querying for Application-URL returned status code " + response.statusCode));
+ }
+ return reject(new Error("Querying for Application-URL returned " + error));
+ });
+ });
+ })
+ // Persist it
+ .then(function (applicationUrl) {
+ servers.forEach(function (server) {
+ if(server.host === host) {
+ server.appUrl = applicationUrl;
+ }
+ });
+ return applicationUrl;
+ });
+}
+
+function getLocation(host) {
+ if(host === undefined) {
+ return Q.reject(new Error("Host address is required to get corresponding LOCATION"));
+ }
+
+ var found = false;
+ var location;
+
+ // Check if host is present in persisted list
+ servers.forEach(function (server) {
+ if(server.host === host) {
+ location = server.location;
+ found = true;
+ }
+ });
+ if(found) {
+ return location;
+ }
+
+ // If not persisted, perform discovery
+ return new Q()
+ .then(discoverSpecificHost.bind(null, host))
+ .then(function (serverObj) {
+ return serverObj.location;
+ });
+}
+
+function discoverSpecificHost(host) {
+ if(host === undefined) {
+ return Q.reject(new Error("Host is required field for discoverSpecificHost function"));
+ }
+
+ var found = false;
+ var serverObjFound;
+
+ servers.forEach(function (server) {
+ if(server.host === host) {
+ serverObjFound = server;
+ found = true;
+ }
+ });
+
+ if(found) {
+ return serverObjFound;
+ }
+ return new Q.Promise(function (resolve, reject) {
+ // On M-Search response
+ client.on("response", function (headers) {
+ var extractedHost = headers.LOCATION.split("http://")[1].split(":")[0];
+ if(host === extractedHost) {
+ client.stop();
+ var mac, timeout;
+ if(headers.WAKEUP) {
+ var wakeup = headers.WAKEUP;
+ mac = wakeup.split(";")[0].split("=")[1];
+ timeout = wakeup.split(";")[1].split("=")[1];
+ }
+ var serverObj = {
+ location : headers.LOCATION,
+ host : headers.LOCATION.split("http://")[1].split(":")[0],
+ ST : headers.ST,
+ mac : mac,
+ timeout : timeout
+ };
+ servers.push(serverObj);
+ clearTimeout(timer);
+ return resolve(serverObj);
+ }
+ });
+
+ // Send M-Search request
+ client.search("urn:dial-multiscreen-org:service:dial:1");
+
+ var timer = setTimeout(function () {
+ client.stop();
+ return reject(new Error("Could not discover host " + host));
+ }, 5000);
+ });
+}
+
+module.exports.discover = discover;
+module.exports.discoverSpecificHost = discoverSpecificHost;
+module.exports.getApplicationStatus = getApplicationStatus;
+module.exports.launchApplication = launchApplication;
+module.exports.stopApplication = stopApplication;
+module.exports.hideApplication = hideApplication;
+module.exports.stopApplicationInstance = stopApplicationInstance;
+module.exports.hideApplicationInstance = hideApplicationInstance;
+module.exports.constructAppResourceUrl = constructAppResourceUrl;
+module.exports.getAppsUrl = getAppsUrl;
+module.exports.getLocation = getLocation;
diff --git a/server/tests/js_tests/libs/utils.js b/server/tests/js_tests/libs/utils.js
new file mode 100644
index 0000000..4fb653e
--- /dev/null
+++ b/server/tests/js_tests/libs/utils.js
@@ -0,0 +1,14 @@
+"use strict";
+
+function getParam(key) {
+ var value;
+ var args = process.argv.slice(2);
+ args.forEach(function (param) {
+ if(param.indexOf(key + "=") === 0) {
+ value = param.split("=")[1];
+ }
+ });
+ return value;
+}
+
+module.exports.getParam = getParam;
diff --git a/server/tests/js_tests/package.json b/server/tests/js_tests/package.json
new file mode 100644
index 0000000..628c9b3
--- /dev/null
+++ b/server/tests/js_tests/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "dialtests",
+ "version": "1.0.0",
+ "description": "Tests for DIAL server using nf-dialclient",
+ "main": "index.js",
+ "scripts": {
+ },
+ "author": "Shruti Ranganathan Jothi",
+ "license": "unlicensed",
+ "dependencies": {
+ "q": "~1.4.1",
+ "node-ssdp": "^3.2.0",
+ "request": "^2.78.0"
+ }
+}
diff --git a/server/tests/js_tests/tests/discoverServerUnderTest.js b/server/tests/js_tests/tests/discoverServerUnderTest.js
new file mode 100644
index 0000000..7efb13f
--- /dev/null
+++ b/server/tests/js_tests/tests/discoverServerUnderTest.js
@@ -0,0 +1,38 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var testServer = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Perform DIAL discovery and ensure that the server under test is discovered");
+ })
+ .then(dial.discover)
+ .then(function findServerInList(servers) {
+ var found = false;
+ servers.forEach(function (server) {
+ if(server.host === testServer) {
+ found = true;
+ }
+ });
+ if(!found) {
+ return Q.reject(new Error("DIAL client was not able to discover the server under test : " + testServer));
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.log("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/hideInvalidApplicationInstance.js b/server/tests/js_tests/tests/hideInvalidApplicationInstance.js
new file mode 100644
index 0000000..4f777f5
--- /dev/null
+++ b/server/tests/js_tests/tests/hideInvalidApplicationInstance.js
@@ -0,0 +1,60 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Try to hide an invalid instance of Netflix application and expect status code 404");
+ })
+ .then(dial.launchApplication.bind(null, host, "Netflix"))
+ .then(function (status) {
+ if(status !== 200 && status !== 201) {
+ return Q.reject(new Error("Error launching Netflix application. Expected status code 200/201 but got " + status));
+ }
+ })
+ .then(function () {
+ return dial.getApplicationStatus(host, "Netflix");
+ })
+ .then(function getCurrentAppState(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Could not retrieve current Netflix application state"));
+ }
+ if(result.dialVer && result.dialVer !== "2.1") {
+ return Q.reject(new Error("This test is only applicable for DIAL version >= 2.1"));
+ }
+ return result.state;
+ })
+ .then(function () {
+ return dial.getAppsUrl(host);
+ })
+ .then(function (appsUrl) {
+ var invalidInstanceUrl = appsUrl + "/application/xyz";
+ return invalidInstanceUrl;
+ })
+ .then(function (url) {
+ return dial.hideApplicationInstance(url);
+ })
+ .then(function (status) {
+ if(status !== 404) {
+ return Q.reject(new Error("Tried to hide invalid application instance. Expected statusCode: 404 but got " + status));
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/hideNetflixWhenAlreadyHidden.js b/server/tests/js_tests/tests/hideNetflixWhenAlreadyHidden.js
new file mode 100644
index 0000000..f144380
--- /dev/null
+++ b/server/tests/js_tests/tests/hideNetflixWhenAlreadyHidden.js
@@ -0,0 +1,67 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Try to hide netflix when it is already in hidden state and expect response code 200 from the DIAL server");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function hideApp(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Could not retrieve current Netflix application state"));
+ }
+ if(result.state !== "hidden") {
+ if(!result.dialVer || result.dialVer !== "2.1") { // Hidden state not supported
+ return Q.reject(new Error("This test is only applicable for DIAL version >= 2.1"));
+ }
+
+ if(result.state === "stopped") {
+ // Launch and hide app
+ return dial.launchApplication(host, "Netflix")
+ .delay(5000)
+ .then(dial.hideApplication.bind(null, host, "Netflix"))
+ .delay(5000);
+ }
+ else if(result.state === "starting" || result.state === "running") {
+ // Hide app
+ return dial.hideApplication(host, "Netflix")
+ .delay(5000);
+ }
+ }
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function checkAppStatus(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Could not retrieve current Netflix application state"));
+ }
+ if(result.state !== "hidden") {
+ return Q.reject(new Error("Expected Netflix app status to be hidden but the state was " + result.state));
+ }
+ })
+
+ .then(dial.hideApplication.bind(null, host, "Netflix"))
+ .then(function (status) {
+ if(status !== 200) {
+ return Q.reject(new Error("Tried to hide Netflix. Expected statusCode: 200 but got " + status));
+ }
+ })
+ .delay(5000)
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/hideNetflixWhenRunning.js b/server/tests/js_tests/tests/hideNetflixWhenRunning.js
new file mode 100644
index 0000000..a249bcc
--- /dev/null
+++ b/server/tests/js_tests/tests/hideNetflixWhenRunning.js
@@ -0,0 +1,55 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Hide netflix application when it is running and expect response code 200");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function getCurrentAppState(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Could not retrieve current Netflix application state"));
+ }
+ if(result.dialVer && result.dialVer !== "2.1") {
+ return Q.reject(new Error("This test is only applicable for DIAL version >= 2.1"));
+ }
+ return result.state;
+ })
+
+ .then(function startAppIfNotRunning(state) {
+ if(state !== "running") {
+ return dial.launchApplication(host, "Netflix")
+ .then(function (status) {
+ if(status !== 201) {
+ return Q.reject(new Error("Could not launch Netflix application. Expected status code 201 but got " + status));
+ }
+ });
+ }
+ })
+ .delay(5000) // Allow time for app to start
+
+ .then(dial.hideApplication.bind(null, host, "Netflix"))
+ .then(function (status) {
+ if(status !== 200) {
+ return Q.reject(new Error("Error stopping Netflix application. Expected status code 200 but got " + status));
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/launchAppNotRecognized.js b/server/tests/js_tests/tests/launchAppNotRecognized.js
new file mode 100644
index 0000000..14933e7
--- /dev/null
+++ b/server/tests/js_tests/tests/launchAppNotRecognized.js
@@ -0,0 +1,38 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Launch an invalid application using DIAL server and check for response code 404");
+ })
+ .then(dial.launchApplication.bind(null, host, "InvalidApplication"))
+ .then(function (status) {
+ if(status !== 404) {
+ return Q.reject(new Error("Tried to launch invalid application using DIAL server. Expected statusCode: 404 but got " + status));
+ }
+ })
+ .then(dial.launchApplication.bind(null, host, "InvalidApplication", "key1=val1&key2=val2"))
+ .then(function (status) {
+ if(status !== 404) {
+ return Q.reject(new Error("Tried to launch invalid application with a payload using DIAL server. Expected statusCode: 404 but got " + status));
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/launchNetflixAlreadyRunningWithNoPayload.js b/server/tests/js_tests/tests/launchNetflixAlreadyRunningWithNoPayload.js
new file mode 100644
index 0000000..83faea3
--- /dev/null
+++ b/server/tests/js_tests/tests/launchNetflixAlreadyRunningWithNoPayload.js
@@ -0,0 +1,52 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Launch Netflix without payload using DIAL server when application is already running and check for response code 200/201");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function getCurrentAppState(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Error retrieving current Netflix application state"));
+ }
+ return result.state;
+ })
+
+ .then(function startAppIfNotRunning(state) {
+ if(state !== "starting" || state !== "running") {
+ return dial.launchApplication(host, "Netflix")
+ .then(function (status) {
+ if(status !== 201) {
+ return Q.reject(new Error("Error launching Netflix application. Expected status code 201 from DIAL server but got " + status));
+ }
+ });
+ }
+ })
+ .delay(5000)
+
+ .then(dial.launchApplication.bind(null, host, "Netflix"))
+ .then(function (status) {
+ if(status !== 201 && status !== 200) {
+ return Q.reject(new Error("Error launching Netflix application when it was already running. Expected status code 200/201 from DIAL server but got " + status));
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/launchNetflixAlreadyRunningWithPayload.js b/server/tests/js_tests/tests/launchNetflixAlreadyRunningWithPayload.js
new file mode 100644
index 0000000..1571f1a
--- /dev/null
+++ b/server/tests/js_tests/tests/launchNetflixAlreadyRunningWithPayload.js
@@ -0,0 +1,52 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Launch Netflix with payload using DIAL server when application is already running and check for response code 200/201");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function getCurrentAppState(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Error retrieving current Netflix application state"));
+ }
+ return result.state;
+ })
+
+ .then(function startAppIfNotRunning(state) {
+ if(state !== "starting" || state !== "running") {
+ return dial.launchApplication(host, "Netflix")
+ .then(function (status) {
+ if(status !== 201) {
+ return Q.reject(new Error("Error launching Netflix application. Expected status code 201 from DIAL server but got " + status));
+ }
+ });
+ }
+ })
+ .delay(5000)
+
+ .then(dial.launchApplication.bind(null, host, "Netflix", "key1=val1&key2=val2"))
+ .then(function (status) {
+ if(status !== 201 && status !== 200) {
+ return Q.reject(new Error("Error launching Netflix application when it was already running. Expected status code 200/201 from DIAL server but got " + status));
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/launchNetflixNotRunningWithNoPayload.js b/server/tests/js_tests/tests/launchNetflixNotRunningWithNoPayload.js
new file mode 100644
index 0000000..9283d2a
--- /dev/null
+++ b/server/tests/js_tests/tests/launchNetflixNotRunningWithNoPayload.js
@@ -0,0 +1,57 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Launch Netflix application using DIAL server when the application is in STOPPED state");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function getCurrentAppState(result) {
+ if(!result || !result.state) {
+ return Q.reject("Could not retrieve current Netflix application state");
+ }
+ if(result.state !== "stopped") {
+ if(result.allowStop && result.allowStop === "false") {
+ return Q.reject(new Error("The DIAL server does not support STOP operation. Test cannot proceed. Make sure the Netflix app is stopped before re-running the test"));
+ }
+ }
+ return result.state;
+ })
+ .then(function stopAppIfCurrentlyRunning(state) {
+ if(state !== "stopped") {
+ return dial.stopApplication(host, "Netflix")
+ .then(function (status) {
+ if(status !== 200) {
+ return Q.reject(new Error("Could not stop Netflix application when it was running. Expected status code 200 but got " + status));
+ }
+ });
+ }
+ })
+ .delay(5000)
+
+ .then(dial.launchApplication.bind(null, host, "Netflix"))
+ .then(function (status) {
+ if(status !== 201) {
+ return Q.reject(new Error("Error launching Netflix application. Expected statusCode: 201 but got " + status));
+ }
+ })
+ .delay(5000)
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/launchNetflixNotRunningWithPayload.js b/server/tests/js_tests/tests/launchNetflixNotRunningWithPayload.js
new file mode 100644
index 0000000..cf22d9e
--- /dev/null
+++ b/server/tests/js_tests/tests/launchNetflixNotRunningWithPayload.js
@@ -0,0 +1,57 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Launch Netflix application with payload using DIAL server when the application is in STOPPED state");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function getCurrentAppState(result) {
+ if(!result || !result.state) {
+ return Q.reject("Could not retrieve current Netflix application state");
+ }
+ if(result.state !== "stopped") {
+ if(result.allowStop && result.allowStop === "false") {
+ return Q.reject(new Error("The DIAL server does not support STOP operation. Test cannot proceed. Make sure the Netflix app is stopped before re-running the test"));
+ }
+ }
+ return result.state;
+ })
+ .then(function stopAppIfCurrentlyRunning(state) {
+ if(state !== "stopped") {
+ return dial.stopApplication(host, "Netflix")
+ .then(function (status) {
+ if(status !== 200) {
+ return Q.reject(new Error("Could not stop Netflix application when it was running. Expected status code 200 but got " + status));
+ }
+ });
+ }
+ })
+ .delay(5000)
+
+ .then(dial.launchApplication.bind(null, host, "Netflix", "key1=val1&key2=val2"))
+ .then(function (status) {
+ if(status !== 201) {
+ return Q.reject(new Error("Error launching Netflix application. Expected statusCode: 201 but got " + status));
+ }
+ })
+ .delay(5000)
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/launchNetflixWhenHiddenWithNoPayload.js b/server/tests/js_tests/tests/launchNetflixWhenHiddenWithNoPayload.js
new file mode 100644
index 0000000..3814724
--- /dev/null
+++ b/server/tests/js_tests/tests/launchNetflixWhenHiddenWithNoPayload.js
@@ -0,0 +1,67 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + "Launch Netflix application using DIAL server when app is in hidden state and check for response code 201 ");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function hideApp(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Error retrieving current Netflix application state"));
+ }
+ if(result.state !== "hidden") {
+ if(result.dialVer && result.dialVer !== "2.1") { // Hidden state not supported
+ return Q.reject(new Error("This test is only applicable for DIAL version >= 2.1"));
+ }
+
+ if(result.state === "stopped") {
+ // Launch and hide app
+ return dial.launchApplication(host, "Netflix")
+ .delay(5000)
+ .then(dial.hideApplication.bind(null, host, "Netflix"))
+ .delay(5000);
+ }
+ else if(result.state === "starting" || result.state === "running") {
+ // Hide app
+ return dial.hideApplication(host, "Netflix")
+ .delay(5000);
+ }
+ }
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function checkAppStatus(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Error retrieving current Netflix application state"));
+ }
+ if(result.state !== "hidden") {
+ return Q.reject(new Error("Expected Netflix app status to be hidden but the status was " + result.state));
+ }
+ })
+
+ .then(dial.launchApplication.bind(null, host, "Netflix"))
+ .then(function (status) {
+ if(status !== 201) {
+ return Q.reject(new Error("Error launching Netflix application when it was in hidden state. Expected statusCode: 201 but got " + status));
+ }
+ })
+ .delay(5000) //Allow time for app to launch
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/launchNetflixWhenHiddenWithPayload.js b/server/tests/js_tests/tests/launchNetflixWhenHiddenWithPayload.js
new file mode 100644
index 0000000..a574820
--- /dev/null
+++ b/server/tests/js_tests/tests/launchNetflixWhenHiddenWithPayload.js
@@ -0,0 +1,67 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + "Launch Netflix application with payload using DIAL server when app is in hidden state and check for response code 201 ");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function hideApp(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Error retrieving current Netflix application state"));
+ }
+ if(result.state !== "hidden") {
+ if(result.dialVer && result.dialVer !== "2.1") { // Hidden state not supported
+ return Q.reject(new Error("This test is only applicable for DIAL version >= 2.1"));
+ }
+
+ if(result.state === "stopped") {
+ // Launch and hide app
+ return dial.launchApplication(host, "Netflix")
+ .delay(5000)
+ .then(dial.hideApplication.bind(null, host, "Netflix"))
+ .delay(5000);
+ }
+ else if(result.state === "starting" || result.state === "running") {
+ // Hide app
+ return dial.hideApplication(host, "Netflix")
+ .delay(5000);
+ }
+ }
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function checkAppStatus(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Error retrieving current Netflix application state"));
+ }
+ if(result.state !== "hidden") {
+ return Q.reject(new Error("Expected Netflix app status to be hidden but the status was " + result.state));
+ }
+ })
+
+ .then(dial.launchApplication.bind(null, host, "Netflix", "key1=val1&key2=val2"))
+ .then(function (status) {
+ if(status !== 201) {
+ return Q.reject(new Error("Error launching Netflix application when it was in hidden state. Expected statusCode: 201 but got " + status));
+ }
+ })
+ .delay(5000) //Allow time for app to launch
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/launchNetflixWithExcessPayload.js b/server/tests/js_tests/tests/launchNetflixWithExcessPayload.js
new file mode 100644
index 0000000..97fd799
--- /dev/null
+++ b/server/tests/js_tests/tests/launchNetflixWithExcessPayload.js
@@ -0,0 +1,66 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ var payload = "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&"
+ + "key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value&key=value";
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Try to launch Netflix app with excess payload and ensure DIAL server returns response code 413");
+ })
+ .then(dial.launchApplication.bind(null, host, "Netflix", payload))
+ .then(function (status) {
+ if(status !== 413) {
+ return Q.reject(new Error("Tried to launch Netflix with excess payload. Expected statusCode: 413 but got " + status));
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/netflixTests.js b/server/tests/js_tests/tests/netflixTests.js
new file mode 100644
index 0000000..2896727
--- /dev/null
+++ b/server/tests/js_tests/tests/netflixTests.js
@@ -0,0 +1,39 @@
+"use strict";
+
+var Q = require("q");
+
+var discoverServerUnderTest = require("../tests/discoverServerUnderTest.js"),
+ launchInvalidApp = require("../tests/launchAppNotRecognized.js"),
+ launchNetflixInRunningStateWithNoPayload = require("../tests/launchNetflixAlreadyRunningWithNoPayload.js"),
+ launchNetflixInRunningStateWithPayload = require("../tests/launchNetflixAlreadyRunningWithPayload.js"),
+ launchNetflixInStoppedStateWithNoPayload = require("../tests/launchNetflixNotRunningWithNoPayload.js"),
+ launchNetflixInStoppedStateWithPayload = require("../tests/launchNetflixNotRunningWithPayload.js"),
+ launchNetflixWhenHiddenWithNoPayload = require("../tests/launchNetflixWhenHiddenWithNoPayload.js"),
+ launchNetflixWhenHiddenWithPayload = require("../tests/launchNetflixWhenHiddenWithPayload.js"),
+ launchNetflixWithExcessPayload = require("../tests/launchNetflixWithExcessPayload.js"),
+ stopInvalidNetflixInstance = require("../tests/stopInvalidNetflixInstance.js"),
+ stopNetflixInRunningState = require("../tests/stopNetflixInRunningState.js"),
+ stopNetflixInStoppedState = require("../tests/stopNetflixInStoppedState.js"),
+ stopNetflixInHiddenState = require("../tests/stopNetflixInHiddenState.js"),
+ hideInvalidApplicationInstance = require("../tests/hideInvalidApplicationInstance.js"),
+ hideNetflixWhenAlreadyHidden = require("../tests/hideNetflixWhenAlreadyHidden.js"),
+ hideNetflixWhenRunning = require("../tests/hideNetflixWhenRunning.js");
+
+new Q()
+ .then(discoverServerUnderTest.test)
+ .then(launchInvalidApp.test)
+ .then(launchNetflixInRunningStateWithNoPayload.test)
+ .then(launchNetflixInRunningStateWithPayload.test)
+ .then(launchNetflixInStoppedStateWithNoPayload.test)
+ .then(launchNetflixInStoppedStateWithPayload.test)
+ .then(launchNetflixWhenHiddenWithNoPayload.test)
+ .then(launchNetflixWhenHiddenWithPayload.test)
+ .then(launchNetflixWithExcessPayload.test)
+ .then(stopInvalidNetflixInstance.test)
+ .then(stopNetflixInRunningState.test)
+ .then(stopNetflixInStoppedState.test)
+ .then(stopNetflixInHiddenState.test)
+ .then(hideInvalidApplicationInstance.test)
+ .then(hideNetflixWhenAlreadyHidden.test)
+ .then(hideNetflixWhenRunning.test)
+ .done();
diff --git a/server/tests/js_tests/tests/stopInvalidNetflixInstance.js b/server/tests/js_tests/tests/stopInvalidNetflixInstance.js
new file mode 100644
index 0000000..81fe783
--- /dev/null
+++ b/server/tests/js_tests/tests/stopInvalidNetflixInstance.js
@@ -0,0 +1,58 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Try to stop invalid Netflix application instance and check for DIAL server response code 404");
+ })
+ .then(dial.launchApplication.bind(null, host, "Netflix"))
+ .delay(5000)
+ .then(function getCurrentAppState() {
+ return dial.getApplicationStatus(host, "Netflix")
+ .then(function (result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Error retrieving current Netflix application state"));
+ }
+ if(result.allowStop && result.allowStop === "false") {
+ return Q.reject(new Error("This test is not applicable for servers that do not support DIAL stop operation."));
+ }
+ if(result.state !== "running") {
+ return Q.reject(new Error("Expected Netflix application to be running but server returned application state as " + result.state));
+ }
+ });
+ })
+ .delay(5000)
+ .then(function () {
+ return dial.getAppsUrl(host);
+ })
+ .then(function (appsUrl) {
+ var invalidInstanceUrl = appsUrl + "/Netflix/xyz";
+ return invalidInstanceUrl;
+ })
+ .then(function (url) {
+ return dial.stopApplicationInstance(url);
+ })
+ .then(function (status) {
+ if(status !== 404) {
+ return Q.reject(new Error("Tried to stop invalid Netflix application instance. Expected statusCode: 404 but got " + status));
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/stopNetflixInHiddenState.js b/server/tests/js_tests/tests/stopNetflixInHiddenState.js
new file mode 100644
index 0000000..7a217af
--- /dev/null
+++ b/server/tests/js_tests/tests/stopNetflixInHiddenState.js
@@ -0,0 +1,69 @@
+
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Stop Netflix application using DIAL server when the application is in hidden state and expect response code 200");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function hideApp(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Could not retrieve current Netflix application state"));
+ }
+ if(result.state !== "hidden") {
+ if(!result.dialVer || result.dialVer !== "2.1") { // Hidden state not supported
+ return Q.reject(new Error("This test is only applicable for DIAL version >= 2.1"));
+ }
+
+ if(result.state === "stopped") {
+ // Launch and hide app
+ return dial.launchApplication(host, "Netflix")
+ .delay(5000)
+ .then(dial.hideApplication.bind(null, host, "Netflix"))
+ .delay(5000);
+ }
+ else if(result.state === "starting" || result.state === "running") {
+ // Hide app
+ return dial.hideApplication(host, "Netflix")
+ .delay(5000);
+ }
+ }
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function checkAppStatus(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Could not retrieve current Netflix application state"));
+ }
+ if(result.state !== "hidden") {
+ return Q.reject(new Error("Expected Netflix app status to be hidden but the status was " + result.state));
+ }
+ })
+
+ .then(dial.stopApplication.bind(null, host, "Netflix"))
+ .then(function (status) {
+ if(status !== 200) {
+ return Q.reject(new Error("Tried to stop Netflix. Expected statusCode: 200 but got " + status));
+ }
+ })
+ .delay(5000)
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/stopNetflixInRunningState.js b/server/tests/js_tests/tests/stopNetflixInRunningState.js
new file mode 100644
index 0000000..41fdcc8
--- /dev/null
+++ b/server/tests/js_tests/tests/stopNetflixInRunningState.js
@@ -0,0 +1,54 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+var host = utils.getParam("host");
+
+function test() {
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Stop Netflix application when it is running and check for response code 200 from DIAL server ");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function getCurrentAppState(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Error retrieving current Netflix application state"));
+ }
+ if(result.allowStop && result.allowStop === "false") {
+ return Q.reject(new Error("This test is not applicable for servers that do not support DIAL stop operation."));
+ }
+ return result.state;
+ })
+
+ .then(function startAppIfNotRunning(state) {
+ if(state !== "starting" && state !== "running") {
+ return dial.launchApplication(host, "Netflix")
+ .then(function (status) {
+ if(status !== 201) {
+ return Q.reject("Error launching Netflix application. Expected status code 201 but got " + status);
+ }
+ });
+ }
+ })
+ .delay(5000)
+ .then(dial.stopApplication.bind(null, host, "Netflix"))
+ .then(function (status) {
+ if(status !== 200) {
+ return Q.reject("Error stopping Netflix application. Expected status code 200 but got " + status);
+ }
+ })
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}
diff --git a/server/tests/js_tests/tests/stopNetflixInStoppedState.js b/server/tests/js_tests/tests/stopNetflixInStoppedState.js
new file mode 100644
index 0000000..5f43be3
--- /dev/null
+++ b/server/tests/js_tests/tests/stopNetflixInStoppedState.js
@@ -0,0 +1,81 @@
+"use strict";
+
+var dial = require("../libs/dialClient.js"),
+ utils = require("../libs/utils.js"),
+ Q = require("q");
+
+function test() {
+ var host = utils.getParam("host");
+ var instanceUrl;
+
+ return new Q()
+ .then(function () {
+ console.log("TEST " + __filename + ": Try to stop Netflix application using DIAL server when the application is already stopped and expect response code 200.");
+ })
+ .then(dial.getApplicationStatus.bind(null, host, "Netflix"))
+ .then(function getCurrentAppState(result) {
+ if(!result || !result.state) {
+ return Q.reject(new Error("Could not retrieve current Netflix application state"));
+ }
+ if(result.state !== "stopped") {
+ if(result.allowStop && result.allowStop === "false") {
+ return Q.reject(new Error("The DIAL server does not support STOP operation. Test cannot proceed. Make sure the Netflix app is stopped before re-running the test"));
+ }
+ }
+ return result.state;
+ })
+ .then(function getRunningInstanceUrlAndStopApp(state) {
+ if(state !== "stopped") {
+ return new Q()
+ .then(dial.constructAppResourceUrl.bind(null, host, "Netflix"))
+ .then(function getInstanceUrl(appResourceUrl) {
+ return dial.getApplicationStatus(host, "Netflix")
+ .then(function (response) {
+ if(response.href) {
+ instanceUrl = appResourceUrl + "/" + response.href; // Construct Application Instance Url
+ return instanceUrl;
+ }
+ return Q.reject(new Error("Could not get instance href from application status to construct Application Instance Url"));
+ });
+ });
+ }
+ return new Q()
+ .then(dial.launchApplication.bind(null, host, "Netflix"))
+ .delay(5000)
+ .then(function () {
+ return dial.constructAppResourceUrl(host, "Netflix");
+ })
+ .then(function getInstanceUrl(appResourceUrl) {
+ return dial.getApplicationStatus(host, "Netflix")
+ .then(function (response) {
+ if(response.href) {
+ instanceUrl = appResourceUrl + "/" + response.href; // Construct Application Instance Url
+ return instanceUrl;
+ }
+ return Q.reject(new Error("Could not get instance href from application status to construct Application Instance Url"));
+ });
+ });
+ })
+
+ .then(function stopApp() {
+ return dial.stopApplicationInstance(instanceUrl);
+ })
+ .then(function (status) {
+ if(status !== 200) {
+ return Q.reject(new Error("Could not stop Netflix application when it was running. Expected status code 200 but got " + status));
+ }
+ })
+ .delay(5000)
+ .then(function () {
+ console.log("TEST PASSED");
+ })
+ .fail(function handleError(err) {
+ console.error("TEST FAILED " + err);
+ });
+}
+
+module.exports.test = test;
+
+if (require.main === module) {
+ test.done();
+}