UNPKG

8.84 kBJavaScriptView Raw
1var assert = require('assert');
2var sinon = require('sinon');
3var shortid = require('shortid');
4var _ = require('lodash');
5var path = require('path');
6var fs = require('fs');
7var request = require('request');
8var inquirer = require('inquirer');
9var log = require('../lib/log');
10var cliInit = require('../lib/cli-init');
11var os = require('os');
12
13require('dash-assert');
14
15describe('cliInit', function() {
16 before(function() {
17 sinon.stub(log, 'write', _.noop());
18 });
19
20 after(function() {
21 log.write.restore();
22 });
23
24 beforeEach(function() {
25 this.user = {
26 userId: shortid.generate(),
27 jwt: {
28 token: 'adfasdfasdfasdf',
29 expires: Date.now() + (1000 * 60 * 30)
30 }
31 };
32
33 this.mockAnswers = {
34 endpoint: 'https://apphost.com',
35 username: 'username',
36 password: 'password',
37 identityProvider: 'ActiveDirectory'
38 };
39
40 this.mockInquirer = require('./mock-inquirer')(this.mockAnswers);
41
42 sinon.stub(request, 'post').yields(null, {statusCode: 200}, this.user);
43
44 sinon.stub(request, 'get', function(options, callback) {
45 if (options.path.indexOf('/apps/') === 0) {
46 callback(null, {statusCode: 200}, {
47 appId: _.last(options.path.split('/'))
48 });
49 } else {
50 callback(new Error('Unexpected get request ' + options.url));
51 }
52 });
53
54 sinon.stub(inquirer, 'prompt', this.mockInquirer.prompt);
55 sinon.stub();
56
57 this.commandOptions = {
58 loadVirtualApp: false,
59 loadManifest: false,
60 requireAuth: true
61 };
62
63 this.program = {
64 globalConfigPath: path.join(os.tmpdir(), '.4front.json')
65 };
66 });
67
68 afterEach(function(done) {
69 request.post.restore();
70 request.get.restore();
71 inquirer.prompt.restore();
72
73 fs.unlink(this.program.globalConfigPath, function() {
74 done();
75 });
76 });
77
78 it('missing global config file', function(done) {
79 var self = this;
80
81 cliInit(this.program, this.commandOptions, function(err) {
82 if (err) return done(err);
83
84 assert.isTrue(self.mockInquirer.wasAsked('endpoint'));
85 assert.isTrue(self.mockInquirer.wasAsked('identityProvider'));
86 assert.isTrue(self.mockInquirer.wasAsked('username'));
87 assert.isTrue(self.mockInquirer.wasAsked('password'));
88
89 assert.equal(self.program.profile.endpoint, self.mockAnswers.endpoint);
90
91 assert.isMatch(request.post.args[0][0], {
92 method: 'POST',
93 json: {
94 username: 'username',
95 password: 'password'
96 },
97 path: '/profile/login'
98 });
99
100 var globalConfig = JSON.parse(fs.readFileSync(self.program.globalConfigPath).toString());
101
102 assert.deepEqual(globalConfig.profiles[0], {
103 endpoint: self.mockAnswers.endpoint,
104 name: 'default',
105 default: true,
106 jwt: self.user.jwt,
107 identityProvider: self.mockAnswers.identityProvider
108 });
109
110 done();
111 });
112 });
113
114 it('corrupt global config file', function(done) {
115 var self = this;
116 fs.writeFileSync(this.program.globalConfigPath, 'invalid json');
117
118 cliInit(this.program, this.commandOptions, function(err) {
119 if (err) return done(err);
120
121 assert.isTrue(self.mockInquirer.wasAsked('endpoint'));
122 assert.isTrue(self.mockInquirer.wasAsked('identityProvider'));
123 assert.isTrue(self.mockInquirer.wasAsked('username'));
124 assert.isTrue(self.mockInquirer.wasAsked('password'));
125 assert.isTrue(request.post.called);
126 done();
127 });
128 });
129
130 it('uses the specified profile', function(done) {
131 var self = this;
132 fs.writeFileSync(this.program.globalConfigPath, JSON.stringify({
133 profiles: [{
134 name: 'host1',
135 endpoint: 'https://host1.com',
136 }, {
137 name: 'host2',
138 endpoint: 'https://host2.com',
139 identityProvider: 'BitBucket'
140 }]
141 }, null, 2));
142
143 this.program.profile = 'host2';
144 cliInit(this.program, this.commandOptions, function(err) {
145 if (err) return done(err);
146
147 assert.equal(self.program.profile.endpoint, 'https://host2.com');
148
149 assert.isTrue(request.post.calledWith(sinon.match({
150 json: {
151 username: self.mockAnswers.username,
152 password: self.mockAnswers.password,
153 identityProvider: 'BitBucket'
154 }
155 })));
156
157 done();
158 });
159 });
160
161 it('default profile is used if none specified', function(done) {
162 var self = this;
163 fs.writeFileSync(this.program.globalConfigPath, JSON.stringify({
164 profiles: [{
165 name: 'host1',
166 endpoint: 'https://host1.com'
167 }, {
168 name: 'host2',
169 endpoint: 'https://host2.com',
170 default: true
171 }]
172 }, null, 2));
173
174 cliInit(this.program, this.commandOptions, function(err) {
175 if (err) return done(err);
176 assert.equal(self.program.profile.endpoint, 'https://host2.com');
177
178 done();
179 });
180 });
181
182 it('first profile used as fallback', function(done) {
183 var self = this;
184 fs.writeFileSync(this.program.globalConfigPath, JSON.stringify({
185 profiles: [{
186 name: 'host1',
187 endpoint: 'https://host1.com'
188 }, {
189 name: 'host2',
190 endpoint: 'https://host2.com'
191 }]
192 }, null, 2));
193
194 cliInit(this.program, this.commandOptions, function(err) {
195 if (err) return done(err);
196 assert.equal(self.program.profile.endpoint, 'https://host1.com');
197
198 done();
199 });
200 });
201
202 it('expired token still requires user to login', function(done) {
203 var self = this;
204 // Write config file with an expired jwt
205 fs.writeFileSync(this.program.globalConfigPath, JSON.stringify({
206 profiles: [{
207 endpoint: 'https://host1.com',
208 jwt: _.extend(this.jwt, {
209 expires: Date.now() - 1000
210 })
211 }]
212 }, null, 2));
213
214 cliInit(this.program, this.commandOptions, function(err) {
215 if (err) return done(err);
216
217 // login api should still be called
218 assert.isTrue(self.mockInquirer.wasAsked('username'));
219 assert.isTrue(self.mockInquirer.wasAsked('password'));
220 assert.isTrue(request.post.called);
221
222 done();
223 });
224 });
225
226 it('valid token skips login', function(done) {
227 var self = this;
228 _.extend(this.user.jwt, {
229 expires: Date.now() + (1000 * 60)
230 });
231
232 fs.writeFileSync(this.program.globalConfigPath, JSON.stringify({
233 profiles: [{
234 endpoint: 'https://host1.com',
235 jwt: self.user.jwt
236 }]
237 }, null, 2));
238
239 cliInit(this.program, this.commandOptions, function(err) {
240 if (err) return done(err);
241
242 // login api should still be called
243 assert.isFalse(self.mockInquirer.wasAsked('username'));
244 assert.isFalse(self.mockInquirer.wasAsked('password'));
245 assert.isFalse(request.post.called);
246 assert.deepEqual(self.program.profile.jwt, self.user.jwt);
247
248 done();
249 });
250 });
251
252 describe('load virtual app', function() {
253 var self;
254
255 beforeEach(function(done) {
256 self = this;
257 writeValidGlobalConfig(this);
258
259 this.appId = shortid.generate();
260
261 this.tmpAppDir = path.join(os.tmpdir(), this.appId);
262
263 // Write a valid package.json in the app directory
264 fs.mkdir(this.tmpAppDir, function() {
265 var packageJson = {
266 _virtualApp: {
267 appId: self.appId
268 }
269 };
270
271 fs.writeFileSync(path.join(self.tmpAppDir, 'package.json'), JSON.stringify(packageJson));
272 done();
273 });
274
275 this.program.cwd = this.tmpAppDir;
276 _.extend(this.commandOptions, {
277 loadVirtualApp: true,
278 loadManifest: true
279 });
280 });
281
282 afterEach(function(done) {
283 fs.unlink(this.tmpAppDir, function() {
284 done();
285 });
286 });
287
288 it('loads virtualAppManifest and virtualApp', function(done) {
289 cliInit(this.program, this.commandOptions, function(err) {
290 if (err) return done(err);
291
292 assert.isTrue(request.get.calledWith(sinon.match({path: '/apps/' + self.appId})));
293 assert.equal(self.program.virtualAppManifest.appId, self.appId);
294 assert.equal(self.program.virtualApp.appId, self.appId);
295
296 done();
297 });
298 });
299
300 it('allows appId to be overridden', function(done) {
301 this.program.appId = shortid.generate();
302
303 cliInit(this.program, this.commandOptions, function(err) {
304 if (err) return done(err);
305
306 assert.isTrue(request.get.calledWith(sinon.match({path: '/apps/' + self.program.appId})));
307 assert.equal(self.program.virtualAppManifest.appId, self.program.appId);
308 assert.equal(self.program.virtualApp.appId, self.program.appId);
309
310 done();
311 });
312 });
313 });
314
315 function writeValidGlobalConfig(self) {
316 fs.writeFileSync(self.program.globalConfigPath, JSON.stringify({
317 profiles: [{
318 endpoint: 'https://host1.com',
319 jwt: self.user.jwt
320 }]
321 }, null, 2));
322 }
323});