@revopush/code-push-cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.eslintrc.json +17 -0
  2. package/.idea/cli.iml +9 -0
  3. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/prettier.xml +6 -0
  7. package/.idea/vcs.xml +6 -0
  8. package/README.md +774 -0
  9. package/bin/script/acquisition-sdk.js +178 -0
  10. package/bin/script/cli.js +23 -0
  11. package/bin/script/command-executor.js +1290 -0
  12. package/bin/script/command-parser.js +1097 -0
  13. package/bin/script/commands/debug.js +125 -0
  14. package/bin/script/hash-utils.js +203 -0
  15. package/bin/script/index.js +5 -0
  16. package/bin/script/management-sdk.js +419 -0
  17. package/bin/script/react-native-utils.js +249 -0
  18. package/bin/script/sign.js +69 -0
  19. package/bin/script/types/cli.js +40 -0
  20. package/bin/script/types/rest-definitions.js +19 -0
  21. package/bin/script/types.js +4 -0
  22. package/bin/script/utils/file-utils.js +50 -0
  23. package/bin/test/acquisition-rest-mock.js +108 -0
  24. package/bin/test/acquisition-sdk.js +188 -0
  25. package/bin/test/cli.js +1342 -0
  26. package/bin/test/hash-utils.js +149 -0
  27. package/bin/test/management-sdk.js +338 -0
  28. package/package.json +68 -0
  29. package/prettier.config.js +7 -0
  30. package/script/acquisition-sdk.ts +273 -0
  31. package/script/cli.ts +27 -0
  32. package/script/command-executor.ts +1610 -0
  33. package/script/command-parser.ts +1310 -0
  34. package/script/commands/debug.ts +148 -0
  35. package/script/hash-utils.ts +241 -0
  36. package/script/index.ts +5 -0
  37. package/script/management-sdk.ts +575 -0
  38. package/script/react-native-utils.ts +283 -0
  39. package/script/sign.ts +80 -0
  40. package/script/types/cli.ts +232 -0
  41. package/script/types/rest-definitions.ts +152 -0
  42. package/script/types.ts +35 -0
  43. package/script/utils/file-utils.ts +46 -0
  44. package/test/acquisition-rest-mock.ts +125 -0
  45. package/test/acquisition-sdk.ts +272 -0
  46. package/test/cli.ts +1692 -0
  47. package/test/hash-utils.ts +170 -0
  48. package/test/management-sdk.ts +438 -0
  49. package/test/resources/TestApp/android/app/build.gradle +56 -0
  50. package/test/resources/TestApp/iOS/TestApp/Info.plist +49 -0
  51. package/test/resources/TestApp/index.android.js +2 -0
  52. package/test/resources/TestApp/index.ios.js +2 -0
  53. package/test/resources/TestApp/index.windows.js +2 -0
  54. package/test/resources/TestApp/package.json +6 -0
  55. package/test/resources/TestApp/windows/TestApp/Package.appxmanifest +46 -0
  56. package/test/resources/ignoredMetadata.zip +0 -0
  57. package/test/resources/test.zip +0 -0
  58. package/test/superagent-mock-config.js +58 -0
  59. package/tsconfig.json +13 -0
