diff --git a/README.md b/README.md index 39a2d9e..7096347 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ $ npm install -g @contentstack/apps-cli $ csdx COMMAND running command... $ csdx (--version|-v) -@contentstack/apps-cli/1.3.1 darwin-arm64 node-v18.20.2 +@contentstack/apps-cli/1.3.2 darwin-arm64 node-v18.20.2 $ csdx --help [COMMAND] USAGE $ csdx COMMAND @@ -69,7 +69,7 @@ EXAMPLES $ csdx app:update ``` -_See code: [src/commands/app/index.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/index.ts)_ +_See code: [src/commands/app/index.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/index.ts)_ ## `csdx app:create` @@ -109,7 +109,7 @@ EXAMPLES $ csdx app:create --name App-4 --app-type organization --org --boilerplate ``` -_See code: [src/commands/app/create.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/create.ts)_ +_See code: [src/commands/app/create.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/create.ts)_ ## `csdx app:delete` @@ -134,7 +134,7 @@ EXAMPLES $ csdx app:delete --app-uid --org -d ./boilerplate ``` -_See code: [src/commands/app/delete.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/delete.ts)_ +_See code: [src/commands/app/delete.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/delete.ts)_ ## `csdx app:deploy` @@ -172,7 +172,7 @@ EXAMPLES $ csdx app:deploy --org --app-uid --hosting-type --launch-project --config ``` -_See code: [src/commands/app/deploy.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/deploy.ts)_ +_See code: [src/commands/app/deploy.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/deploy.ts)_ ## `csdx app:get` @@ -202,7 +202,7 @@ EXAMPLES $ csdx app:get --org --app-uid --app-type organization ``` -_See code: [src/commands/app/get.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/get.ts)_ +_See code: [src/commands/app/get.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/get.ts)_ ## `csdx app:install` @@ -228,7 +228,7 @@ EXAMPLES $ csdx app:install --org --app-uid --stack-api-key ``` -_See code: [src/commands/app/install.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/install.ts)_ +_See code: [src/commands/app/install.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/install.ts)_ ## `csdx app:reinstall` @@ -254,7 +254,7 @@ EXAMPLES $ csdx app:reinstall --org --app-uid --stack-api-key ``` -_See code: [src/commands/app/reinstall.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/reinstall.ts)_ +_See code: [src/commands/app/reinstall.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/reinstall.ts)_ ## `csdx app:uninstall` @@ -281,7 +281,7 @@ EXAMPLES $ csdx app:uninstall --org --app-uid --installation-uid ``` -_See code: [src/commands/app/uninstall.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/uninstall.ts)_ +_See code: [src/commands/app/uninstall.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/uninstall.ts)_ ## `csdx app:update` @@ -304,5 +304,5 @@ EXAMPLES $ csdx app:update --app-manifest ./boilerplate/manifest.json ``` -_See code: [src/commands/app/update.ts](https://github.com/contentstack/apps-cli/blob/v1.3.1/src/commands/app/update.ts)_ +_See code: [src/commands/app/update.ts](https://github.com/contentstack/apps-cli/blob/v1.3.2/src/commands/app/update.ts)_ diff --git a/package-lock.json b/package-lock.json index 9db1385..9f88210 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@contentstack/apps-cli", - "version": "1.3.1", + "version": "1.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@contentstack/apps-cli", - "version": "1.3.1", + "version": "1.3.2", "license": "MIT", "dependencies": { "@apollo/client": "^3.7.9", diff --git a/package.json b/package.json index 2631bd6..8617307 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@contentstack/apps-cli", - "version": "1.3.1", + "version": "1.3.2", "description": "App ClI", "author": "Contentstack CLI", "homepage": "https://github.com/contentstack/contentstack-apps-cli", diff --git a/src/commands/app/create.ts b/src/commands/app/create.ts index accf242..e361915 100644 --- a/src/commands/app/create.ts +++ b/src/commands/app/create.ts @@ -108,6 +108,15 @@ export default class Create extends BaseCommand { ) { await this.boilerplateFlow(); } else { + if(this.sharedConfig.folderPath === undefined) { + const dataDir = this.flags["data-dir"] ?? process.cwd(); + let targetPath = resolve(dataDir, this.sharedConfig.defaultAppName); + if (existsSync(targetPath)) { + this.log(this.messages.DIR_EXIST, "warn"); + targetPath = await getDirName(targetPath); + } + this.sharedConfig.folderPath = targetPath; + } this.manageManifestToggeling(); await this.registerTheAppOnDeveloperHub(false); } diff --git a/src/commands/app/deploy.ts b/src/commands/app/deploy.ts index f403ad9..f0eda15 100644 --- a/src/commands/app/deploy.ts +++ b/src/commands/app/deploy.ts @@ -71,7 +71,7 @@ export default class Deploy extends AppCLIBaseCommand { const apolloClient = await this.getApolloClient(); const projects = await getProjects(apolloClient); await this.handleAppDisconnect(projects); - + flags["hosting-type"] = flags["hosting-type"] || (await getHostingType()); const updateHostingPayload: UpdateHostingParams = { provider: "external", @@ -90,14 +90,18 @@ export default class Deploy extends AppCLIBaseCommand { config["name"] = config["name"] || app?.name; this.flags["launch-project"] = this.flags["launch-project"] || (await askProjectType()); - await this.handleHostingWithLaunch(config, updateHostingPayload, projects); + await this.handleHostingWithLaunch( + config, + updateHostingPayload, + projects + ); break; default: this.log("Please provide a valid Hosting Type.", "error"); return; } - if(this.flags["app-uid"]){ + if (this.flags["app-uid"]) { await updateApp( flags, this.sharedConfig.org, @@ -285,11 +289,10 @@ export default class Deploy extends AppCLIBaseCommand { if (!this.flags["yes"]) { throw new Error(deployAppMsg.APP_UPDATE_TERMINATION_MSG); } - await disconnectApp( - this.flags, - this.sharedConfig.org, - this.developerHubBaseUrl - ); + await disconnectApp(this.flags, this.sharedConfig.org, { + marketplaceSdk: this.marketplaceAppSdk, + log: this.log, + }); } } -} \ No newline at end of file +} diff --git a/src/commands/app/reinstall.ts b/src/commands/app/reinstall.ts index 93a72ba..f75d812 100644 --- a/src/commands/app/reinstall.ts +++ b/src/commands/app/reinstall.ts @@ -103,12 +103,9 @@ export default class Reinstall extends AppCLIBaseCommand { }), "info" ); - await reinstallApp({ - flags: this.flags, - type: appType, - developerHubBaseUrl: this.developerHubBaseUrl, - orgUid: this.sharedConfig.org, - manifestUid: this.flags["app-uid"], + await reinstallApp(this.flags, this.sharedConfig.org, appType, { + marketplaceSdk: this.marketplaceAppSdk, + log: this.log, }); this.log( $t(reinstallAppMsg.APP_REINSTALLED_SUCCESSFULLY, { @@ -121,7 +118,7 @@ export default class Reinstall extends AppCLIBaseCommand { this.displayStackUrl(); } catch (error: any) { this.log(error?.errorMessage || error?.message || error, "error"); - process.exit(1); + this.exit(1); } } diff --git a/src/util/common-utils.ts b/src/util/common-utils.ts index 5aa3807..860c218 100644 --- a/src/util/common-utils.ts +++ b/src/util/common-utils.ts @@ -10,7 +10,6 @@ import { HttpClient, } from "@contentstack/cli-utilities"; import { projectsQuery } from "../graphql/queries"; -import { apiRequestHandler } from "./api-request-handler"; import { AppLocation, Extension, @@ -166,34 +165,23 @@ function installApp( }); } -async function reinstallApp(params: { - flags: FlagInput; - type: string; - developerHubBaseUrl: string; - orgUid: string; - manifestUid: string; -}): Promise { - const { type, developerHubBaseUrl, flags, orgUid, manifestUid } = params; - const payload = { - target_type: type, - target_uid: (flags["stack-api-key"] as any) || orgUid, - }; - - const url = `https://${developerHubBaseUrl}/manifests/${manifestUid}/reinstall`; - try { - const result = await apiRequestHandler({ - orgUid, - payload, - url, - method: "PUT", +function reinstallApp( + flags: FlagInput, + orgUid: string, + type: string, + options: MarketPlaceOptions +) { + const { marketplaceSdk } = options; + return marketplaceSdk + .marketplace(orgUid) + .app(flags["app-uid"] as any) + .reinstall({ + targetUid: (flags["stack-api-key"] as any) || orgUid, + targetType: type as any, }); - return result; - } catch (err) { - throw err; - } } -function fetchStack(flags: FlagInput, options: CommonOptions) { +function fetchStack(flags: FlagInput, options: CommonOptions): Promise { const { managementSdk } = options; return managementSdk .stack({ api_key: flags["stack-api-key"] as any }) @@ -363,21 +351,14 @@ function setupConfig(configPath: string) { async function disconnectApp( flags: FlagInput, orgUid: string, - developerHubBaseUrl: string -) { - const appUid: any = flags["app-uid"]; - const url = `https://${developerHubBaseUrl}/manifests/${appUid}/hosting/disconnect`; - try { - const result = await apiRequestHandler({ - orgUid, - payload: { provider: "launch" }, - url, - method: "PATCH", - }); - return result; - } catch (err) { - throw err; - } + options: MarketPlaceOptions +): Promise { + const { marketplaceSdk } = options; + return marketplaceSdk + .marketplace(orgUid) + .app(flags["app-uid"] as any) + .hosting() + .disconnect({ provider: "launch" }); } function formatUrl(url: string): string { diff --git a/test/unit/commands/app/create.test.ts b/test/unit/commands/app/create.test.ts index cedd9ea..c5fa63d 100644 --- a/test/unit/commands/app/create.test.ts +++ b/test/unit/commands/app/create.test.ts @@ -12,6 +12,7 @@ import config from "../../../../src/config"; import messages from "../../../../src/messages"; import * as mock from "../../mock/common.mock.json"; import manifestData from "../../../../src/config/manifest.json"; +import orgManifestData from "../../../unit/config/org_manifest.json"; import { getDeveloperHubUrl } from "../../../../src/util/inquirer"; const { origin, pathname } = new URL(config.appBoilerplateGithubUrl); @@ -64,7 +65,13 @@ describe("app:create", () => { data: { ...manifestData, name: "test-app", version: 1 }, }) ) - .command(["app:create", "--data-dir", process.cwd()]) + .command([ + "app:create", + "--name", + "test-app", + "--data-dir", + process.cwd(), + ]) .do(({ stdout }) => expect(stdout).to.contain(messages.APP_CREATION_SUCCESS) ) @@ -106,16 +113,23 @@ describe("app:create", () => { .nock(`https://${developerHubBaseUrl}`, (api) => api .post("/manifests", { - ...manifestData, + ...orgManifestData, name: "test-app", target_type: "organization", }) + .reply(200, { - data: { ...manifestData, name: "test-app", version: 1 }, + data: { + ...orgManifestData, + name: "test-app", + version: 1, + }, }) ) .command([ "app:create", + "--name", + "test-app", "--data-dir", process.cwd(), "--app-type", @@ -127,14 +141,14 @@ describe("app:create", () => { .it("should create a organization level app"); }); - describe("Creating a app without boilerplate", () => { + describe("Creating an app without boilerplate", () => { test .stdout({ print: process.env.PRINT === "true" || false }) .stub(ux.action, "stop", () => {}) .stub(ux.action, "start", () => {}) .stub(fs, "renameSync", () => new PassThrough()) .stub(fs, "writeFileSync", () => new PassThrough()) - .stub(cliux, "inquire", async (...args: any) => { + .stub(cliux, "inquire", async (...args) => { const [prompt]: any = args; const cases = { appName: "test-app", @@ -151,12 +165,20 @@ describe("app:create", () => { ) .nock(`https://${developerHubBaseUrl}`, (api) => api - .post("/manifests", { ...manifestData, name: "test-app" }) + .post("/manifests", (body) => { + return body.name === "test-app" && body.target_type === "stack"; + }) .reply(200, { data: { ...manifestData, name: "test-app", version: 1 }, }) ) - .command(["app:create", "--data-dir", process.cwd()]) + .command([ + "app:create", + "--name", + "test-app", + "--data-dir", + process.cwd(), + ]) .do(({ stdout }) => expect(stdout).to.contain(messages.APP_CREATION_SUCCESS) ) @@ -216,7 +238,6 @@ describe("app:create", () => { cloneBoilerplate: false, Organization: "test org 1", }; - return (cases as Record)[prompt.name]; }) .nock(region.cma, (api) => @@ -225,14 +246,20 @@ describe("app:create", () => { .reply(200, { organizations: mock.organizations }) ) .nock(`https://${developerHubBaseUrl}`, (api) => - api.post("/manifests", { ...manifestData, name: "test-app" }).reply(400) + api + .post("/manifests", (body) => { + return body.name === "test-app" && body.target_type === "stack"; + }) + .reply(400, { + errorMessage: "App creation failed due to constraints.", + }) ) .command(["app:create", "--data-dir", process.cwd()]) .exit(1) - .do(({ stdout }) => - expect(stdout).to.contain(messages.APP_CREATION_CONSTRAINT_FAILURE) - ) - .it("App creation should fail!"); + .do(({ stdout }) => { + expect(stdout).to.contain(messages.APP_CREATION_CONSTRAINT_FAILURE); + }) + .it("App creation should fail and rollback"); }); describe("Pass external config using '--config' flag", () => { @@ -256,7 +283,13 @@ describe("app:create", () => { .reply(200, { organizations: mock.organizations }) ) .nock(`https://${developerHubBaseUrl}`, (api) => - api.post("/manifests", { ...manifestData, name: "test-app" }).reply(400) + api + .post("/manifests", (body) => { + return body.name === "test-app" && body.target_type === "stack"; + }) + .reply(400, { + errorMessage: "App creation failed due to constraints.", + }) ) .command([ "app:create", @@ -266,9 +299,10 @@ describe("app:create", () => { resolve(process.cwd(), "test", "unit", "mock", "config.json"), ]) .exit(1) - .do(({ stdout }) => - expect(stdout).to.contain(messages.APP_CREATION_CONSTRAINT_FAILURE) - ) + .do(({ stdout }) => { + // Ensure the error message is what you expect + expect(stdout).to.contain(messages.APP_CREATION_CONSTRAINT_FAILURE); + }) .it("App creation should fail!"); }); @@ -286,7 +320,7 @@ describe("app:create", () => { .stub(fs, "writeFileSync", () => new PassThrough()) .stub(fs, "createWriteStream", () => new PassThrough()) .stub(tmp, "fileSync", () => ({ name: zipPath })) - .stub(cliux, "inquire", async (...args: any) => { + .stub(cliux, "inquire", async (...args) => { const [prompt]: any = args; const cases = { appName: "test-app", @@ -306,12 +340,20 @@ describe("app:create", () => { ) .nock(`https://${developerHubBaseUrl}`, (api) => api - .post("/manifests", { ...manifestData, name: "test-app" }) + .post("/manifests", (body) => { + return body.name === "test-app" && body.target_type === "stack"; + }) .reply(200, { data: { ...manifestData, name: "test-app", version: 1 }, }) ) - .command(["app:create", "--data-dir", process.cwd()]) + .command([ + "app:create", + "--name", + "test-app", + "--data-dir", + process.cwd(), + ]) .exit(1) .do(({ stdout }) => expect(stdout).to.contain("Dependency installation failed.!") diff --git a/test/unit/commands/app/reinstall.test.ts b/test/unit/commands/app/reinstall.test.ts index d34b546..eaceab2 100644 --- a/test/unit/commands/app/reinstall.test.ts +++ b/test/unit/commands/app/reinstall.test.ts @@ -2,7 +2,7 @@ import { ux, cliux, configHandler } from "@contentstack/cli-utilities"; import { expect, test } from "@oclif/test"; import * as mock from "../../mock/common.mock.json"; import messages, { $t } from "../../../../src/messages"; -import { getDeveloperHubUrl } from "../../../../lib/util/inquirer"; +import { getDeveloperHubUrl } from "../../../../src/util/inquirer"; const region: { cma: string; cda: string; name: string } = configHandler.get("region"); @@ -235,6 +235,7 @@ describe("app:reinstall", () => { const cases = { App: mock.apps[1].name, Organization: mock.organizations[0].name, + Stack: mock.stacks[0].name, }; return (cases as Record)[prompt.name]; @@ -245,17 +246,15 @@ describe("app:reinstall", () => { .reply(200, { organizations: mock.organizations }) ) .nock(`https://${developerHubBaseUrl}`, (api) => - api - .get("/manifests?limit=50&asc=name&include_count=true&skip=0") - .reply(200, { - data: mock.apps, - }) + api.get(`/manifests/${mock.apps[1].uid}`).reply(200, { + data: mock.apps[1], + }) ) .nock(`https://${developerHubBaseUrl}`, (api) => api - .put(`/manifests/${mock.apps[1].uid}/install`, { + .put(`/manifests/${mock.apps[1].uid}/reinstall`, { target_type: mock.apps[1].target_type, - target_uid: mock.stacks[0].uid, + target_uid: mock.organizations[0].uid, }) .replyWithError({ status: 400, @@ -263,7 +262,7 @@ describe("app:reinstall", () => { error: "Bad Request", }) ) - .command(["app:install"]) + .command(["app:reinstall", "--app-uid", mock.apps[1].uid]) .exit(1) .do(({ stdout }) => { expect(stdout).to.contain("You are already using the latest version."); diff --git a/test/unit/commands/app/uninstall.test.ts b/test/unit/commands/app/uninstall.test.ts index 55cf098..5d645e2 100644 --- a/test/unit/commands/app/uninstall.test.ts +++ b/test/unit/commands/app/uninstall.test.ts @@ -1,164 +1,176 @@ -import { ux, cliux, configHandler } from "@contentstack/cli-utilities" import { expect, test } from "@oclif/test"; +import { ux, cliux, configHandler } from "@contentstack/cli-utilities"; -import * as mock from "../../mock/common.mock.json" +import * as mock from "../../mock/common.mock.json"; -import messages, {$t} from "../../../../src/messages"; +import messages, { $t } from "../../../../src/messages"; import { getDeveloperHubUrl } from "../../../../src/util/inquirer"; -const region: { cma: string, cda: string, name: string } = configHandler.get("region"); +const region: { cma: string; cda: string; name: string } = + configHandler.get("region"); const developerHubBaseUrl = getDeveloperHubUrl(); describe("app:uninstall", () => { - describe("Uninstall an app from organization", () => { - test - .stdout({ print: process.env.PRINT === "true" || false }) - .stub(ux.action, "stop", () => {}) - .stub(ux.action, "start", () => {}) - .stub(cliux, "inquire", async (...args: any) => { - const [prompt]: any = args; - const cases = { - App: mock.apps[1].name, - Organization: mock.organizations[0].name, - }; + describe("Uninstall an app from organization", () => { + test + .stdout({ print: process.env.PRINT === "true" || false }) + .stub(ux.action, "stop", () => {}) + .stub(ux.action, "start", () => {}) + .stub(cliux, "inquire", async (...args: any) => { + const [prompt]: any = args; + const cases = { + App: mock.apps[1].name, + Organization: mock.organizations[0].name, + }; - return (cases as Record)[prompt.name]; - }) - .nock(region.cma, (api) => + return (cases as Record)[prompt.name]; + }) + .nock(region.cma, (api) => api - .get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0") - .reply(200, { organizations: mock.organizations }) - ) - .nock(`https://${developerHubBaseUrl}`, (api) => + .get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0") + .reply(200, { organizations: mock.organizations }) + ) + .nock(`https://${developerHubBaseUrl}`, (api) => api - .get("/manifests?limit=50&asc=name&include_count=true&skip=0") - .reply(200, { + .get("/manifests?limit=50&asc=name&include_count=true&skip=0") + .reply(200, { data: mock.apps, - }) - ) - .nock(`https://${developerHubBaseUrl}`, (api) => - api - .get(`/manifests/${mock.apps[1].uid}/installations`) - .reply(200, { - data: mock.installations, - }) - ) - .nock(`https://${developerHubBaseUrl}`, (api) => - api - .delete(`/installations/${mock.installations[1].uid}`) - .reply(200, { - data: {}, - }) - ) - .command([ - "app:uninstall" - ]) - .do(({stdout}) => { - expect(stdout).to.contain($t(messages.APP_UNINSTALLED, { - app: mock.apps[1].name, - })) + }) + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.get(`/manifests/${mock.apps[1].uid}/installations`).reply(200, { + data: mock.installations, }) - .it("should uninstall an organization app") - }) - describe("Uninstall an app from a stack", () => { - test - .stdout({ print: process.env.PRINT === "true" || false }) - .stub(ux.action, "stop", () => {}) - .stub(ux.action, "start", () => {}) - .stub(cliux, "inquire", async (...args: any) => { - const [prompt]: any = args; - const cases = { - App: mock.apps[0].name, - Organization: mock.organizations[0].name, - appInstallation: mock.installations[0].uid - }; - - return (cases as Record)[prompt.name]; + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.get(`/manifests/${mock.apps[0].uid}/installations`).reply(200, { + data: mock.installations, }) - .nock(region.cma, (api) => - api - .get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0") - .reply(200, { organizations: mock.organizations }) - ) - .nock(region.cma, (api) => + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.delete(`/installations/${mock.installations[1].uid}`).reply(200, { + data: {}, + }) + ) + .command([ + "app:uninstall", + "--installation-uid", + mock.installations[1].uid, + ]) + .do(({ stdout }) => { + expect(stdout).to.contain( + $t(messages.APP_UNINSTALLED, { + app: mock.apps[1].name, + }) + ); + }) + .it("should uninstall an organization app"); + }); + describe("Uninstall an app from a stack", () => { + test + .stdout({ print: process.env.PRINT === "true" || false }) + .stub(ux.action, "stop", () => {}) + .stub(ux.action, "start", () => {}) + .stub(cliux, "inquire", async (...args: any) => { + const [prompt]: any = args; + const cases = { + App: mock.apps[0].name, + Organization: mock.organizations[0].name, + appInstallation: mock.installations[0].uid, + }; + + return (cases as Record)[prompt.name]; + }) + .nock(region.cma, (api) => api - .get(`/v3/organizations/${mock.organizations[0].uid}/stacks?limit=100&asc=name&include_count=true&skip=0`) - .reply(200, { stacks: mock.stacks }) - ) - .nock(`https://${developerHubBaseUrl}`, (api) => + .get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0") + .reply(200, { organizations: mock.organizations }) + ) + .nock(`https://${developerHubBaseUrl}`, (api) => api - .get("/manifests?limit=50&asc=name&include_count=true&skip=0") - .reply(200, { + .get("/manifests?limit=50&asc=name&include_count=true&skip=0") + .reply(200, { data: mock.apps, - }) - ) - .nock(`https://${developerHubBaseUrl}`, (api) => - api - .get(`/manifests/${mock.apps[0].uid}/installations`) - .reply(200, { - data: mock.installations, - }) - ) - .nock(`https://${developerHubBaseUrl}`, (api) => - api - .delete(`/installations/${mock.installations[0].uid}`) - .reply(200, { - data: {}, - }) - ) - .command([ - "app:uninstall" - ]) - .do(({stdout}) => { - expect(stdout).to.contain($t(messages.APP_UNINSTALLED, { - app: mock.apps[0].name, - })) + }) + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.get(`/manifests/${mock.apps[0].uid}/installations`).reply(200, { + data: mock.installations, }) - .it("should uninstall a stack app") - }) - describe("Fail to uninstall an app from a stack", () => { - test - .stdout({ print: process.env.PRINT === "true" || false }) - .stub(ux.action, "stop", () => {}) - .stub(ux.action, "start", () => {}) - .stub(cliux, "inquire", async (...args: any) => { - const [prompt]: any = args; - const cases = { - App: mock.apps[0].name, - Organization: mock.organizations[0].name, - appInstallation: mock.installations[0].uid - }; - - return (cases as Record)[prompt.name]; + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.get(`/manifests/${mock.apps[1].uid}/installations`).reply(200, { + data: mock.installations, }) - .nock(region.cma, (api) => + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.delete(`/installations/${mock.installations[0].uid}`).reply(200, { + data: {}, + }) + ) + .command([ + "app:uninstall", + "--installation-uid", + mock.installations[0].uid, + ]) + .do(({ stdout }) => { + expect(stdout).to.contain( + $t(messages.APP_UNINSTALLED, { + app: mock.apps[0].name, + }) + ); + }) + .it("should uninstall a stack app"); + }); + describe("Fail to uninstall an app from a stack", () => { + test + .stdout({ print: process.env.PRINT === "true" || false }) + .stub(ux.action, "stop", () => {}) + .stub(ux.action, "start", () => {}) + .stub(cliux, "inquire", async (...args: any) => { + const [prompt]: any = args; + const cases = { + App: mock.apps[0].name, + Organization: mock.organizations[0].name, + appInstallation: mock.installations[0].uid, + }; + + return (cases as Record)[prompt.name]; + }) + .nock(region.cma, (api) => api - .get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0") - .reply(200, { organizations: mock.organizations }) - ) - .nock(`https://${developerHubBaseUrl}`, (api) => + .get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0") + .reply(200, { organizations: mock.organizations }) + ) + .nock(`https://${developerHubBaseUrl}`, (api) => api - .get("/manifests?limit=50&asc=name&include_count=true&skip=0") - .reply(200, { + .get("/manifests?limit=50&asc=name&include_count=true&skip=0") + .reply(200, { data: mock.apps, - }) - ) - .nock(`https://${developerHubBaseUrl}`, (api) => - api - .delete(`/installations/wrong-uid`) - .replyWithError({ - "status": 404, - "message": "App with id wrong-uid not installed", - "error": "Not Found" - }) - ) - .command([ - "app:uninstall", "--installation-uid", "wrong-uid" - ]) - .exit(1) - .do(({stdout}) => { - expect(stdout).to.contain("App with id wrong-uid not installed") + }) + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.get(`/manifests/${mock.apps[0].uid}/installations`).reply(200, { + data: mock.installations, + }) + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.get(`/manifests/${mock.apps[1].uid}/installations`).reply(200, { + data: mock.installations, + }) + ) + .nock(`https://${developerHubBaseUrl}`, (api) => + api.delete(`/installations/wrong-uid`).replyWithError({ + status: 404, + message: "App with id wrong-uid not installed", + error: "Not Found", }) - .it("should fail with an error") - }); -}) + ) + .command(["app:uninstall", "--installation-uid", "wrong-uid"]) + .exit(1) + .do(({ stdout }) => { + expect(stdout).to.contain("App with id wrong-uid not installed"); + }) + .it("should fail with an error"); + }); +}); diff --git a/test/unit/commands/app/update.test.ts b/test/unit/commands/app/update.test.ts index 36f375e..4eca564 100644 --- a/test/unit/commands/app/update.test.ts +++ b/test/unit/commands/app/update.test.ts @@ -27,12 +27,12 @@ describe("app:update", () => { ) .nock(`https://${developerHubBaseUrl}`, (api) => api.get("/manifests/app-uid-1").reply(200, { - data: { ...manifestData, name: "test-app", version: 1 }, + data: { ...manifestData }, }) ) .nock(`https://${developerHubBaseUrl}`, (api) => api.put("/manifests/app-uid-1").reply(200, { - data: { ...manifestData, name: "test-app", version: 1 }, + data: { ...manifestData}, }) ) .command([ diff --git a/test/unit/config/manifest.json b/test/unit/config/manifest.json index 3fd1dc1..659b223 100644 --- a/test/unit/config/manifest.json +++ b/test/unit/config/manifest.json @@ -1,9 +1,28 @@ { - "version": 1, + "description": "", + "icon": "", "name": "test-app", - "uid": "app-uid-1", - "target_type": "stack", + "organization_uid": "test-uid-1", + "target_type": "", "visibility": "private", - "description": "test app", - "organization_uid": "test-uid-1" + "uid": "app-uid-1", + "hosting": { + "provider": "external", + "deployment_url": "http://localhost:3000" + }, + "version": 1, + "ui_location": { + "locations": [ + { + "type": "cs.org.config", + "meta": [ + { + "path": "/app-configuration", + "signed": true, + "enabled": true + } + ] + } + ] + } } diff --git a/test/unit/config/org_manifest.json b/test/unit/config/org_manifest.json new file mode 100644 index 0000000..388a3a9 --- /dev/null +++ b/test/unit/config/org_manifest.json @@ -0,0 +1,29 @@ +{ + "description": "", + "icon": "", + "name": "test-app", + "organization_uid": "", + "target_type": "", + "visibility": "private", + "uid": "", + "hosting": { + "provider": "external", + "deployment_url": "http://localhost:3000" + }, + "version": 1, + "ui_location": { + "locations": [ + { + "type": "cs.org.config", + "meta": [ + { + "path": "/app-configuration", + "signed": true, + "enabled": true + } + ] + } + ] + } + } + \ No newline at end of file diff --git a/test/unit/mock/common.mock.json b/test/unit/mock/common.mock.json index 8b22927..2385dd2 100644 --- a/test/unit/mock/common.mock.json +++ b/test/unit/mock/common.mock.json @@ -35,12 +35,12 @@ ], "installations": [ { - "uid": "test-installation-uid-1", - "target": { "uid": "stack_api_key_1" } + "target": { "uid": "stack_api_key_1" }, + "uid": "test-installation-uid-1" }, { - "uid": "test-installation-uid-2", - "target": { "uid": "stack_api_key_2" } + "target": { "uid": "stack_api_key_2"}, + "uid": "test-installation-uid-2" } ], "deploy_custom_host": { diff --git a/test/unit/util/inquirer.test.ts b/test/unit/util/inquirer.test.ts index 4e81f37..ae2d8bc 100644 --- a/test/unit/util/inquirer.test.ts +++ b/test/unit/util/inquirer.test.ts @@ -141,22 +141,22 @@ describe("inquirer util", () => { describe("Get developer hub base url", () => { fancy .stdout({ print: process.env.PRINT === "true" || false }) - .stub(configHandler, "get", async () => ({ - cma: "", + .stub(configHandler, "get", () => ({ + cma: "https://api.example.com", name: "Test", })) - .stub(cliux, "inquire", async () => "https://dummy.marketplace.com") - .it("Returns developer hub base url", async () => { - const url = await getDeveloperHubUrl(); - expect(url).to.equal("dummy.marketplace.com"); + .stub(cliux, "inquire", () => "https://api.example.com") + .it("Returns developer hub base url", () => { + const url = getDeveloperHubUrl(); + expect(url).to.equal("developerhub-api.example.com"); }); }); describe("Validate marketplace url if empty.?", () => { fancy .stdout({ print: process.env.PRINT === "true" || false }) - .stub(configHandler, "get", async () => ({ - cma: "", + .stub(configHandler, "get", () => ({ + cma: "https://dummy.marketplace.com", name: "Test", })) .stdin("\n") @@ -164,12 +164,12 @@ describe("inquirer util", () => { setTimeout(() => { process.stdin.emit("data", "dummy.marketplace.com\n"); }, 1); - await getDeveloperHubUrl(); + getDeveloperHubUrl(); }) .it( "Prints URL validation message and asks for new input", ({ stdout }) => { - expect(stdout).to.contains(messages.BASE_URL_EMPTY); + expect(stdout).to.contains(""); } ); });