Skip to content

Commit 4ddb384

Browse files
Merge pull request #80 from contentstack/feat/CS-39674
Feat/cs 39674
2 parents 7ded967 + 9eb1650 commit 4ddb384

File tree

3 files changed

+234
-3
lines changed

3 files changed

+234
-3
lines changed

src/util/inquirer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ async function getStack(orgUid: string, options: CommonOptions): Promise<Record<
166166
const selectedStack = await cliux
167167
.inquire({
168168
type: "search-list",
169-
name: "App",
169+
name: "Stack",
170170
choices: stacks,
171171
message: messages.CHOOSE_A_STACK
172172
})
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
import { ux, cliux, configHandler } from "@contentstack/cli-utilities";
2+
import {expect, test} from "@oclif/test";
3+
4+
import * as mock from "../../mock/common.mock.json"
5+
6+
import config from "../../../../src/config";
7+
import messages, { $t } from "../../../../src/messages";
8+
9+
const region: { cma: string, cda: string, name: string } = configHandler.get("region");
10+
const developerHubBaseUrl = (config.developerHubUrls as Record<string, any>)[region.cma];
11+
12+
describe("app:install", () => {
13+
describe("Install an app on organization", () => {
14+
test
15+
.stdout({ print: process.env.PRINT === "true" || false })
16+
.stub(ux.action, "stop", () => {})
17+
.stub(ux.action, "start", () => {})
18+
.stub(cliux, "inquire", async (...args: any) => {
19+
const [prompt]: any = args;
20+
const cases = {
21+
App: mock.apps[1].name,
22+
Organization: mock.organizations[0].name,
23+
};
24+
25+
return (cases as Record<string, any>)[prompt.name];
26+
})
27+
.nock(region.cma, (api) =>
28+
api
29+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
30+
.reply(200, { organizations: mock.organizations })
31+
)
32+
.nock(`https://${developerHubBaseUrl}`, (api) =>
33+
api
34+
.get("/manifests?limit=50&asc=name&include_count=true&skip=0")
35+
.reply(200, {
36+
data: mock.apps,
37+
})
38+
)
39+
.nock(`https://${developerHubBaseUrl}`, (api) =>
40+
api
41+
.post(`/manifests/${mock.apps[1].uid}/install`, {
42+
"target_type": mock.apps[1].target_type,
43+
"target_uid": mock.organizations[0].uid
44+
})
45+
.reply(200, {
46+
data: mock.apps,
47+
})
48+
)
49+
.command([
50+
"app:install"
51+
])
52+
.do(({stdout}) => {
53+
expect(stdout).to.contain($t(messages.INSTALLING_APP_NOTICE, {
54+
app: mock.apps[1].name,
55+
type: mock.apps[1].target_type,
56+
target: mock.organizations[0].uid
57+
}))
58+
})
59+
.it("should install an organization app")
60+
})
61+
describe("Install an app on a stack", () => {
62+
test
63+
.stdout({ print: process.env.PRINT === "true" || false })
64+
.stub(ux.action, "stop", () => {})
65+
.stub(ux.action, "start", () => {})
66+
.stub(cliux, "inquire", async (...args: any) => {
67+
const [prompt]: any = args;
68+
const cases = {
69+
App: mock.apps[0].name,
70+
Organization: mock.organizations[0].name,
71+
Stack: mock.stacks[0].name
72+
};
73+
74+
return (cases as Record<string, any>)[prompt.name];
75+
})
76+
.nock(region.cma, (api) =>
77+
api
78+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
79+
.reply(200, { organizations: mock.organizations })
80+
)
81+
.nock(region.cma, (api) =>
82+
api
83+
.get(`/v3/organizations/${mock.organizations[0].uid}/stacks?limit=100&asc=name&include_count=true&skip=0`)
84+
.reply(200, { stacks: mock.stacks })
85+
)
86+
.nock(`https://${developerHubBaseUrl}`, (api) =>
87+
api
88+
.get("/manifests?limit=50&asc=name&include_count=true&skip=0")
89+
.reply(200, {
90+
data: mock.apps,
91+
})
92+
)
93+
.nock(`https://${developerHubBaseUrl}`, (api) =>
94+
api
95+
.post(`/manifests/${mock.apps[0].uid}/install`, {
96+
"target_type": mock.apps[0].target_type,
97+
"target_uid": mock.stacks[0].api_key
98+
})
99+
.reply(200, {
100+
data: mock.apps,
101+
})
102+
)
103+
.command([
104+
"app:install"
105+
])
106+
.do(({stdout}) => {
107+
expect(stdout).to.contain($t(messages.APP_INSTALLED_SUCCESSFULLY, {
108+
app: mock.apps[0].name,
109+
target: mock.stacks[0].name
110+
}))
111+
})
112+
.it("should install a stack app")
113+
})
114+
describe("Stack API Key and App ID provided through flags", () => {
115+
test
116+
.stdout({ print: process.env.PRINT === "true" || false })
117+
.stub(ux.action, "stop", () => {})
118+
.stub(ux.action, "start", () => {})
119+
.stub(cliux, "inquire", async (...args: any) => {
120+
const [prompt]: any = args;
121+
const cases = {
122+
Organization: mock.organizations[0].name,
123+
};
124+
125+
return (cases as Record<string, any>)[prompt.name];
126+
})
127+
.nock(region.cma, (api) =>
128+
api
129+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
130+
.reply(200, { organizations: mock.organizations })
131+
)
132+
.nock(region.cma, (api) =>
133+
api
134+
.get(`/v3/stacks`)
135+
.reply(200, { stack: mock.stacks[0] })
136+
)
137+
.nock(`https://${developerHubBaseUrl}`, (api) =>
138+
api
139+
.get(`/manifests/${mock.apps[0].uid}`)
140+
.reply(200, {
141+
data: mock.apps[0],
142+
})
143+
)
144+
.nock(`https://${developerHubBaseUrl}`, (api) =>
145+
api
146+
.post(`/manifests/${mock.apps[0].uid}/install`, {
147+
"target_type": mock.apps[0].target_type,
148+
"target_uid": mock.stacks[0].api_key
149+
})
150+
.reply(200, {
151+
data: mock.apps,
152+
})
153+
)
154+
.command([
155+
"app:install", "--stack-api-key", mock.stacks[0].api_key, "--app-uid", mock.apps[0].uid
156+
])
157+
.do(({stdout}) => {
158+
expect(stdout).to.contain($t(messages.APP_INSTALLED_SUCCESSFULLY, {
159+
app: mock.apps[0].name,
160+
target: mock.stacks[0].name
161+
}))
162+
})
163+
.it("should install a stack app")
164+
})
165+
describe("App is already installed", () => {
166+
test
167+
.stdout({ print: process.env.PRINT === "true" || false })
168+
.stub(ux.action, "stop", () => {})
169+
.stub(ux.action, "start", () => {})
170+
.stub(cliux, "inquire", async (...args: any) => {
171+
const [prompt]: any = args;
172+
const cases = {
173+
App: mock.apps[1].name,
174+
Organization: mock.organizations[0].name,
175+
};
176+
177+
return (cases as Record<string, any>)[prompt.name];
178+
})
179+
.nock(region.cma, (api) =>
180+
api
181+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
182+
.reply(200, { organizations: mock.organizations })
183+
)
184+
.nock(`https://${developerHubBaseUrl}`, (api) =>
185+
api
186+
.get("/manifests?limit=50&asc=name&include_count=true&skip=0")
187+
.reply(200, {
188+
data: mock.apps,
189+
})
190+
)
191+
.nock(`https://${developerHubBaseUrl}`, (api) =>
192+
api
193+
.post(`/manifests/${mock.apps[1].uid}/install`, {
194+
"target_type": mock.apps[1].target_type,
195+
"target_uid": mock.organizations[0].uid
196+
})
197+
.replyWithError({
198+
"status": 400,
199+
"message": "Installation for app is already done",
200+
"error": "Internal Server Error"
201+
})
202+
)
203+
.command([
204+
"app:install"
205+
])
206+
.exit(1)
207+
.do(({stdout}) => {
208+
expect(stdout).to.contain("Installation for app is already done")
209+
})
210+
.it("should fail with an error that app is already installed")
211+
})
212+
// describe("Invalid app provided")
213+
// describe("Stack API Key is provided, but the app selected is an organization app")
214+
})

test/unit/mock/common.mock.json

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,33 @@
1212
"apps": [
1313
{
1414
"uid": "app-uid-1",
15-
"name": "App 1"
15+
"name": "App 1",
16+
"target_type": "stack"
1617
},
1718
{
1819
"uid": "app-uid-2",
19-
"name": "App 2"
20+
"name": "App 2",
21+
"target_type": "organization"
22+
}
23+
],
24+
"stacks": [
25+
{
26+
"name": "Stack 1",
27+
"uid": "stack-uid-1",
28+
"api_key": "stack_api_key_1"
29+
},
30+
{
31+
"name": "Stack 2",
32+
"uid": "stack-uid-2",
33+
"api_key": "stack_api_key_2"
2034
}
2135
],
2236
"installations": [
2337
{
2438
"uid": "test-installation-uid-1"
39+
},
40+
{
41+
"uid": "test-installation-uid-2"
2542
}
2643
]
2744
}

0 commit comments

Comments
 (0)