@botonic/cli 0.42.0 → 0.44.0

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.
@@ -4,7 +4,7 @@ import { dirname } from 'path';
4
4
  const __filename = fileURLToPath(import.meta.url);
5
5
  const __dirname = dirname(__filename);
6
6
  const exampleTestPath = path.resolve(__dirname, '..', '..', '..', 'examples');
7
- const exampleVersion = '0.42.0';
7
+ const exampleVersion = '0.44.0';
8
8
  export const EXAMPLES = [
9
9
  {
10
10
  name: 'blank',
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,423 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { jest } from '@jest/globals';
3
+ import axios from 'axios';
4
+ import { BotonicAPIService } from '../src/botonic-api-service.js';
5
+ import { BotCredentialsHandler, GlobalCredentialsHandler, } from '../src/util/credentials-handler.js';
6
+ describe('TEST: BotonicApiService', () => {
7
+ let service;
8
+ const mockOAuth = {
9
+ access_token: 'test-access-token',
10
+ expires_in: 3600,
11
+ token_type: 'Bearer',
12
+ scope: 'read write',
13
+ refresh_token: 'test-refresh-token',
14
+ };
15
+ const mockMe = {
16
+ id: 'user-123',
17
+ email: 'test@example.com',
18
+ first_name: 'John',
19
+ last_name: 'Doe',
20
+ organization_id: 'org-123',
21
+ campaign: 'test-campaign',
22
+ };
23
+ const mockBot = {
24
+ id: 'bot-123',
25
+ name: 'test-bot',
26
+ organization: 'org-123',
27
+ last_update: {
28
+ version: '1.0.0',
29
+ created_at: '2024-01-01T00:00:00Z',
30
+ modified_at: '2024-01-02T00:00:00Z',
31
+ published_at: '2024-01-03T00:00:00Z',
32
+ comment: 'Test update',
33
+ },
34
+ created_at: '2024-01-01T00:00:00Z',
35
+ provider_accounts: [],
36
+ is_debug: false,
37
+ is_published: true,
38
+ active_users: 10,
39
+ };
40
+ beforeEach(() => {
41
+ // Mock the credential handlers
42
+ jest
43
+ .spyOn(GlobalCredentialsHandler.prototype, 'load')
44
+ .mockReturnValue(undefined);
45
+ jest
46
+ .spyOn(BotCredentialsHandler.prototype, 'load')
47
+ .mockReturnValue(undefined);
48
+ jest
49
+ .spyOn(GlobalCredentialsHandler.prototype, 'dump')
50
+ .mockImplementation(() => { });
51
+ jest
52
+ .spyOn(BotCredentialsHandler.prototype, 'dump')
53
+ .mockImplementation(() => { });
54
+ jest
55
+ .spyOn(GlobalCredentialsHandler.prototype, 'createDirIfNotExists')
56
+ .mockImplementation(() => { });
57
+ jest
58
+ .spyOn(BotCredentialsHandler.prototype, 'createDirIfNotExists')
59
+ .mockImplementation(() => { });
60
+ });
61
+ afterEach(() => {
62
+ jest.restoreAllMocks();
63
+ });
64
+ describe('Constructor', () => {
65
+ it('should initialize with no credentials', () => {
66
+ service = new BotonicAPIService();
67
+ expect(service.oauth).toBeUndefined();
68
+ expect(service.me).toBeUndefined();
69
+ expect(service.bot).toBeNull();
70
+ expect(service.apiClient).toBeDefined();
71
+ });
72
+ it('should load existing global credentials', () => {
73
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
74
+ oauth: mockOAuth,
75
+ me: mockMe,
76
+ });
77
+ service = new BotonicAPIService();
78
+ expect(service.oauth).toEqual(mockOAuth);
79
+ expect(service.me).toEqual(mockMe);
80
+ });
81
+ it('should load existing bot credentials', () => {
82
+ jest
83
+ .spyOn(BotCredentialsHandler.prototype, 'load')
84
+ .mockReturnValue({ bot: mockBot });
85
+ service = new BotonicAPIService();
86
+ expect(service.bot).toEqual(mockBot);
87
+ });
88
+ it('should set headers with access token', () => {
89
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
90
+ oauth: mockOAuth,
91
+ me: mockMe,
92
+ });
93
+ service = new BotonicAPIService();
94
+ expect(service.headers.get('Authorization')).toContain('Bearer test-access-token');
95
+ });
96
+ });
97
+ describe('botInfo', () => {
98
+ beforeEach(() => {
99
+ jest
100
+ .spyOn(BotCredentialsHandler.prototype, 'load')
101
+ .mockReturnValue({ bot: mockBot });
102
+ service = new BotonicAPIService();
103
+ });
104
+ it('should return bot info when bot exists', () => {
105
+ const result = service.botInfo();
106
+ expect(result).toEqual(mockBot);
107
+ });
108
+ it('should throw error when bot info is not available', () => {
109
+ service.bot = null;
110
+ expect(() => service.botInfo()).toThrow('Not bot info available');
111
+ });
112
+ });
113
+ describe('getOauth', () => {
114
+ beforeEach(() => {
115
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
116
+ oauth: mockOAuth,
117
+ me: mockMe,
118
+ });
119
+ service = new BotonicAPIService();
120
+ });
121
+ it('should return oauth when available', () => {
122
+ const result = service.getOauth();
123
+ expect(result).toEqual(mockOAuth);
124
+ });
125
+ it('should throw error when oauth is not available', () => {
126
+ service.oauth = undefined;
127
+ expect(() => service.getOauth()).toThrow('Not OAuth available');
128
+ });
129
+ });
130
+ describe('beforeExit', () => {
131
+ beforeEach(() => {
132
+ service = new BotonicAPIService();
133
+ });
134
+ it('should save global and bot credentials', () => {
135
+ const globalDumpSpy = jest.spyOn(service.globalCredentialsHandler, 'dump');
136
+ const botDumpSpy = jest.spyOn(service.botCredentialsHandler, 'dump');
137
+ const createDirSpy = jest.spyOn(service.globalCredentialsHandler, 'createDirIfNotExists');
138
+ service.oauth = mockOAuth;
139
+ service.me = mockMe;
140
+ service.bot = mockBot;
141
+ service.beforeExit();
142
+ expect(createDirSpy).toHaveBeenCalled();
143
+ expect(globalDumpSpy).toHaveBeenCalledWith({
144
+ oauth: mockOAuth,
145
+ me: mockMe,
146
+ });
147
+ expect(botDumpSpy).toHaveBeenCalledWith({
148
+ bot: mockBot,
149
+ });
150
+ });
151
+ });
152
+ describe('login', () => {
153
+ beforeEach(() => {
154
+ service = new BotonicAPIService();
155
+ });
156
+ it('should login successfully and set credentials', async () => {
157
+ const postSpy = jest.spyOn(axios, 'post').mockResolvedValueOnce({
158
+ data: mockOAuth,
159
+ status: 200,
160
+ statusText: 'OK',
161
+ headers: {},
162
+ config: {},
163
+ });
164
+ const getSpy = jest
165
+ .spyOn(service.apiClient, 'get')
166
+ .mockResolvedValueOnce({
167
+ data: mockMe,
168
+ status: 200,
169
+ statusText: 'OK',
170
+ headers: {},
171
+ config: {},
172
+ });
173
+ await service.login('test@example.com', 'password123');
174
+ expect(postSpy).toHaveBeenCalledWith(expect.stringContaining('/o/token/'), expect.any(String), expect.objectContaining({
175
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
176
+ }));
177
+ expect(service.oauth).toEqual(mockOAuth);
178
+ expect(service.me).toEqual(mockMe);
179
+ expect(service.headers.get('Authorization')).toContain('Bearer test-access-token');
180
+ });
181
+ });
182
+ describe('signup', () => {
183
+ beforeEach(() => {
184
+ service = new BotonicAPIService();
185
+ });
186
+ it('should call signup endpoint with correct data', async () => {
187
+ const postSpy = jest
188
+ .spyOn(service.apiClient, 'post')
189
+ .mockResolvedValueOnce({
190
+ data: { success: true },
191
+ status: 200,
192
+ statusText: 'OK',
193
+ headers: {},
194
+ config: {},
195
+ });
196
+ await service.signup('test@example.com', 'password123', 'Test Org', {
197
+ source: 'web',
198
+ });
199
+ expect(postSpy).toHaveBeenCalledWith(expect.stringContaining('sign-up/'), {
200
+ email: 'test@example.com',
201
+ password: 'password123',
202
+ org_name: 'Test Org',
203
+ campaign: { source: 'web' },
204
+ }, expect.any(Object));
205
+ });
206
+ });
207
+ describe('createBot', () => {
208
+ beforeEach(() => {
209
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
210
+ oauth: mockOAuth,
211
+ me: mockMe,
212
+ });
213
+ service = new BotonicAPIService();
214
+ });
215
+ it('should create a new bot and set it as current', async () => {
216
+ const postSpy = jest
217
+ .spyOn(service.apiClient, 'post')
218
+ .mockResolvedValueOnce({
219
+ data: mockBot,
220
+ status: 201,
221
+ statusText: 'Created',
222
+ headers: {},
223
+ config: {},
224
+ });
225
+ const result = await service.createBot('new-bot');
226
+ expect(postSpy).toHaveBeenCalledWith(expect.stringContaining('v2/bots/'), { name: 'new-bot' }, expect.any(Object));
227
+ expect(service.bot).toEqual(mockBot);
228
+ expect(result.data).toEqual(mockBot);
229
+ });
230
+ });
231
+ describe('getBots', () => {
232
+ beforeEach(() => {
233
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
234
+ oauth: mockOAuth,
235
+ me: mockMe,
236
+ });
237
+ service = new BotonicAPIService();
238
+ });
239
+ it('should get bots without pagination', async () => {
240
+ const mockResponse = {
241
+ data: {
242
+ count: 2,
243
+ next: null,
244
+ previous: null,
245
+ results: [
246
+ { id: 'bot-1', name: 'Bot 1' },
247
+ { id: 'bot-2', name: 'Bot 2' },
248
+ ],
249
+ },
250
+ status: 200,
251
+ statusText: 'OK',
252
+ headers: {},
253
+ config: {},
254
+ };
255
+ const getSpy = jest
256
+ .spyOn(service.apiClient, 'get')
257
+ .mockResolvedValueOnce(mockResponse);
258
+ const result = await service.getBots();
259
+ expect(result.data.results).toHaveLength(2);
260
+ expect(getSpy).toHaveBeenCalledTimes(1);
261
+ });
262
+ it('should handle paginated bot results', async () => {
263
+ const firstPageResponse = {
264
+ data: {
265
+ count: 150,
266
+ next: 'https://api.hubtype.com/v2/bots/?page=2',
267
+ previous: null,
268
+ results: Array.from({ length: 100 }, (_, i) => ({
269
+ id: `bot-${i}`,
270
+ name: `Bot ${i}`,
271
+ })),
272
+ },
273
+ status: 200,
274
+ statusText: 'OK',
275
+ headers: {},
276
+ config: {},
277
+ };
278
+ const secondPageResponse = {
279
+ data: {
280
+ count: 150,
281
+ next: null,
282
+ previous: 'https://api.hubtype.com/v2/bots/?page=1',
283
+ results: Array.from({ length: 50 }, (_, i) => ({
284
+ id: `bot-${i + 100}`,
285
+ name: `Bot ${i + 100}`,
286
+ })),
287
+ },
288
+ status: 200,
289
+ statusText: 'OK',
290
+ headers: {},
291
+ config: {},
292
+ };
293
+ const getSpy = jest
294
+ .spyOn(service.apiClient, 'get')
295
+ .mockResolvedValueOnce(firstPageResponse)
296
+ .mockResolvedValueOnce(secondPageResponse);
297
+ const result = await service.getBots();
298
+ expect(result.data.results).toHaveLength(150);
299
+ expect(getSpy).toHaveBeenCalledTimes(2);
300
+ });
301
+ });
302
+ describe('setCurrentBot', () => {
303
+ beforeEach(() => {
304
+ service = new BotonicAPIService();
305
+ });
306
+ it('should set current bot', () => {
307
+ service.setCurrentBot(mockBot);
308
+ expect(service.bot).toEqual(mockBot);
309
+ });
310
+ });
311
+ describe('logout', () => {
312
+ beforeEach(() => {
313
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
314
+ oauth: mockOAuth,
315
+ me: mockMe,
316
+ });
317
+ service = new BotonicAPIService();
318
+ });
319
+ it('should call logout and attempt to delete credentials', () => {
320
+ // Just verify the logout method runs without errors
321
+ // File system operations are mocked at the module level
322
+ expect(() => service.logout()).not.toThrow();
323
+ });
324
+ });
325
+ describe('getProviders', () => {
326
+ beforeEach(() => {
327
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
328
+ oauth: mockOAuth,
329
+ me: mockMe,
330
+ });
331
+ jest
332
+ .spyOn(BotCredentialsHandler.prototype, 'load')
333
+ .mockReturnValue({ bot: mockBot });
334
+ service = new BotonicAPIService();
335
+ });
336
+ it('should get providers for current bot', async () => {
337
+ const mockProviders = [
338
+ { id: 'provider-1', name: 'Provider 1' },
339
+ { id: 'provider-2', name: 'Provider 2' },
340
+ ];
341
+ const getSpy = jest
342
+ .spyOn(service.apiClient, 'get')
343
+ .mockResolvedValueOnce({
344
+ data: mockProviders,
345
+ status: 200,
346
+ statusText: 'OK',
347
+ headers: {},
348
+ config: {},
349
+ });
350
+ await service.getProviders();
351
+ expect(getSpy).toHaveBeenCalledWith(expect.stringContaining('provider_accounts/'), expect.objectContaining({
352
+ params: { bot_id: 'bot-123' },
353
+ }));
354
+ });
355
+ });
356
+ describe('deployStatus', () => {
357
+ beforeEach(() => {
358
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
359
+ oauth: mockOAuth,
360
+ me: mockMe,
361
+ });
362
+ jest
363
+ .spyOn(BotCredentialsHandler.prototype, 'load')
364
+ .mockReturnValue({ bot: mockBot });
365
+ service = new BotonicAPIService();
366
+ });
367
+ it('should get deploy status', async () => {
368
+ const mockDeployStatus = { status: 'completed', deploy_id: 'deploy-123' };
369
+ const getSpy = jest
370
+ .spyOn(service.apiClient, 'get')
371
+ .mockResolvedValueOnce({
372
+ data: mockDeployStatus,
373
+ status: 200,
374
+ statusText: 'OK',
375
+ headers: {},
376
+ config: {},
377
+ });
378
+ await service.deployStatus('deploy-123');
379
+ expect(getSpy).toHaveBeenCalledWith(expect.stringContaining(`v2/bots/${mockBot.id}/deploy_status/`), expect.objectContaining({
380
+ params: { deploy_id: 'deploy-123' },
381
+ }));
382
+ });
383
+ });
384
+ describe('refreshToken', () => {
385
+ beforeEach(() => {
386
+ jest.spyOn(GlobalCredentialsHandler.prototype, 'load').mockReturnValue({
387
+ oauth: mockOAuth,
388
+ me: mockMe,
389
+ });
390
+ service = new BotonicAPIService();
391
+ });
392
+ it('should refresh token successfully', async () => {
393
+ const newOAuth = { ...mockOAuth, access_token: 'new-access-token' };
394
+ const postSpy = jest.spyOn(axios, 'post').mockResolvedValueOnce({
395
+ status: 200,
396
+ data: newOAuth,
397
+ statusText: 'OK',
398
+ headers: {},
399
+ config: {},
400
+ });
401
+ const dumpSpy = jest.spyOn(service.globalCredentialsHandler, 'dump');
402
+ // Access private method through any
403
+ await service.refreshToken();
404
+ expect(postSpy).toHaveBeenCalledWith(expect.stringContaining('/o/token/'), expect.any(String), expect.objectContaining({
405
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
406
+ }));
407
+ expect(service.oauth).toEqual(newOAuth);
408
+ expect(service.headers.get('Authorization')).toContain('Bearer new-access-token');
409
+ expect(dumpSpy).toHaveBeenCalled();
410
+ });
411
+ it('should throw error when refresh fails', async () => {
412
+ jest.spyOn(axios, 'post').mockResolvedValueOnce({
413
+ status: 401,
414
+ data: {},
415
+ statusText: 'Unauthorized',
416
+ headers: {},
417
+ config: {},
418
+ });
419
+ await expect(service.refreshToken()).rejects.toThrow('Error refreshing token');
420
+ });
421
+ });
422
+ });
423
+ //# sourceMappingURL=botonic-api-service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"botonic-api-service.test.js","sourceRoot":"","sources":["../../tests/botonic-api-service.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,81 @@
1
+ import { Config } from '@oclif/core';
2
+ import { assert } from 'console';
3
+ import { jest } from '@jest/globals';
4
+ import { join } from 'path';
5
+ import { chdir } from 'process';
6
+ import { BotonicAPIService } from '../../src/botonic-api-service.js';
7
+ import { EXAMPLES } from '../../src/botonic-examples.js';
8
+ import { default as DeployCommand } from '../../src/commands/deploy.js';
9
+ import { default as NewCommand } from '../../src/commands/new.js';
10
+ import { copyRecursively, createTempDir, readDir, removeRecursively, } from '../../src/util/file-system.js';
11
+ const botonicApiService = new BotonicAPIService();
12
+ const newCommand = new NewCommand(process.argv, new Config({ root: '' }));
13
+ const deployCommand = new DeployCommand(process.argv, new Config({ root: '' }));
14
+ const BLANK_EXAMPLE = EXAMPLES[0];
15
+ assert(BLANK_EXAMPLE.name === 'blank');
16
+ function cleanupTempFolders() {
17
+ const currentDir = readDir('.');
18
+ const foldersToClean = currentDir.filter(item => item.startsWith('botonic-tmp') || item === 'tmp');
19
+ foldersToClean.forEach(folder => removeRecursively(folder));
20
+ }
21
+ describe('TEST: Deploy pipeline', () => {
22
+ beforeAll(() => {
23
+ cleanupTempFolders();
24
+ });
25
+ test('Install, build and deploy a project', async () => {
26
+ const tmpPath = createTempDir('botonic-tmp');
27
+ copyRecursively(BLANK_EXAMPLE.localTestPath, tmpPath);
28
+ chdir(tmpPath);
29
+ await newCommand.installDependencies();
30
+ const spyDeployBundle = jest
31
+ .spyOn(deployCommand, 'deployBundle')
32
+ .mockImplementation(async () => {
33
+ return { hasDeployErrors: false };
34
+ });
35
+ const spyDeploy = jest
36
+ .spyOn(deployCommand, 'deploy')
37
+ .mockImplementation(async () => {
38
+ await botonicApiService.build();
39
+ await deployCommand.createBundle();
40
+ const onceBundled = readDir('.');
41
+ expect(onceBundled).toContain('botonic_bundle.zip');
42
+ expect(onceBundled).toContain('tmp');
43
+ const botConfigJson = {
44
+ build_info: {
45
+ node_version: 'v20.0.0',
46
+ npm_version: '10.0.0',
47
+ botonic_cli_version: '0.29.0',
48
+ },
49
+ packages: {
50
+ '@botonic/core': { version: '0.29.0' },
51
+ '@botonic/react': { version: '0.29.0' },
52
+ },
53
+ tools: [
54
+ {
55
+ name: 'tool1',
56
+ description: 'tool1 description',
57
+ },
58
+ ],
59
+ payloads: ['payload1', 'payload2'],
60
+ webviews: [
61
+ {
62
+ name: 'webview1',
63
+ },
64
+ ],
65
+ };
66
+ const { hasDeployErrors } = await deployCommand.deployBundle(botConfigJson);
67
+ expect(hasDeployErrors).toBe(false);
68
+ removeRecursively(join('.', 'botonic_bundle.zip'));
69
+ removeRecursively(join('.', 'tmp'));
70
+ });
71
+ await deployCommand.deploy();
72
+ const onceDeployed = readDir('.');
73
+ expect(onceDeployed).not.toContain('botonic_bundle.zip');
74
+ expect(onceDeployed).not.toContain('tmp');
75
+ chdir('..');
76
+ removeRecursively(tmpPath);
77
+ spyDeployBundle.mockRestore();
78
+ spyDeploy.mockRestore();
79
+ });
80
+ });
81
+ //# sourceMappingURL=deploy.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.test.js","sourceRoot":"","sources":["../../../tests/commands/deploy.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,62 @@
1
+ import { Config } from '@oclif/core';
2
+ import { assert } from 'console';
3
+ import { join } from 'path';
4
+ import { chdir } from 'process';
5
+ import { EXAMPLES } from '../../src/botonic-examples.js';
6
+ import { default as NewCommand } from '../../src/commands/new.js';
7
+ import { copyRecursively, createTempDir, readDir, readJSON, removeRecursively, } from '../../src/util/file-system.js';
8
+ const newCommand = new NewCommand(process.argv, new Config({ root: '' }));
9
+ const BLANK_EXAMPLE = EXAMPLES[0];
10
+ assert(BLANK_EXAMPLE.name === 'blank');
11
+ describe('TEST: New command (resolving project)', () => {
12
+ it('Resolves correctly an existing one (argv)', async () => {
13
+ const botonicProjectName = 'blank';
14
+ const sut = await newCommand.resolveSelectedProject(botonicProjectName);
15
+ expect(sut).toEqual(BLANK_EXAMPLE);
16
+ });
17
+ it('Resolves correctly an unexisting one (argv)', async () => {
18
+ const sut = await newCommand.resolveSelectedProject('unexistingProject');
19
+ expect(sut).toBeUndefined();
20
+ });
21
+ });
22
+ describe('TEST: New command (downloading project)', () => {
23
+ it('Succeeds to download into path', async () => {
24
+ const tmpPath = createTempDir('botonic-tmp');
25
+ await newCommand.downloadSelectedProjectIntoPath(BLANK_EXAMPLE, tmpPath);
26
+ const packageJSON = readJSON(join(tmpPath, 'package.json'));
27
+ expect(packageJSON.name).toEqual(tmpPath);
28
+ removeRecursively(tmpPath);
29
+ });
30
+ it('Fails to download into path', async () => {
31
+ const tmpPath = createTempDir('botonic-tmp');
32
+ await expect(newCommand.downloadSelectedProjectIntoPath({
33
+ name: 'unexistingProject',
34
+ version: '0.0.0',
35
+ description: 'desc',
36
+ localTestPath: 'unexistingLocalPath',
37
+ }, tmpPath)).rejects.toThrow(Error);
38
+ removeRecursively(tmpPath);
39
+ });
40
+ });
41
+ describe('TEST: New command (installing project)', () => {
42
+ it('Succeeds to install', async () => {
43
+ const tmpPath = createTempDir('botonic-tmp');
44
+ // await newCommand.downloadSelectedProjectIntoPath(BLANK_EXAMPLE, tmpPath)
45
+ copyRecursively(BLANK_EXAMPLE.localTestPath, tmpPath);
46
+ chdir(tmpPath);
47
+ await newCommand.installDependencies();
48
+ const sut = readDir('.');
49
+ expect(sut).toContain('node_modules');
50
+ expect(sut).toContain('package-lock.json');
51
+ chdir('..');
52
+ removeRecursively(tmpPath);
53
+ });
54
+ it('Fails to install', async () => {
55
+ const tmpPath = createTempDir('botonic-tmp');
56
+ // await newCommand.downloadSelectedProjectIntoPath(BLANK_EXAMPLE, tmpPath)
57
+ copyRecursively(BLANK_EXAMPLE.localTestPath, tmpPath);
58
+ await expect(newCommand.installDependencies('npm instal-typo')).rejects.toThrow(Error);
59
+ removeRecursively(tmpPath);
60
+ });
61
+ });
62
+ //# sourceMappingURL=new.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.test.js","sourceRoot":"","sources":["../../../tests/commands/new.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};