Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions src/commands/use.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { expect } from "chai";
import * as sinon from "sinon";
import { RC } from "../rc";

import { command } from "./use";
import * as projects from "../management/projects";
import * as studio from "../management/studio";
import * as prompt from "../prompt";
import * as utils from "../utils";
import * as auth from "../requireAuth";
import * as detect from "../detectProjectRoot";
import * as rcModule from "../rc";

describe("use command", () => {
let getProjectStub: sinon.SinonStub;
let makeActiveProjectStub: sinon.SinonStub;
let detectProjectRootStub: sinon.SinonStub;

beforeEach(() => {
getProjectStub = sinon.stub(projects, "getProject").resolves({
projectId: "my-project",
projectNumber: "123",
displayName: "My Project",
resources: {},
} as unknown as projects.ProjectInfo);
sinon
.stub(projects, "listFirebaseProjects")
.resolves([{ projectId: "my-project" }] as unknown as projects.ProjectInfo[]);
sinon.stub(studio, "updateStudioFirebaseProject").resolves();
makeActiveProjectStub = sinon.stub(utils, "makeActiveProject").returns();
sinon.stub(prompt, "select").resolves("my-project");
sinon.stub(prompt, "input").resolves("staging");
sinon.stub(auth, "requireAuth").resolves();
detectProjectRootStub = sinon.stub(detect, "detectProjectRoot").returns("/path/to/project");
sinon
.stub(rcModule, "loadRC")
.callsFake((options: unknown) => (options as Record<string, unknown>).rc || new RC());

Check failure on line 37 in src/commands/use.spec.ts

View workflow job for this annotation

GitHub Actions / unit (24)

Argument of type '(options: unknown) => {}' is not assignable to parameter of type '(options: { [other: string]: any; cwd?: string | undefined; }) => RC'.

Check failure on line 37 in src/commands/use.spec.ts

View workflow job for this annotation

GitHub Actions / unit (24)

Argument of type '(options: unknown) => {}' is not assignable to parameter of type '(options: { [other: string]: any; cwd?: string | undefined; }) => RC'.
});

afterEach(() => {
sinon.restore();
});

it("should throw if not in a project root", async () => {
detectProjectRootStub.returns(undefined);
const options = { rc: new RC() };
await expect(command.runner()("my-project", options)).to.be.rejectedWith(
/must be run from a Firebase project directory/,
);
});

it("should set active project for existing alias", async () => {
const rc = new RC(undefined, { projects: { staging: "my-project" } });
const options = { rc, projectRoot: "/path/to/project" };

await command.runner()("staging", options);

expect(makeActiveProjectStub).to.have.been.calledWith("/path/to/project", "staging");
});

it("should set active project for project ID directly", async () => {
const rc = new RC();
const options = { rc, projectRoot: "/path/to/project" };

await command.runner()("my-project", options);

expect(makeActiveProjectStub).to.have.been.calledWith("/path/to/project", "my-project");
});

it("should throw if alias not found and not valid project ID", async () => {
const rc = new RC();
const options = { rc, projectRoot: "/path/to/project" };
getProjectStub.rejects(new Error("Not found"));

await expect(command.runner()("nonexistent", options)).to.be.rejectedWith(
/Invalid project selection/,
);
});

it("should unalias a project", async () => {
const rc = new RC(undefined, { projects: { staging: "my-project" } });
const options = { rc, projectRoot: "/path/to/project", unalias: "staging" };

await command.runner()(undefined, options);

expect(rc.hasProjectAlias("staging")).to.be.false;
});

it("should add a new alias interactively", async () => {
const rc = new RC();
const options = { rc, projectRoot: "/path/to/project", add: true, interactive: true };

await command.runner()(undefined, options);

expect(rc.resolveAlias("staging")).to.equal("my-project");
expect(makeActiveProjectStub).to.have.been.calledWith("/path/to/project", "staging");
});

it("should clear the active project", async () => {
const rc = new RC();
const options = { rc, projectRoot: "/path/to/project", clear: true, projectAlias: "staging" };

await command.runner()(undefined, options);

expect(makeActiveProjectStub).to.have.been.calledWith("/path/to/project", undefined);
});

it("should display generic use info if no arguments passed", async () => {
const rc = new RC(undefined, { projects: { staging: "my-project" } });
const options = {
rc,
projectRoot: "/path/to/project",
projectAlias: "staging",
project: "my-project",
};

const result = await command.runner()(undefined, options);

Check warning on line 117 in src/commands/use.spec.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe assignment of an `any` value

expect(result).to.equal("my-project");
});
});
2 changes: 1 addition & 1 deletion src/commands/use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import { RC } from "../rc";
import { isFirebaseStudio } from "../env";

function listAliases(options: Options) {

Check warning on line 16 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
if (options.rc.hasProjects) {
logger.info("Project aliases for", clc.bold(options.projectRoot || "") + ":");
logger.info();
Expand All @@ -35,7 +35,7 @@
}

// firebase use [alias_or_project]
export async function setNewActive(

Check warning on line 38 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing JSDoc comment

Check warning on line 38 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
projectOrAlias: string,
aliasOpt: string | undefined,
rc: RC,
Expand Down Expand Up @@ -89,7 +89,7 @@
}

// firebase use --unalias [alias]
function unalias(alias: string, options: UseOptions) {

Check warning on line 92 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
if (options.rc.hasProjectAlias(alias)) {
options.rc.removeProjectAlias(alias);
logger.info("Removed alias", clc.bold(alias));
Expand All @@ -99,7 +99,7 @@
}

// firebase use --add
async function addAlias(options: UseOptions) {

Check warning on line 102 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
if (options.nonInteractive) {
return utils.reject(
"Cannot run " +
Expand All @@ -125,15 +125,15 @@
alias,
};
options.rc.addProjectAlias(alias, project);
utils.makeActiveProject(options.projectRoot!, results.alias);

Check warning on line 128 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion
logger.info();
logger.info("Created alias", clc.bold(results.alias || ""), "for", results.project + ".");
logger.info("Now using alias", clc.bold(results.alias || "") + " (" + results.project + ")");
}

// firebase use --clear
function clearAlias(options: UseOptions) {

Check warning on line 135 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
utils.makeActiveProject(options.projectRoot!, undefined);

Check warning on line 136 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion
delete options.projectAlias;
delete options.project;
logger.info("Cleared active project.");
Expand All @@ -142,7 +142,7 @@
}

// firebase use
async function genericUse(options: UseOptions) {

Check warning on line 145 in src/commands/use.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
if (options.nonInteractive || !process.stdout.isTTY) {
if (options.project) {
logger.info(options.project);
Expand Down Expand Up @@ -177,7 +177,7 @@
.option("--alias <name>", "create a new alias for the provided project id")
.option("--unalias <name>", "remove an already created project alias")
.option("--clear", "clear the active project selection")
.before(requireAuth)
.before((options: Options) => requireAuth(options))
.action((newActive, options: UseOptions) => {
// HACK: Commander.js silently swallows an option called alias >_<
let aliasOpt: string | undefined;
Expand Down
Loading