UNPKG

@hkvstore/taco-cli

Version:

taco-cli is a command-line interface for rapid Apache Cordova development (forked from Microsoft taco-cli)

260 lines (258 loc) 11 kB
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. /// <reference path="../../typings/mocha.d.ts" /> /// <reference path="../../typings/node.d.ts" /> /// <reference path="../../typings/should.d.ts" /> /// <reference path="../../typings/tacoTestsUtils.d.ts"/> "use strict"; /* tslint:disable:no-var-requires */ // var require needed for should module to work correctly // Note not import: We don't want to refer to shouldModule, but we need the require to occur since it modifies the prototype of Object. var shouldModule = require("should"); /* tslint:enable:no-var-requires */ var fs = require("fs"); var http = require("http"); var os = require("os"); var path = require("path"); var Q = require("q"); var request = require("request"); var rimraf = require("rimraf"); var ConnectionSecurityHelper = require("../cli/remoteBuild/connectionSecurityHelper"); var ServerMock = require("./utils/serverMock"); var Settings = require("../cli/utils/settings"); var RemoteMod = require("../cli/remote"); var RemoteMock = require("./utils/remoteMock"); var TacoUtility = require("taco-utils"); var tacoTestsUtils = require("taco-tests-utils"); var CommandHelper = require("./utils/commandHelper"); var utils = TacoUtility.UtilHelper; var MemoryStream = tacoTestsUtils.MemoryStream; var remote = CommandHelper.getCommand("remote"); describe("taco remote", function () { var testHome = path.join(os.tmpdir(), "taco-cli", "setup"); var tacoSettingsFile = path.join(testHome, "TacoSettings.json"); before(function () { utils.createDirectoryIfNecessary(testHome); process.env["TACO_HOME"] = testHome; process.env["TACO_UNIT_TEST"] = true; if (fs.existsSync(tacoSettingsFile)) { fs.unlinkSync(tacoSettingsFile); } }); after(function (done) { if (fs.existsSync(tacoSettingsFile)) { fs.unlinkSync(tacoSettingsFile); } rimraf(testHome, function (err) { done(); }); // ignore errors }); function makeICommandData(args) { return { options: {}, original: args, remain: args }; } var remoteRun = function (args) { return remote.run(args); }; it("should save in the expected format", function (mocha) { var questionsAsked = 0; var sessionClosed = false; var desiredState = { host: "localhost", port: 3000, pin: "" }; var desiredMountPoint = "testMountPoint"; var expectedSequence = [ { expectedUrl: "/modules/taco-remote", head: { "Content-Type": "text/plain" }, statusCode: 200, response: desiredMountPoint } ]; var mockServer = http.createServer(); var serverFunction = ServerMock.generateServerFunction(mocha, expectedSequence); var cliVersion = require("../package.json").version; var expectedTelemetryProperties = { subCommand: { isPii: false, value: "add" }, platform: { isPii: false, value: "ios" }, isSecure: { isPii: false, value: "false" } }; mockServer.listen(desiredState.port); mockServer.on("request", serverFunction); RemoteMod.cliSession = RemoteMock.makeCliMock(mocha, function () { sessionClosed = true; }, desiredState, function () { questionsAsked++; }); Q(["add", "ios"]).then(remoteRun).then(function (telemetryParameters) { // Verify telemetry properties telemetryParameters.should.be.eql(expectedTelemetryProperties); if (questionsAsked !== 3) { throw new Error("Wrong number of questions asked: " + questionsAsked); } else if (!sessionClosed) { throw new Error("CLI Session not closed"); } }).then(function () { return Settings.loadSettings(); }).then(function (data) { data.remotePlatforms["ios"].should.eql({ host: desiredState.host, port: desiredState.port, secure: desiredState.pin !== "", mountPoint: desiredMountPoint }); }).finally(function () { mockServer.close(); }).done(function () { mocha(); }, mocha); }); it("should print help for unknown parameters", function (mocha) { RemoteMod.cliSession = { question: function (question, callback) { mocha(new Error("Should not get as far as querying the user with invalid paramters")); }, close: function () { mocha(new Error("Should not get as far as querying the user with invalid paramters")); } }; Q([]).then(remoteRun).then(function () { mocha(); }, function (e) { mocha(new Error("Should have printed help")); }); }); it("should be able to configure secure connections", function (mocha) { var mockServer = ServerMock.createSecureTestServer(); var desiredState = { host: "localhost", port: 3000, pin: "123456", mountPoint: "cordova" }; var expectedSequence = [ { expectedUrl: "/certs/" + desiredState.pin, head: { "Content-Type": "application/octet-stream" }, statusCode: 200, response: fs.readFileSync(path.resolve(__dirname, "resources", "certs", "client.pfx")) }, { expectedUrl: "/modules/taco-remote", head: { "Content-Type": "text/plain" }, statusCode: 200, response: desiredState.mountPoint }, { expectedUrl: "/cordova/testCertUsage", head: { "Content-Type": "text/plain" }, statusCode: 200, response: "success" } ]; var serverFunction = ServerMock.generateServerFunction(mocha, expectedSequence); mockServer.listen(desiredState.port); mockServer.on("request", serverFunction); RemoteMod.cliSession = RemoteMock.makeCliMock(mocha, utils.emptyMethod, desiredState); Q(["add", "ios"]).then(remoteRun).then(function () { return Settings.loadSettings(); }).then(function (data) { data.remotePlatforms["ios"].should.eql({ host: desiredState.host, port: desiredState.port, secure: true, certName: data.remotePlatforms["ios"].certName, mountPoint: desiredState.mountPoint }); return ConnectionSecurityHelper.getAgent(data.remotePlatforms["ios"]).then(function (agent) { // Now that a cert is configured, try making a secure connection to the (mocked) server to make sure the cert works. // TODO: Remove the casting once we've get some complete/up-to-date .d.ts files. See https://github.com/Microsoft/TACO/issues/18 var options = { url: Settings.getRemoteServerUrl(data.remotePlatforms["ios"]) + "/testCertUsage", headers: { "Accept-Language": "en" }, agent: agent }; var deferred = Q.defer(); request.get(options, function (err, response, body) { if (err) { mocha(err); } else { deferred.resolve({}); } }); return deferred.promise; }); }).finally(function () { mockServer.close(); }).done(function () { mocha(); }, mocha); }); describe("Onboarding experience", function () { // because of function overloading assigning "(buffer: string, cb?: Function) => boolean" as the type for // stdoutWrite just doesn't work var stdoutWrite = process.stdout.write; // We save the original implementation, so we can restore it later var memoryStdout; beforeEach(function () { memoryStdout = new MemoryStream; // Each individual test gets a new and empty console process.stdout.write = memoryStdout.writeAsFunction(); // We'll be printing into an "in-memory" console, so we can test the output }); after(function () { // We just need to reset the stdout just once, after all the tests have finished process.stdout.write = stdoutWrite; }); // Here you can write to the console with logger.log(...) and then you'll be able to // retrieve the contents from the memory stream it("prints the onboarding experience when adding a new remote", function (done) { var desiredState = { host: "localhost", port: 3000, pin: "", mountPoint: "testMountPoint" }; var expectedSequence = [ { expectedUrl: "/modules/taco-remote", head: { "Content-Type": "text/plain" }, statusCode: 200, response: desiredState.mountPoint } ]; var mockServer = http.createServer(); var serverFunction = ServerMock.generateServerFunction(done, expectedSequence); mockServer.listen(desiredState.port); mockServer.on("request", serverFunction); RemoteMod.cliSession = RemoteMock.makeCliMock(done, utils.emptyMethod, desiredState, utils.emptyMethod); remoteRun(["add", "ios"]).finally(function () { mockServer.close(); }).done(function () { var messages = ["CommandRemoteHeader", "CommandRemoteSettingsStored", "OnboardingExperienceTitle", " * HowToUseCommandBuildPlatform", " * HowToUseCommandEmulatePlatform", " * HowToUseCommandRunPlatform", "", "HowToUseCommandHelp", "HowToUseCommandDocs", ""]; // Get the expected console output var expected = messages.join("\n"); var actual = memoryStdout.contentsAsText(); actual.should.be.equal(expected); done(); }, done); }); }); }); //# sourceMappingURL=remote.js.map