Skip to content

Commit 0877ce0

Browse files
Merge pull request #72 from contentstack/feat/CS-39668
test: Update command unit test added
2 parents a0a580e + 80df46e commit 0877ce0

7 files changed

Lines changed: 544 additions & 15 deletions

File tree

.github/workflows/secrets-scan.yml

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { PassThrough } from "stream";
88
import { expect, test } from "@oclif/test";
99
import { cliux, ux, configHandler } from "@contentstack/cli-utilities";
1010

11-
import config from "../../../src/config";
12-
import messages from "../../../src/messages";
13-
import * as mock from "../mock/create.mock.json";
14-
import manifestData from "../../../src/config/manifest.json";
11+
import config from "../../../../src/config";
12+
import messages from "../../../../src/messages";
13+
import * as mock from "../../mock/common.mock.json";
14+
import manifestData from "../../../../src/config/manifest.json";
1515

1616
const gitHubHost = "https://github.com";
1717
const zipPath = join(process.cwd(), "test", "unit", "mock", "boilerplate.zip");
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
import fs from "fs";
2+
import { join } from "path";
3+
import { PassThrough } from "stream";
4+
5+
import { expect, test } from "@oclif/test";
6+
import { cliux, ux, configHandler } from "@contentstack/cli-utilities";
7+
8+
import config from "../../../../src/config";
9+
import messages from "../../../../src/messages";
10+
import * as mock from "../../mock/common.mock.json";
11+
import manifestData from "../../config/manifest.json";
12+
13+
const region: { cma: string; name: string; cda: string } =
14+
configHandler.get("region");
15+
const developerHubBaseUrl = (config.developerHubUrls as Record<string, any>)[
16+
region.cma
17+
];
18+
19+
describe("app:update", () => {
20+
describe("Update app with `--app-manifest` flag", () => {
21+
test
22+
.stdout({ print: process.env.PRINT === "true" || false })
23+
.stub(ux.action, "stop", () => {})
24+
.stub(ux.action, "start", () => {})
25+
.stub(fs, "writeFileSync", () => new PassThrough())
26+
.stub(cliux, "inquire", async (...args: any) => {
27+
const [prompt]: any = args;
28+
const cases = {
29+
appUid: "app-uid-1",
30+
Organization: "test org 1",
31+
appManifest: "test-manifest",
32+
};
33+
34+
return (cases as Record<string, any>)[prompt.name];
35+
})
36+
.nock(region.cma, (api) =>
37+
api
38+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
39+
.reply(200, { organizations: mock.organizations })
40+
)
41+
.nock(`https://${developerHubBaseUrl}`, (api) =>
42+
api.get("/manifests/app-uid-1").reply(200, {
43+
data: { ...manifestData, name: "test-app", version: 1 },
44+
})
45+
)
46+
.nock(`https://${developerHubBaseUrl}`, (api) =>
47+
api.put("/manifests/app-uid-1").reply(200, {
48+
data: { ...manifestData, name: "test-app", version: 1 },
49+
})
50+
)
51+
.command([
52+
"app:update",
53+
"--app-manifest",
54+
join(process.cwd(), "test", "unit", "config", "manifest.json"),
55+
])
56+
.do(({ stdout }) =>
57+
expect(stdout).to.contain(messages.APP_UPDATE_SUCCESS)
58+
)
59+
.it("should update a app");
60+
});
61+
describe("Update app with `--data-dir` flag", () => {
62+
test
63+
.stdout({ print: process.env.PRINT === "true" || false })
64+
.stub(ux.action, "stop", () => {})
65+
.stub(ux.action, "start", () => {})
66+
.stub(fs, "writeFileSync", () => new PassThrough())
67+
.stub(cliux, "inquire", async (...args: any) => {
68+
const [prompt]: any = args;
69+
const cases = {
70+
appUid: "app-uid-1",
71+
Organization: "test org 1",
72+
appManifest: "test-manifest",
73+
};
74+
75+
return (cases as Record<string, any>)[prompt.name];
76+
})
77+
.nock(region.cma, (api) =>
78+
api
79+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
80+
.reply(200, { organizations: mock.organizations })
81+
)
82+
.nock(`https://${developerHubBaseUrl}`, (api) =>
83+
api.get("/manifests/app-uid-1").reply(200, {
84+
data: { ...manifestData, name: "test-app", version: 1 },
85+
})
86+
)
87+
.nock(`https://${developerHubBaseUrl}`, (api) =>
88+
api.put("/manifests/app-uid-1").reply(200, {
89+
data: { ...manifestData, name: "test-app", version: 1 },
90+
})
91+
)
92+
.command([
93+
"app:update",
94+
"--data-dir",
95+
join(process.cwd(), "test", "unit", "config"),
96+
])
97+
.do(({ stdout }) =>
98+
expect(stdout).to.contain(messages.APP_UPDATE_SUCCESS)
99+
)
100+
.it("should update a app");
101+
});
102+
describe("Update app with wrong `manifest.json` path", () => {
103+
test
104+
.stdout({ print: process.env.PRINT === "true" || false })
105+
.stub(ux.action, "stop", () => {})
106+
.stub(ux.action, "start", () => {})
107+
.stub(fs, "writeFileSync", () => new PassThrough())
108+
.stub(cliux, "inquire", async (...args: any) => {
109+
const [prompt]: any = args;
110+
const cases = {
111+
appUid: "app-uid-1",
112+
Organization: "test org 1",
113+
appManifest: "test-manifest",
114+
};
115+
116+
return (cases as Record<string, any>)[prompt.name];
117+
})
118+
.nock(region.cma, (api) =>
119+
api
120+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
121+
.reply(200, { organizations: mock.organizations })
122+
)
123+
.command(["app:update"])
124+
.do(({ stdout }) => expect(stdout).to.contain(messages.MAX_RETRY_LIMIT))
125+
.it("should fail with manifest max retry message");
126+
});
127+
describe("Update app with wrong `app-uid`", () => {
128+
test
129+
.stdout({ print: process.env.PRINT === "true" || false })
130+
.stub(ux.action, "stop", () => {})
131+
.stub(ux.action, "start", () => {})
132+
.stub(fs, "writeFileSync", () => new PassThrough())
133+
.stub(cliux, "inquire", async (...args: any) => {
134+
const [prompt]: any = args;
135+
const cases = {
136+
appUid: "app-uid-2",
137+
Organization: "test org 1",
138+
appManifest: "test-manifest",
139+
};
140+
141+
return (cases as Record<string, any>)[prompt.name];
142+
})
143+
.nock(region.cma, (api) =>
144+
api
145+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
146+
.reply(200, { organizations: mock.organizations })
147+
)
148+
.command([
149+
"app:update",
150+
"--app-manifest",
151+
join(process.cwd(), "test", "unit", "config", "manifest.json"),
152+
])
153+
.do(({ stdout }) => expect(stdout).to.contain(messages.MAX_RETRY_LIMIT))
154+
.it("should fail with max retry message");
155+
});
156+
describe("Update app with wrong `app version`", () => {
157+
test
158+
.stdout({ print: process.env.PRINT === "true" || false })
159+
.stub(ux.action, "stop", () => {})
160+
.stub(ux.action, "start", () => {})
161+
.stub(fs, "writeFileSync", () => new PassThrough())
162+
.stub(cliux, "inquire", async (...args: any) => {
163+
const [prompt]: any = args;
164+
const cases = {
165+
appUid: "app-uid-1",
166+
Organization: "test org 1",
167+
appManifest: "test-manifest",
168+
};
169+
170+
return (cases as Record<string, any>)[prompt.name];
171+
})
172+
.nock(region.cma, (api) =>
173+
api
174+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
175+
.reply(200, { organizations: mock.organizations })
176+
)
177+
.nock(`https://${developerHubBaseUrl}`, (api) =>
178+
api.get("/manifests/app-uid-1").reply(200, {
179+
data: { ...manifestData, name: "test-app", version: 2 },
180+
})
181+
)
182+
.command([
183+
"app:update",
184+
"--app-manifest",
185+
join(process.cwd(), "test", "unit", "config", "manifest.json"),
186+
])
187+
.do(({ stdout }) =>
188+
expect(stdout).to.contain(messages.APP_VERSION_MISS_MATCH)
189+
)
190+
.it("should fail with version miss match error message");
191+
});
192+
describe("Update app wrong app-uid API failure", () => {
193+
test
194+
.stdout({ print: process.env.PRINT === "true" || false })
195+
.stub(ux.action, "stop", () => {})
196+
.stub(ux.action, "start", () => {})
197+
.stub(fs, "writeFileSync", () => new PassThrough())
198+
.stub(cliux, "inquire", async (...args: any) => {
199+
const [prompt]: any = args;
200+
const cases = {
201+
appUid: "app-uid-1",
202+
Organization: "test org 1",
203+
appManifest: "test-manifest",
204+
};
205+
206+
return (cases as Record<string, any>)[prompt.name];
207+
})
208+
.nock(region.cma, (api) =>
209+
api
210+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
211+
.reply(200, { organizations: mock.organizations })
212+
)
213+
.nock(`https://${developerHubBaseUrl}`, (api) =>
214+
api.get("/manifests/app-uid-1").reply(200, {
215+
data: { ...manifestData, name: "test-app", version: 1 },
216+
})
217+
)
218+
.nock(`https://${developerHubBaseUrl}`, (api) =>
219+
api.put("/manifests/app-uid-1").reply(400, {
220+
data: { ...manifestData, name: "test-app", version: 1 },
221+
})
222+
)
223+
.command([
224+
"app:update",
225+
"--app-manifest",
226+
join(process.cwd(), "test", "unit", "config", "manifest.json"),
227+
])
228+
.do(({ stdout }) => expect(stdout).to.contain(messages.INVALID_APP_ID))
229+
.it("update app should fail with 400 status code");
230+
});
231+
describe("Update app wrong org-uid API failure", () => {
232+
test
233+
.stdout({ print: process.env.PRINT === "true" || false })
234+
.stub(ux.action, "stop", () => {})
235+
.stub(ux.action, "start", () => {})
236+
.stub(fs, "writeFileSync", () => new PassThrough())
237+
.stub(cliux, "inquire", async (...args: any) => {
238+
const [prompt]: any = args;
239+
const cases = {
240+
appUid: "app-uid-1",
241+
Organization: "test org 1",
242+
appManifest: "test-manifest",
243+
};
244+
245+
return (cases as Record<string, any>)[prompt.name];
246+
})
247+
.nock(region.cma, (api) =>
248+
api
249+
.get("/v3/organizations?limit=100&asc=name&include_count=true&skip=0")
250+
.reply(200, { organizations: mock.organizations })
251+
)
252+
.nock(`https://${developerHubBaseUrl}`, (api) =>
253+
api.get("/manifests/app-uid-1").reply(200, {
254+
data: { ...manifestData, name: "test-app", version: 1 },
255+
})
256+
)
257+
.nock(`https://${developerHubBaseUrl}`, (api) =>
258+
api.put("/manifests/app-uid-1").reply(403, {
259+
data: { ...manifestData, name: "test-app", version: 1 },
260+
})
261+
)
262+
.command([
263+
"app:update",
264+
"--app-manifest",
265+
join(process.cwd(), "test", "unit", "config", "manifest.json"),
266+
])
267+
.do(({ stdout }) => expect(stdout).to.contain(messages.APP_INVALID_ORG))
268+
.it("update app should fail with 403 status code");
269+
});
270+
});

