UNPKG

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