@@ -0,0 +1,170 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import * as assert from "assert";
5
+ import * as crypto from "crypto";
6
+ import * as fs from "fs";
7
+ import * as hashUtils from "../script/hash-utils";
8
+ var mkdirp = require("mkdirp");
9
+ import * as os from "os";
10
+ import * as path from "path";
11
+ import * as q from "q";
12
+ var yauzl = require("yauzl");
13
+
14
+ import PackageManifest = hashUtils.PackageManifest;
15
+ import Promise = q.Promise;
16
+
17
+ function randomString(): string {
18
+ var stringLength = 10;
19
+ return crypto
20
+ .randomBytes(Math.ceil(stringLength / 2))
21
+ .toString("hex") // convert to hexadecimal format
22
+ .slice(0, stringLength); // return required number of characters
23
+ }
24
+
25
+ function unzipToDirectory(zipPath: string, directoryPath: string): Promise<void> {
26
+ var deferred: q.Deferred<void> = q.defer<void>();
27
+ var originalCwd: string = process.cwd();
28
+
29
+ mkdirp(directoryPath, (err: Error) => {
30
+ if (err) throw err;
31
+ process.chdir(directoryPath);
32
+
33
+ yauzl.open(zipPath, { lazyEntries: true }, function (err: Error, zipfile: any) {
34
+ if (err) throw err;
35
+ zipfile.readEntry();
36
+ zipfile.on("entry", function (entry: any) {
37
+ if (/\/$/.test(entry.fileName)) {
38
+ // directory file names end with '/'
39
+ mkdirp(entry.fileName, function (err: Error) {
40
+ if (err) throw err;
41
+ zipfile.readEntry();
42
+ });
43
+ } else {
44
+ // file entry
45
+ zipfile.openReadStream(entry, function (err: Error, readStream: any) {
46
+ if (err) throw err;
47
+ // ensure parent directory exists
48
+ mkdirp(path.dirname(entry.fileName), function (err: Error) {
49
+ if (err) throw err;
50
+ readStream.pipe(fs.createWriteStream(entry.fileName));
51
+ readStream.on("end", function () {
52
+ zipfile.readEntry();
53
+ });
54
+ });
55
+ });
56
+ }
57
+ });
58
+
59
+ zipfile.on("end", function (err: Error) {
60
+ if (err) deferred.reject(err);
61
+ else deferred.resolve(<void>null);
62
+ });
63
+ });
64
+ });
65
+
66
+ return deferred.promise.finally(() => {
67
+ process.chdir(originalCwd);
68
+ });
69
+ }
70
+
71
+ describe("Hashing utility", () => {
72
+ const TEST_DIRECTORY = path.join(os.tmpdir(), "codepushtests", randomString());
73
+
74
+ const TEST_ARCHIVE_FILE_PATH = path.join(__dirname, "resources", "test.zip");
75
+ const TEST_ZIP_HASH = "540fed8df3553079e81d1353c5cc4e3cac7db9aea647a85d550f646e8620c317";
76
+ const TEST_ZIP_MANIFEST_HASH = "9e0499ce7df5c04cb304c9deed684dc137fc603cb484a5b027478143c595d80b";
77
+ const HASH_B = "3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d";
78
+ const HASH_C = "2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6";
79
+ const HASH_D = "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4";
80
+
81
+ const IGNORED_METADATA_ARCHIVE_FILE_PATH = path.join(__dirname, "resources", "ignoredMetadata.zip");
82
+ const INDEX_HASH = "b0693dc92f76e08bf1485b3dd9b514a2e31dfd6f39422a6b60edb722671dc98f";
83
+
84
+ it("generates a package hash from file", (done) => {
85
+ hashUtils.hashFile(TEST_ARCHIVE_FILE_PATH).done((packageHash: string): void => {
86
+ assert.equal(packageHash, TEST_ZIP_HASH);
87
+
88
+ done();
89
+ });
90
+ });
91
+
92
+ it("generates a package manifest for an archive", (done) => {
93
+ hashUtils.generatePackageManifestFromZip(TEST_ARCHIVE_FILE_PATH).done((manifest: PackageManifest): void => {
94
+ var fileHashesMap = manifest.toMap();
95
+ assert.equal(fileHashesMap.size, 3);
96
+
97
+ var hash: string = fileHashesMap.get("b.txt");
98
+ assert.equal(hash, HASH_B);
99
+
100
+ hash = fileHashesMap.get("c.txt");
101
+ assert.equal(hash, HASH_C);
102
+
103
+ hash = fileHashesMap.get("d.txt");
104
+ assert.equal(hash, HASH_D);
105
+
106
+ done();
107
+ });
108
+ });
109
+
110
+ it("generates a package manifest for a directory", (done) => {
111
+ var directory = path.join(TEST_DIRECTORY, "testZip");
112
+
113
+ unzipToDirectory(TEST_ARCHIVE_FILE_PATH, directory)
114
+ .then(() => {
115
+ return hashUtils.generatePackageManifestFromDirectory(/*directoryPath*/ directory, /*basePath*/ directory);
116
+ })
117
+ .done((manifest: PackageManifest): void => {
118
+ var fileHashesMap = manifest.toMap();
119
+ assert.equal(fileHashesMap.size, 3);
120
+
121
+ var hash: string = fileHashesMap.get("b.txt");
122
+ assert.equal(hash, HASH_B);
123
+
124
+ hash = fileHashesMap.get("c.txt");
125
+ assert.equal(hash, HASH_C);
126
+
127
+ hash = fileHashesMap.get("d.txt");
128
+ assert.equal(hash, HASH_D);
129
+
130
+ done();
131
+ });
132
+ });
133
+
134
+ it("generates a package hash from manifest", (done) => {
135
+ hashUtils
136
+ .generatePackageManifestFromZip(TEST_ARCHIVE_FILE_PATH)
137
+ .then((manifest: PackageManifest) => {
138
+ return manifest.computePackageHash();
139
+ })
140
+ .done((packageHash: string): void => {
141
+ assert.equal(packageHash, TEST_ZIP_MANIFEST_HASH);
142
+
143
+ done();
144
+ });
145
+ });
146
+
147
+ it("generates a package manifest for an archive with ignorable metadata", (done) => {
148
+ hashUtils.generatePackageManifestFromZip(IGNORED_METADATA_ARCHIVE_FILE_PATH).done((manifest: PackageManifest): void => {
149
+ assert.equal(manifest.toMap().size, 1);
150
+ var hash: string = manifest.toMap().get("www/index.html");
151
+ assert.equal(hash, INDEX_HASH);
152
+ done();
153
+ });
154
+ });
155
+
156
+ it("generates a package manifest for a directory with ignorable metadata", (done) => {
157
+ var directory = path.join(TEST_DIRECTORY, "ignorableMetadata");
158
+
159
+ unzipToDirectory(IGNORED_METADATA_ARCHIVE_FILE_PATH, directory)
160
+ .then(() => {
161
+ return hashUtils.generatePackageManifestFromDirectory(/*directoryPath*/ directory, /*basePath*/ directory);
162
+ })
163
+ .done((manifest: PackageManifest): void => {
164
+ assert.equal(manifest.toMap().size, 1);
165
+ var hash: string = manifest.toMap().get("www/index.html");
166
+ assert.equal(hash, INDEX_HASH);
167
+ done();
168
+ });
169
+ });
170
+ });
@@ -0,0 +1,438 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import * as assert from "assert";
5
+ import * as Q from "q";
6
+
7
+ import AccountManager = require("../script/management-sdk");
8
+
9
+ var request = require("superagent");
10
+
11
+ var manager: AccountManager;
12
+ describe("Management SDK", () => {
13
+ beforeEach(() => {
14
+ manager = new AccountManager(/*accessKey=*/ "dummyAccessKey", /*customHeaders=*/ null, /*serverUrl=*/ "http://localhost");
15
+ });
16
+
17
+ after(() => {
18
+ // Prevent an exception that occurs due to how superagent-mock overwrites methods
19
+ request.Request.prototype._callback = function () {};
20
+ });
21
+
22
+ it("methods reject the promise with status code info when an error occurs", (done: Mocha.Done) => {
23
+ mockReturn("Text", 404);
24
+
25
+ var methodsWithErrorHandling: any[] = [
26
+ manager.addApp.bind(manager, "appName"),
27
+ manager.getApp.bind(manager, "appName"),
28
+ manager.renameApp.bind(manager, "appName", {}),
29
+ manager.removeApp.bind(manager, "appName"),
30
+ manager.transferApp.bind(manager, "appName", "email1"),
31
+
32
+ manager.addDeployment.bind(manager, "appName", "deploymentName"),
33
+ manager.getDeployment.bind(manager, "appName", "deploymentName"),
34
+ manager.getDeployments.bind(manager, "appName"),
35
+ manager.renameDeployment.bind(manager, "appName", "deploymentName", {
36
+ name: "newDeploymentName",
37
+ }),
38
+ manager.removeDeployment.bind(manager, "appName", "deploymentName"),
39
+
40
+ manager.addCollaborator.bind(manager, "appName", "email1"),
41
+ manager.getCollaborators.bind(manager, "appName"),
42
+ manager.removeCollaborator.bind(manager, "appName", "email1"),
43
+
44
+ manager.patchRelease.bind(manager, "appName", "deploymentName", "label", {
45
+ description: "newDescription",
46
+ }),
47
+ manager.promote.bind(manager, "appName", "deploymentName", "newDeploymentName", { description: "newDescription" }),
48
+ manager.rollback.bind(manager, "appName", "deploymentName", "targetReleaseLabel"),
49
+ ];
50
+
51
+ var result = Q<void>(null);
52
+ methodsWithErrorHandling.forEach(function (f) {
53
+ result = result.then(() => {
54
+ return testErrors(f);
55
+ });
56
+ });
57
+
58
+ result.done(() => {
59
+ done();
60
+ });
61
+
62
+ // Test that the proper error code and text is passed through on a server error
63
+ function testErrors(method: any): Q.Promise<void> {
64
+ return Q.Promise<void>((resolve: any, reject: any, notify: any) => {
65
+ method().done(
66
+ () => {
67
+ assert.fail("Should have thrown an error");
68
+ reject();
69
+ },
70
+ (error: any) => {
71
+ assert.equal(error.message, "Text");
72
+ assert(error.statusCode);
73
+ resolve();
74
+ }
75
+ );
76
+ });
77
+ }
78
+ });
79
+
80
+ it("isAuthenticated handles successful auth", (done: Mocha.Done) => {
81
+ mockReturn(JSON.stringify({ authenticated: true }), 200, {});
82
+ manager.isAuthenticated().done((authenticated: boolean) => {
83
+ assert(authenticated, "Should be authenticated");
84
+ done();
85
+ });
86
+ });
87
+
88
+ it("isAuthenticated handles unsuccessful auth", (done: Mocha.Done) => {
89
+ mockReturn("Unauthorized", 401, {});
90
+ manager.isAuthenticated().done((authenticated: boolean) => {
91
+ assert(!authenticated, "Should not be authenticated");
92
+ done();
93
+ });
94
+ });
95
+
96
+ it("isAuthenticated handles unsuccessful auth with promise rejection", (done: Mocha.Done) => {
97
+ mockReturn("Unauthorized", 401, {});
98
+
99
+ // use optional parameter to ask for rejection of the promise if not authenticated
100
+ manager.isAuthenticated(true).done(
101
+ (authenticated: boolean) => {
102
+ assert.fail("isAuthenticated should have rejected the promise");
103
+ done();
104
+ },
105
+ (err) => {
106
+ assert.equal(err.message, "Unauthorized", "Error message should be 'Unauthorized'");
107
+ done();
108
+ }
109
+ );
110
+ });
111
+
112
+ it("isAuthenticated handles unexpected status codes", (done: Mocha.Done) => {
113
+ mockReturn("Not Found", 404, {});
114
+ manager.isAuthenticated().done(
115
+ (authenticated: boolean) => {
116
+ assert.fail("isAuthenticated should have rejected the promise");
117
+ done();
118
+ },
119
+ (err) => {
120
+ assert.equal(err.message, "Not Found", "Error message should be 'Not Found'");
121
+ done();
122
+ }
123
+ );
124
+ });
125
+
126
+ it("addApp handles successful response", (done: Mocha.Done) => {
127
+ mockReturn(JSON.stringify({ success: true }), 201, {
128
+ location: "/appName",
129
+ });
130
+ manager.addApp("appName").done((obj) => {
131
+ assert.ok(obj);
132
+ done();
133
+ }, rejectHandler);
134
+ });
135
+
136
+ it("addApp handles error response", (done: Mocha.Done) => {
137
+ mockReturn(JSON.stringify({ success: false }), 404, {});
138
+ manager.addApp("appName").done(
139
+ (obj) => {
140
+ throw new Error("Call should not complete successfully");
141
+ },
142
+ (error: Error) => done()
143
+ );
144
+ });
145
+
146
+ it("getApp handles JSON response", (done: Mocha.Done) => {
147
+ mockReturn(JSON.stringify({ app: {} }), 200, {});
148
+
149
+ manager.getApp("appName").done((obj: any) => {
150
+ assert.ok(obj);
151
+ done();
152
+ }, rejectHandler);
153
+ });
154
+
155
+ it("updateApp handles success response", (done: Mocha.Done) => {
156
+ mockReturn(JSON.stringify({ apps: [] }), 200, {});
157
+
158
+ manager.renameApp("appName", "newAppName").done((obj: any) => {
159
+ assert.ok(!obj);
160
+ done();
161
+ }, rejectHandler);
162
+ });
163
+
164
+ it("removeApp handles success response", (done: Mocha.Done) => {
165
+ mockReturn("", 200, {});
166
+
167
+ manager.removeApp("appName").done((obj: any) => {
168
+ assert.ok(!obj);
169
+ done();
170
+ }, rejectHandler);
171
+ });
172
+
173
+ it("transferApp handles successful response", (done: Mocha.Done) => {
174
+ mockReturn("", 201);
175
+ manager.transferApp("appName", "email1").done((obj: any) => {
176
+ assert.ok(!obj);
177
+ done();
178
+ }, rejectHandler);
179
+ });
180
+
181
+ it("addDeployment handles success response", (done: Mocha.Done) => {
182
+ mockReturn(JSON.stringify({ deployment: { name: "name", key: "key" } }), 201, { location: "/deploymentName" });
183
+
184
+ manager.addDeployment("appName", "deploymentName").done((obj: any) => {
185
+ assert.ok(obj);
186
+ done();
187
+ }, rejectHandler);
188
+ });
189
+
190
+ it("getDeployment handles JSON response", (done: Mocha.Done) => {
191
+ mockReturn(JSON.stringify({ deployment: {} }), 200, {});
192
+
193
+ manager.getDeployment("appName", "deploymentName").done((obj: any) => {
194
+ assert.ok(obj);
195
+ done();
196
+ }, rejectHandler);
197
+ });
198
+
199
+ it("getDeployments handles JSON response", (done: Mocha.Done) => {
200
+ mockReturn(JSON.stringify({ deployments: [] }), 200, {});
201
+
202
+ manager.getDeployments("appName").done((obj: any) => {
203
+ assert.ok(obj);
204
+ done();
205
+ }, rejectHandler);
206
+ });
207
+
208
+ it("renameDeployment handles success response", (done: Mocha.Done) => {
209
+ mockReturn(JSON.stringify({ apps: [] }), 200, {});
210
+
211
+ manager.renameDeployment("appName", "deploymentName", "newDeploymentName").done((obj: any) => {
212
+ assert.ok(!obj);
213
+ done();
214
+ }, rejectHandler);
215
+ });
216
+
217
+ it("removeDeployment handles success response", (done: Mocha.Done) => {
218
+ mockReturn("", 200, {});
219
+
220
+ manager.removeDeployment("appName", "deploymentName").done((obj: any) => {
221
+ assert.ok(!obj);
222
+ done();
223
+ }, rejectHandler);
224
+ });
225
+
226
+ it("getDeploymentHistory handles success response with no packages", (done: Mocha.Done) => {
227
+ mockReturn(JSON.stringify({ history: [] }), 200);
228
+
229
+ manager.getDeploymentHistory("appName", "deploymentName").done((obj: any) => {
230
+ assert.ok(obj);
231
+ assert.equal(obj.length, 0);
232
+ done();
233
+ }, rejectHandler);
234
+ });
235
+
236
+ it("getDeploymentHistory handles success response with two packages", (done: Mocha.Done) => {
237
+ mockReturn(JSON.stringify({ history: [{ label: "v1" }, { label: "v2" }] }), 200);
238
+
239
+ manager.getDeploymentHistory("appName", "deploymentName").done((obj: any) => {
240
+ assert.ok(obj);
241
+ assert.equal(obj.length, 2);
242
+ assert.equal(obj[0].label, "v1");
243
+ assert.equal(obj[1].label, "v2");
244
+ done();
245
+ }, rejectHandler);
246
+ });
247
+
248
+ it("getDeploymentHistory handles error response", (done: Mocha.Done) => {
249
+ mockReturn("", 404);
250
+
251
+ manager.getDeploymentHistory("appName", "deploymentName").done(
252
+ (obj: any) => {
253
+ throw new Error("Call should not complete successfully");
254
+ },
255
+ (error: Error) => done()
256
+ );
257
+ });
258
+
259
+ it("clearDeploymentHistory handles success response", (done: Mocha.Done) => {
260
+ mockReturn("", 204);
261
+
262
+ manager.clearDeploymentHistory("appName", "deploymentName").done((obj: any) => {
263
+ assert.ok(!obj);
264
+ done();
265
+ }, rejectHandler);
266
+ });
267
+
268
+ it("clearDeploymentHistory handles error response", (done: Mocha.Done) => {
269
+ mockReturn("", 404);
270
+
271
+ manager.clearDeploymentHistory("appName", "deploymentName").done(
272
+ (obj: any) => {
273
+ throw new Error("Call should not complete successfully");
274
+ },
275
+ (error: Error) => done()
276
+ );
277
+ });
278
+
279
+ it("addCollaborator handles successful response", (done: Mocha.Done) => {
280
+ mockReturn("", 201, { location: "/collaborators" });
281
+ manager.addCollaborator("appName", "email1").done((obj: any) => {
282
+ assert.ok(!obj);
283
+ done();
284
+ }, rejectHandler);
285
+ });
286
+
287
+ it("addCollaborator handles error response", (done: Mocha.Done) => {
288
+ mockReturn("", 404, {});
289
+ manager.addCollaborator("appName", "email1").done(
290
+ (obj) => {
291
+ throw new Error("Call should not complete successfully");
292
+ },
293
+ (error: Error) => done()
294
+ );
295
+ });
296
+
297
+ it("getCollaborators handles success response with no collaborators", (done: Mocha.Done) => {
298
+ mockReturn(JSON.stringify({ collaborators: {} }), 200);
299
+
300
+ manager.getCollaborators("appName").done((obj: any) => {
301
+ assert.ok(obj);
302
+ assert.equal(Object.keys(obj).length, 0);
303
+ done();
304
+ }, rejectHandler);
305
+ });
306
+
307
+ it("getCollaborators handles success response with multiple collaborators", (done: Mocha.Done) => {
308
+ mockReturn(
309
+ JSON.stringify({
310
+ collaborators: {
311
+ email1: { permission: "Owner", isCurrentAccount: true },
312
+ email2: { permission: "Collaborator", isCurrentAccount: false },
313
+ },
314
+ }),
315
+ 200
316
+ );
317
+
318
+ manager.getCollaborators("appName").done((obj: any) => {
319
+ assert.ok(obj);
320
+ assert.equal(obj["email1"].permission, "Owner");
321
+ assert.equal(obj["email2"].permission, "Collaborator");
322
+ done();
323
+ }, rejectHandler);
324
+ });
325
+
326
+ it("removeCollaborator handles success response", (done: Mocha.Done) => {
327
+ mockReturn("", 200, {});
328
+
329
+ manager.removeCollaborator("appName", "email1").done((obj: any) => {
330
+ assert.ok(!obj);
331
+ done();
332
+ }, rejectHandler);
333
+ });
334
+
335
+ it("patchRelease handles success response", (done: Mocha.Done) => {
336
+ mockReturn(JSON.stringify({ package: { description: "newDescription" } }), 200);
337
+
338
+ manager
339
+ .patchRelease("appName", "deploymentName", "label", {
340
+ description: "newDescription",
341
+ })
342
+ .done((obj: any) => {
343
+ assert.ok(!obj);
344
+ done();
345
+ }, rejectHandler);
346
+ });
347
+
348
+ it("patchRelease handles error response", (done: Mocha.Done) => {
349
+ mockReturn("", 400);
350
+
351
+ manager.patchRelease("appName", "deploymentName", "label", {}).done(
352
+ (obj: any) => {
353
+ throw new Error("Call should not complete successfully");
354
+ },
355
+ (error: Error) => done()
356
+ );
357
+ });
358
+
359
+ it("promote handles success response", (done: Mocha.Done) => {
360
+ mockReturn(JSON.stringify({ package: { description: "newDescription" } }), 200);
361
+
362
+ manager
363
+ .promote("appName", "deploymentName", "newDeploymentName", {
364
+ description: "newDescription",
365
+ })
366
+ .done((obj: any) => {
367
+ assert.ok(!obj);
368
+ done();
369
+ }, rejectHandler);
370
+ });
371
+
372
+ it("promote handles error response", (done: Mocha.Done) => {
373
+ mockReturn("", 400);
374
+
375
+ manager
376
+ .promote("appName", "deploymentName", "newDeploymentName", {
377
+ rollout: 123,
378
+ })
379
+ .done(
380
+ (obj: any) => {
381
+ throw new Error("Call should not complete successfully");
382
+ },
383
+ (error: Error) => done()
384
+ );
385
+ });
386
+
387
+ it("rollback handles success response", (done: Mocha.Done) => {
388
+ mockReturn(JSON.stringify({ package: { label: "v1" } }), 200);
389
+
390
+ manager.rollback("appName", "deploymentName", "v1").done((obj: any) => {
391
+ assert.ok(!obj);
392
+ done();
393
+ }, rejectHandler);
394
+ });
395
+
396
+ it("rollback handles error response", (done: Mocha.Done) => {
397
+ mockReturn("", 400);
398
+
399
+ manager.rollback("appName", "deploymentName", "v1").done(
400
+ (obj: any) => {
401
+ throw new Error("Call should not complete successfully");
402
+ },
403
+ (error: Error) => done()
404
+ );
405
+ });
406
+ });
407
+
408
+ // Helper method that is used everywhere that an assert.fail() is needed in a promise handler
409
+ function rejectHandler(val: any): void {
410
+ assert.fail();
411
+ }
412
+
413
+ // Wrapper for superagent-mock that abstracts away information not needed for SDK tests
414
+ function mockReturn(bodyText: string, statusCode: number, header = {}): void {
415
+ require("superagent-mock")(request, [
416
+ {
417
+ pattern: "http://localhost/(\\w+)/?",
418
+ fixtures: function (match: any, params: any): any {
419
+ var isOk = statusCode >= 200 && statusCode < 300;
420
+ if (!isOk) {
421
+ var err: any = new Error(bodyText);
422
+ err.status = statusCode;
423
+ throw err;
424
+ }
425
+ return {
426
+ text: bodyText,
427
+ status: statusCode,
428
+ ok: isOk,
429
+ header: header,
430
+ headers: {},
431
+ };
432
+ },
433
+ callback: function (match: any, data: any): any {
434
+ return data;
435
+ },
436
+ },
437
+ ]);
438
+ }
@@ -0,0 +1,56 @@
1
+ apply plugin: "com.android.application"
2
+
3
+ import com.android.build.OutputFile
4
+
5
+ apply from: "react.gradle"
6
+
7
+ def enableSeparateBuildPerCPUArchitecture = false
8
+ def enableProguardInReleaseBuilds = true
9
+
10
+ android {
11
+ compileSdkVersion 23
12
+ buildToolsVersion "23.0.1"
13
+
14
+ defaultConfig {
15
+ applicationId "com.microsoft.testapp"
16
+ minSdkVersion 16
17
+ targetSdkVersion 22
18
+ versionCode 1
19
+ versionName "1.0.0"
20
+ ndk {
21
+ abiFilters "armeabi-v7a", "x86"
22
+ }
23
+ }
24
+ splits {
25
+ abi {
26
+ enable enableSeparateBuildPerCPUArchitecture
27
+ universalApk true
28
+ reset()
29
+ include "armeabi-v7a", "x86"
30
+ }
31
+ }
32
+ buildTypes {
33
+ release {
34
+ minifyEnabled enableProguardInReleaseBuilds
35
+ proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
36
+ }
37
+ }
38
+
39
+ applicationVariants.all { variant ->
40
+ variant.outputs.each { output ->
41
+ def versionCodes = ["armeabi-v7a":1, "x86":2]
42
+ def abi = output.getFilter(OutputFile.ABI)
43
+ if (abi != null) {
44
+ output.versionCodeOverride =
45
+ versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ dependencies {
52
+ compile fileTree(dir: "libs", include: ["*.jar"])
53
+ compile "com.android.support:appcompat-v7:23.0.1"
54
+ compile "com.facebook.react:react-native:0.19.+"
55
+ compile project(":react-native-code-push")
56
+ }