test/unit/config/manifest.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"version": 1,
3+
"name": "test-app",
4+
"uid": "app-uid-1",
5+
"target_type": "stack",
6+
"visibility": "private",
7+
"description": "test app",
8+
"organization_uid": "test-uid-1"
9+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { fancy } from "fancy-test";
2+
import { expect } from "@oclif/test";
3+
import {
4+
configHandler,
5+
ContentstackClient,
6+
managementSDKClient,
7+
} from "@contentstack/cli-utilities";
8+
9+
import { getOrganizations } from "../../../src/util/common-utils";
10+
import * as mock from "../mock/common.mock.json";
11+
import { LogFn } from "../../../src/types";
12+
13+
const region: { cma: string; name: string; cda: string } =
14+
configHandler.get("region");
15+
16+
describe("common utils", () => {
17+
const log: LogFn = () => {};
18+
let managementSdk: ContentstackClient;
19+
20+
before(async () => {
21+
managementSdk = await managementSDKClient({
22+
host: region.cma.replace("https://", ""),
23+
});
24+
});
25+
26+
describe("getOrganizations", () => {
27+
describe("Get list of organizations", () => {
28+
fancy
29+
.nock(region.cma, (api) =>
30+
api
31+
.get(
32+
"/v3/organizations?limit=100&asc=name&include_count=true&skip=0"
33+
)
34+
.reply(200, { organizations: mock.organizations })
35+
)
36+
.it("Returns list of org", async () => {
37+
const [org1, org2] = await getOrganizations({ log, managementSdk });
38+
expect(org1.uid).to.equal(mock.organizations[0].uid);
39+
expect(org2.uid).to.equal(mock.organizations[1].uid);
40+
});
41+
});
42+
43+
describe("Get list of organizations using pagination", () => {
44+
fancy
45+
.nock(region.cma, (api) =>
46+
api
47+
.get(
48+
"/v3/organizations?limit=100&asc=name&include_count=true&skip=0"
49+
)
50+
.reply(200, { organizations: mock.organizations, count: 110 })
51+
)
52+
.nock(region.cma, (api) =>
53+
api
54+
.get(
55+
"/v3/organizations?limit=100&asc=name&include_count=true&skip=100"
56+
)
57+
.reply(200, { organizations: mock.organizations, count: 0 })
58+
)
59+
.it("returns list of organizations", async () => {
60+
const organizations = await getOrganizations({ log, managementSdk });
61+
const [org1, org2] = organizations;
62+
expect(org1.uid).to.equal(mock.organizations[0].uid);
63+
expect(org2.uid).to.equal(mock.organizations[1].uid);
64+
});
65+
});
66+
67+
describe("Get list of organizations failure case", async () => {
68+
fancy
69+
.nock(region.cma, (api) =>
70+
api
71+
.get(
72+
"/v3/organizations?limit=100&asc=name&include_count=true&skip=0"
73+
)
74+
.reply(400)
75+
)
76+
.do(async () => await getOrganizations({ log, managementSdk }))
77+
.catch((err) => {
78+
const { status }: { status: number } = JSON.parse(err.message);
79+
expect(status).to.equal(400);
80+
})
81+
.it("API fails with status code 400");
82+
});
83+
});
84+
});

0 commit comments

Comments
 (0)