"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const sinon = require("sinon");
const path = require("path");
const tmp = require("tmp");
const BasicServer_1 = require("./BasicServer");
const Logger_1 = require("./shared/Logger");
describe("BasicServer", () => {
    let server;
    let tmpDir;
    let dataPath;
    let logger;
    beforeEach(() => {
        logger = new Logger_1.MuteLogger();
        tmpDir = tmp.dirSync();
        dataPath = tmpDir.name;
        server = new BasicServer_1.BasicServer();
    });
    afterEach(() => __awaiter(this, void 0, void 0, function* () {
        yield server.shutdown().catch(() => { });
    }));
    describe("run (CLI)", () => {
        let exitStub;
        let stdoutStub;
        let capturedStdout;
        let stderrStub;
        let capturedStderr;
        let startStub;
        beforeEach(() => {
            exitStub = sinon.stub(process, "exit").callsFake(function (code) {
                if (code !== 0) {
                    throw new Error("exit with error");
                }
            });
            capturedStdout = "";
            stdoutStub = sinon.stub(process.stdout, "write").callsFake(function (data) {
                capturedStdout += data;
            });
            capturedStderr = "";
            stderrStub = sinon.stub(process.stderr, "write").callsFake(function (data) {
                capturedStderr += data;
            });
            startStub = sinon.stub(server, "start").resolves();
        });
        afterEach(() => {
            exitStub.restore();
            stdoutStub.restore();
            stderrStub.restore();
        });
        describe("--help", () => {
            it("should display help", () => __awaiter(this, void 0, void 0, function* () {
                yield chai_1.assert.isRejected(server.run(["node", "cli.js", "--help"]), "exit with error");
                sinon.assert.calledWith(exitStub, 1);
                chai_1.assert.match(capturedStdout, /ros start \-\-help/);
            }));
        });
        describe("without arguments", () => {
            it("should display help", () => __awaiter(this, void 0, void 0, function* () {
                yield chai_1.assert.isRejected(server.run(["node", "cli.js"]), "exit with error");
                sinon.assert.calledWith(exitStub, 1);
                chai_1.assert.match(capturedStdout, /ros start \-\-help/);
            }));
        });
        describe("with 'start'", () => {
            afterEach(() => __awaiter(this, void 0, void 0, function* () {
                yield server.shutdown().catch((err) => { });
            }));
            describe("with valid args", () => {
                it("should start ROS", () => __awaiter(this, void 0, void 0, function* () {
                    const dataDir = tmp.dirSync();
                    yield chai_1.assert.isFulfilled(server.run(["node", "cli.js", "start", "--data", dataDir.name]));
                    sinon.assert.calledWithMatch(startStub, {
                        dataPath: dataDir.name,
                    });
                }));
            });
            describe("with invalid loglevel", () => {
                it("should exit with error", () => __awaiter(this, void 0, void 0, function* () {
                    yield chai_1.assert.isRejected(server.run(["node", "cli.js", "start", "--loglevel", "disaster"]), "exit with error");
                    chai_1.assert.match(capturedStderr, /log-level must be one of\: /);
                    sinon.assert.calledWith(exitStub, 1);
                }));
            });
            describe("with invalid access token ttl", () => {
                it("should exit with error", () => __awaiter(this, void 0, void 0, function* () {
                    yield chai_1.assert.isRejected(server.run(["node", "cli.js", "start", "--access-token-ttl", "whenever"]), "exit with error");
                    chai_1.assert.match(capturedStderr, /access-token-ttl must be a positive number/);
                    sinon.assert.calledWith(exitStub, 1);
                }));
            });
            describe("with invalid refresh token ttl", () => {
                it("should exit with error", () => __awaiter(this, void 0, void 0, function* () {
                    yield chai_1.assert.isRejected(server.run(["node", "cli.js", "start", "--refresh-token-ttl", "whenever"]), "exit with error");
                    chai_1.assert.match(capturedStderr, /refresh-token-ttl must be a positive number/);
                    sinon.assert.calledWith(exitStub, 1);
                }));
            });
            describe("with invalid port", () => {
                it("should exit with error", () => __awaiter(this, void 0, void 0, function* () {
                    yield chai_1.assert.isRejected(server.run(["node", "cli.js", "start", "--port", "notaport"]), "exit with error");
                    chai_1.assert.match(capturedStderr, /Invalid port number/);
                    sinon.assert.calledWith(exitStub, 1);
                }));
            });
            describe("with https", () => {
                describe("with invalid port", () => {
                    it("should exit with error", () => __awaiter(this, void 0, void 0, function* () {
                        yield chai_1.assert.isRejected(server.run(["node", "cli.js", "start", "--https", "--https-port", "notaport"]), "exit with error");
                        chai_1.assert.match(capturedStderr, /Invalid HTTPS port number/);
                        sinon.assert.calledWith(exitStub, 1);
                    }));
                });
                describe("with valid arguments", () => {
                    it("should call start with expected params", () => __awaiter(this, void 0, void 0, function* () {
                        const dataDir = tmp.dirSync();
                        yield chai_1.assert.isFulfilled(server.run(["node", "cli.js", "start",
                            "--data", dataDir.name,
                            "--https",
                            "--https-key", path.join(__dirname, "..", "fixtures", "https.key"),
                            "--https-cert", path.join(__dirname, "..", "fixtures", "https.crt"),
                        ]));
                        sinon.assert.calledWithMatch(startStub, {
                            dataPath: dataDir.name,
                            https: true,
                            httpsKeyPath: path.resolve(__dirname, "..", "fixtures", "https.key"),
                            httpsCertChainPath: path.resolve(__dirname, "..", "fixtures", "https.crt"),
                            httpsAddress: "0.0.0.0",
                            httpsPort: 9443,
                        });
                    }));
                });
            });
        });
    });
});
//# sourceMappingURL=BasicServer.spec.js.map