How to use d.createSession method in Appium Base Driver

Best JavaScript code snippet using appium-base-driver

Run Appium Base Driver automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

driver-specs.js

Source: driver-specs.js Github

copy
1// transpile:mocha
2
3import { AppiumDriver } from '../lib/appium';
4import { FakeDriver } from 'appium-fake-driver';
5import { BASE_CAPS, W3C_CAPS } from './helpers';
6import _ from 'lodash';
7import sinon from 'sinon';
8import chai from 'chai';
9import chaiAsPromised from 'chai-as-promised';
10import { XCUITestDriver } from 'appium-xcuitest-driver';
11import { IosDriver } from 'appium-ios-driver';
12import { AndroidUiautomator2Driver } from 'appium-uiautomator2-driver';
13import { sleep } from 'asyncbox';
14import { insertAppiumPrefixes } from '../lib/utils';
15
16chai.should();
17chai.use(chaiAsPromised);
18
19const SESSION_ID = 1;
20
21describe('AppiumDriver', function () {
22  describe('AppiumDriver', function () {
23    function getDriverAndFakeDriver () {
24      const appium = new AppiumDriver({});
25      const fakeDriver = new FakeDriver();
26      const mockFakeDriver = sinon.mock(fakeDriver);
27      appium.getDriverAndVersionForCaps = function (/*args*/) {
28        return {
29          driver: function Driver () {
30            return fakeDriver;
31          },
32          version: '1.2.3',
33        };
34      };
35      return [appium, mockFakeDriver];
36    }
37    describe('createSession', function () {
38      let appium;
39      let mockFakeDriver;
40      beforeEach(function () {
41        [appium, mockFakeDriver] = getDriverAndFakeDriver();
42      });
43      afterEach(async function () {
44        mockFakeDriver.restore();
45        await appium.deleteSession(SESSION_ID);
46      });
47
48      it(`should call inner driver's createSession with desired capabilities`, async function () {
49        mockFakeDriver.expects('createSession')
50          .once().withExactArgs(BASE_CAPS, undefined, null, [])
51          .returns([SESSION_ID, BASE_CAPS]);
52        await appium.createSession(BASE_CAPS);
53        mockFakeDriver.verify();
54      });
55      it(`should call inner driver's createSession with desired and default capabilities`, async function () {
56        let defaultCaps = {deviceName: 'Emulator'};
57        let allCaps = _.extend(_.clone(defaultCaps), BASE_CAPS);
58        appium.args.defaultCapabilities = defaultCaps;
59        mockFakeDriver.expects('createSession')
60          .once().withArgs(allCaps)
61          .returns([SESSION_ID, allCaps]);
62        await appium.createSession(BASE_CAPS);
63        mockFakeDriver.verify();
64      });
65      it(`should call inner driver's createSession with desired and default capabilities without overriding caps`, async function () {
66        // a default capability with the same key as a desired capability
67        // should do nothing
68        let defaultCaps = {platformName: 'Ersatz'};
69        appium.args.defaultCapabilities = defaultCaps;
70        mockFakeDriver.expects('createSession')
71          .once().withArgs(BASE_CAPS)
72          .returns([SESSION_ID, BASE_CAPS]);
73        await appium.createSession(BASE_CAPS);
74        mockFakeDriver.verify();
75      });
76      it('should kill all other sessions if sessionOverride is on', async function () {
77        appium.args.sessionOverride = true;
78
79        // mock three sessions that should be removed when the new one is created
80        let fakeDrivers = [
81          new FakeDriver(),
82          new FakeDriver(),
83          new FakeDriver(),
84        ];
85        let mockFakeDrivers = _.map(fakeDrivers, (fd) => sinon.mock(fd));
86        mockFakeDrivers[0].expects('deleteSession')
87          .once();
88        mockFakeDrivers[1].expects('deleteSession')
89          .once()
90          .throws('Cannot shut down Android driver; it has already shut down');
91        mockFakeDrivers[2].expects('deleteSession')
92          .once();
93        appium.sessions['abc-123-xyz'] = fakeDrivers[0];
94        appium.sessions['xyz-321-abc'] = fakeDrivers[1];
95        appium.sessions['123-abc-xyz'] = fakeDrivers[2];
96
97        let sessions = await appium.getSessions();
98        sessions.should.have.length(3);
99
100        mockFakeDriver.expects('createSession')
101          .once().withExactArgs(BASE_CAPS, undefined, null, [])
102          .returns([SESSION_ID, BASE_CAPS]);
103        await appium.createSession(BASE_CAPS);
104
105        sessions = await appium.getSessions();
106        sessions.should.have.length(1);
107
108        for (let mfd of mockFakeDrivers) {
109          mfd.verify();
110        }
111        mockFakeDriver.verify();
112      });
113      it('should call "createSession" with W3C capabilities argument, if provided', async function () {
114        mockFakeDriver.expects('createSession')
115          .once().withArgs(null, undefined, W3C_CAPS)
116          .returns([SESSION_ID, BASE_CAPS]);
117        await appium.createSession(undefined, undefined, W3C_CAPS);
118        mockFakeDriver.verify();
119      });
120      it('should call "createSession" with W3C capabilities argument with additional provided parameters', async function () {
121        let w3cCaps = {
122          ...W3C_CAPS,
123          alwaysMatch: {
124            ...W3C_CAPS.alwaysMatch,
125            'appium:someOtherParm': 'someOtherParm',
126          },
127        };
128        mockFakeDriver.expects('createSession')
129          .once().withArgs(null, undefined, {
130            alwaysMatch: {
131              ...w3cCaps.alwaysMatch,
132              'appium:someOtherParm': 'someOtherParm',
133            },
134            firstMatch: [{}],
135          })
136          .returns([SESSION_ID, insertAppiumPrefixes(BASE_CAPS)]);
137
138        await appium.createSession(undefined, undefined, w3cCaps);
139        mockFakeDriver.verify();
140      });
141      it('should call "createSession" with JSONWP capabilities if W3C has incomplete capabilities', async function () {
142        let w3cCaps = {
143          ...W3C_CAPS,
144          alwaysMatch: {
145            ...W3C_CAPS.alwaysMatch,
146            'appium:someOtherParm': 'someOtherParm',
147          },
148        };
149
150        let jsonwpCaps = {
151          ...BASE_CAPS,
152          automationName: 'Fake',
153          someOtherParam: 'someOtherParam',
154        };
155
156        let expectedW3cCaps = {
157          ...w3cCaps,
158          alwaysMatch: {
159            ...w3cCaps.alwaysMatch,
160            'appium:automationName': 'Fake',
161            'appium:someOtherParam': 'someOtherParam',
162          },
163        };
164
165        mockFakeDriver.expects('createSession')
166          .once().withArgs(jsonwpCaps, undefined, expectedW3cCaps)
167          .returns([SESSION_ID, jsonwpCaps]);
168
169        await appium.createSession(jsonwpCaps, undefined, w3cCaps);
170        mockFakeDriver.verify();
171      });
172    });
173    describe('deleteSession', function () {
174      let appium;
175      let mockFakeDriver;
176      beforeEach(function () {
177        [appium, mockFakeDriver] = getDriverAndFakeDriver();
178      });
179      afterEach(function () {
180        mockFakeDriver.restore();
181      });
182      it('should remove the session if it is found', async function () {
183        let [sessionId] = (await appium.createSession(BASE_CAPS)).value;
184        let sessions = await appium.getSessions();
185        sessions.should.have.length(1);
186        await appium.deleteSession(sessionId);
187        sessions = await appium.getSessions();
188        sessions.should.have.length(0);
189      });
190      it('should call inner driver\'s deleteSession method', async function () {
191        const [sessionId] = (await appium.createSession(BASE_CAPS)).value;
192        mockFakeDriver.expects('deleteSession')
193          .once().withExactArgs(sessionId, [])
194          .returns();
195        await appium.deleteSession(sessionId);
196        mockFakeDriver.verify();
197
198        // cleanup, since we faked the delete session call
199        await mockFakeDriver.object.deleteSession();
200      });
201    });
202    describe('getSessions', function () {
203      let appium;
204      let sessions;
205      before(function () {
206        appium = new AppiumDriver({});
207      });
208      afterEach(async function () {
209        for (let session of sessions) {
210          await appium.deleteSession(session.id);
211        }
212      });
213      it('should return an empty array of sessions', async function () {
214        sessions = await appium.getSessions();
215        sessions.should.be.an('array');
216        sessions.should.be.empty;
217      });
218      it('should return sessions created', async function () {
219        let session1 = (await appium.createSession(_.extend(_.clone(BASE_CAPS), {cap: 'value'}))).value;
220        let session2 = (await appium.createSession(_.extend(_.clone(BASE_CAPS), {cap: 'other value'}))).value;
221
222        sessions = await appium.getSessions();
223        sessions.should.be.an('array');
224        sessions.should.have.length(2);
225        sessions[0].id.should.equal(session1[0]);
226        sessions[0].capabilities.should.eql(session1[1]);
227        sessions[1].id.should.equal(session2[0]);
228        sessions[1].capabilities.should.eql(session2[1]);
229      });
230    });
231    describe('getStatus', function () {
232      let appium;
233      before(function () {
234        appium = new AppiumDriver({});
235      });
236      it('should return a status', async function () {
237        let status = await appium.getStatus();
238        status.build.should.exist;
239        status.build.version.should.exist;
240      });
241    });
242    describe('sessionExists', function () {
243    });
244    describe('attachUnexpectedShutdownHandler', function () {
245      let appium;
246      let mockFakeDriver;
247      beforeEach(function () {
248        [appium, mockFakeDriver] = getDriverAndFakeDriver();
249      });
250      afterEach(async function () {
251        await mockFakeDriver.object.deleteSession();
252        mockFakeDriver.restore();
253        appium.args.defaultCapabilities = {};
254      });
255
256      it('should remove session if inner driver unexpectedly exits with an error', async function () {
257        let [sessionId,] = (await appium.createSession(_.clone(BASE_CAPS))).value; // eslint-disable-line comma-spacing
258        _.keys(appium.sessions).should.contain(sessionId);
259        appium.sessions[sessionId].eventEmitter.emit('onUnexpectedShutdown', new Error('Oops'));
260        // let event loop spin so rejection is handled
261        await sleep(1);
262        _.keys(appium.sessions).should.not.contain(sessionId);
263      });
264      it('should remove session if inner driver unexpectedly exits with no error', async function () {
265        let [sessionId,] = (await appium.createSession(_.clone(BASE_CAPS))).value; // eslint-disable-line comma-spacing
266        _.keys(appium.sessions).should.contain(sessionId);
267        appium.sessions[sessionId].eventEmitter.emit('onUnexpectedShutdown');
268        // let event loop spin so rejection is handled
269        await sleep(1);
270        _.keys(appium.sessions).should.not.contain(sessionId);
271      });
272    });
273    describe('getDriverAndVersionForCaps', function () {
274      it('should not blow up if user does not provide platformName', function () {
275        const appium = new AppiumDriver({});
276        (() => { appium.getDriverAndVersionForCaps({}); }).should.throw(/platformName/);
277      });
278      it('should ignore automationName Appium', function () {
279        const appium = new AppiumDriver({});
280        const {driver} = appium.getDriverAndVersionForCaps({
281          platformName: 'Android',
282          automationName: 'Appium'
283        });
284        driver.should.be.an.instanceof(Function);
285        driver.should.equal(AndroidUiautomator2Driver);
286      });
287      it('should get XCUITestDriver driver for automationName of XCUITest', function () {
288        const appium = new AppiumDriver({});
289        const {driver} = appium.getDriverAndVersionForCaps({
290          platformName: 'iOS',
291          automationName: 'XCUITest'
292        });
293        driver.should.be.an.instanceof(Function);
294        driver.should.equal(XCUITestDriver);
295      });
296      it('should get iosdriver for ios < 10', function () {
297        const appium = new AppiumDriver({});
298        const caps = {
299          platformName: 'iOS',
300          platformVersion: '8.0',
301        };
302        let {driver} = appium.getDriverAndVersionForCaps(caps);
303        driver.should.be.an.instanceof(Function);
304        driver.should.equal(IosDriver);
305
306        caps.platformVersion = '8.1';
307        ({driver} = appium.getDriverAndVersionForCaps(caps));
308        driver.should.equal(IosDriver);
309
310        caps.platformVersion = '9.4';
311        ({driver} = appium.getDriverAndVersionForCaps(caps));
312        driver.should.equal(IosDriver);
313
314        caps.platformVersion = '';
315        ({driver} = appium.getDriverAndVersionForCaps(caps));
316        driver.should.equal(IosDriver);
317
318        caps.platformVersion = 'foo';
319        ({driver} = appium.getDriverAndVersionForCaps(caps));
320        driver.should.equal(IosDriver);
321
322        delete caps.platformVersion;
323        ({driver} = appium.getDriverAndVersionForCaps(caps));
324        driver.should.equal(IosDriver);
325      });
326      it('should get xcuitestdriver for ios >= 10', function () {
327        const appium = new AppiumDriver({});
328        const caps = {
329          platformName: 'iOS',
330          platformVersion: '10',
331        };
332        let {driver} = appium.getDriverAndVersionForCaps(caps);
333        driver.should.be.an.instanceof(Function);
334        driver.should.equal(XCUITestDriver);
335
336        caps.platformVersion = '10.0';
337        ({driver} = appium.getDriverAndVersionForCaps(caps));
338        driver.should.equal(XCUITestDriver);
339
340        caps.platformVersion = '10.1';
341        ({driver} = appium.getDriverAndVersionForCaps(caps));
342        driver.should.equal(XCUITestDriver);
343
344        caps.platformVersion = '12.14';
345        ({driver} = appium.getDriverAndVersionForCaps(caps));
346        driver.should.equal(XCUITestDriver);
347      });
348      it('should be able to handle different cases in automationName', function () {
349        const appium = new AppiumDriver({});
350        const caps = {
351          platformName: 'iOS',
352          platformVersion: '10',
353          automationName: 'XcUiTeSt',
354        };
355        let {driver} = appium.getDriverAndVersionForCaps(caps);
356        driver.should.be.an.instanceof(Function);
357        driver.should.equal(XCUITestDriver);
358      });
359      it('should be able to handle different case in platformName', function () {
360        const appium = new AppiumDriver({});
361        const caps = {
362          platformName: 'IoS',
363          platformVersion: '10',
364        };
365        let {driver} = appium.getDriverAndVersionForCaps(caps);
366        driver.should.be.an.instanceof(Function);
367        driver.should.equal(XCUITestDriver);
368      });
369    });
370  });
371});
372
Full Screen

capability-specs.js

Source: capability-specs.js Github

copy
1import { default as BaseDriver, errors } from '../..';
2import chai from 'chai';
3import chaiAsPromised from 'chai-as-promised';
4import logger from '../../lib/basedriver/logger';
5import sinon from 'sinon';
6
7const should = chai.should();
8chai.use(chaiAsPromised);
9
10describe('Desired Capabilities', function () {
11  let d;
12
13  beforeEach(function () {
14    d = new BaseDriver();
15    sinon.spy(logger, 'warn');
16  });
17
18  afterEach(function () {
19    logger.warn.restore();
20  });
21
22  it('should require platformName and deviceName', async function () {
23    try {
24      await d.createSession({});
25    } catch (e) {
26      e.should.be.instanceof(errors.SessionNotCreatedError);
27      e.message.should.contain('platformName');
28      return;
29    }
30
31    should.fail('error should have been thrown');
32  });
33
34
35  it('should require platformName', async function () {
36    try {
37      await d.createSession({'deviceName': 'Delorean'});
38    } catch (e) {
39      e.should.be.instanceof(errors.SessionNotCreatedError);
40      e.message.should.contain('platformName');
41      return;
42    }
43
44    should.fail('error should have been thrown');
45  });
46
47  it('should not care about cap order', async function () {
48
49    await d.createSession({
50      deviceName: 'Delorean',
51      platformName: 'iOS'
52    });
53
54  });
55
56  it('should check required caps which are added to driver', async function () {
57    d.desiredCapConstraints = {
58      necessary: {
59        presence: true
60      },
61      proper: {
62        presence: true,
63        isString: true,
64        inclusion: ['Delorean', 'Reventon']
65      }
66    };
67
68    try {
69      await d.createSession({
70        'platformName': 'iOS',
71        'deviceName': 'Delorean'
72      });
73    } catch (e) {
74      e.should.be.instanceof(errors.SessionNotCreatedError);
75      e.message.should.contain('necessary');
76      e.message.should.contain('proper');
77      return;
78    }
79
80    should.fail('error should have been thrown');
81  });
82
83  it('should check added required caps in addition to base', async function () {
84    d.desiredCapConstraints = {
85      necessary: {
86        presence: true
87      },
88      proper: {
89        presence: true,
90        isString: true,
91        inclusion: ['Delorean', 'Reventon']
92      }
93    };
94
95    try {
96      await d.createSession({
97        necessary: 'yup',
98        proper: 'yup, your highness'
99      });
100    } catch (e) {
101      e.should.be.instanceof(errors.SessionNotCreatedError);
102      e.message.should.contain('platformName');
103      return;
104    }
105
106    should.fail('error should have been thrown');
107  });
108
109  it('should accept extra capabilities', async function () {
110    await d.createSession({
111      'platformName': 'iOS',
112      'deviceName': 'Delorean',
113      'extra': 'cheese',
114      'hold the': 'sauce'
115    });
116  });
117
118  it('should log the use of extra caps', async function () {
119    this.timeout(500);
120
121    await d.createSession({
122      'platformName': 'iOS',
123      'deviceName': 'Delorean',
124      'extra': 'cheese',
125      'hold the': 'sauce'
126    });
127
128    logger.warn.callCount.should.be.above(0);
129  });
130
131  it('should be sensitive to the case of caps', async function () {
132    try {
133      await d.createSession({
134        'platformname': 'iOS',
135        'deviceName': 'Delorean'
136      });
137    } catch (e) {
138      e.should.be.instanceof(errors.SessionNotCreatedError);
139      e.message.should.contain('platformName');
140      return;
141    }
142
143    should.fail('error should have been thrown');
144  });
145
146  describe('boolean capabilities', function () {
147    it('should allow a string "false"', async function () {
148      await d.createSession({
149        'platformName': 'iOS',
150        'deviceName': 'Delorean',
151        'noReset': 'false'
152      });
153      logger.warn.callCount.should.be.above(0);
154
155      let sessions = await d.getSessions();
156      sessions[0].capabilities.noReset.should.eql(false);
157    });
158
159    it('should allow a string "true"', async function () {
160      await d.createSession({
161        'platformName': 'iOS',
162        'deviceName': 'Delorean',
163        'noReset': 'true'
164      });
165      logger.warn.callCount.should.be.above(0);
166
167      let sessions = await d.getSessions();
168      sessions[0].capabilities.noReset.should.eql(true);
169    });
170
171    it('should allow a string "true" in string capabilities', async function () {
172      await d.createSession({
173        'platformName': 'iOS',
174        'deviceName': 'Delorean',
175        'language': 'true'
176      });
177      logger.warn.callCount.should.equal(0);
178
179      let sessions = await d.getSessions();
180      sessions[0].capabilities.language.should.eql('true');
181    });
182  });
183
184  describe('number capabilities', function () {
185    it('should allow a string "1"', async function () {
186      await d.createSession({
187        'platformName': 'iOS',
188        'deviceName': 'Delorean',
189        'newCommandTimeout': '1'
190      });
191      logger.warn.callCount.should.be.above(0);
192
193      let sessions = await d.getSessions();
194      sessions[0].capabilities.newCommandTimeout.should.eql(1);
195    });
196
197    it('should allow a string "1.1"', async function () {
198      await d.createSession({
199        'platformName': 'iOS',
200        'deviceName': 'Delorean',
201        'newCommandTimeout': '1.1'
202      });
203      logger.warn.callCount.should.be.above(0);
204
205      let sessions = await d.getSessions();
206      sessions[0].capabilities.newCommandTimeout.should.eql(1.1);
207    });
208
209    it('should allow a string "1" in string capabilities', async function () {
210      await d.createSession({
211        'platformName': 'iOS',
212        'deviceName': 'Delorean',
213        'language': '1'
214      });
215      logger.warn.callCount.should.equal(0);
216
217      let sessions = await d.getSessions();
218      sessions[0].capabilities.language.should.eql('1');
219    });
220  });
221
222  it ('should error if objects in caps', async function () {
223    try {
224      await d.createSession({
225        'platformName': {a: 'iOS'},
226        'deviceName': 'Delorean'
227      });
228    } catch (e) {
229      e.should.be.instanceof(errors.SessionNotCreatedError);
230      e.message.should.contain('platformName');
231      return;
232    }
233
234    should.fail('error should have been thrown');
235  });
236
237  it('should check for deprecated caps', async function () {
238    this.timeout(500);
239
240    d.desiredCapConstraints = {
241      'lynx-version': {
242        deprecated: true
243      }
244    };
245
246    await d.createSession({
247      'platformName': 'iOS',
248      'deviceName': 'Delorean',
249      'lynx-version': 5
250    });
251
252    logger.warn.callCount.should.be.above(0);
253  });
254
255  it('should not warn if deprecated=false', async function () {
256    this.timeout(500);
257
258    d.desiredCapConstraints = {
259      'lynx-version': {
260        deprecated: false
261      }
262    };
263
264    await d.createSession({
265      'platformName': 'iOS',
266      'deviceName': 'Delorean',
267      'lynx-version': 5
268    });
269
270    logger.warn.callCount.should.equal(0);
271  });
272
273  it('should not validate against null/undefined caps', async function () {
274    d.desiredCapConstraints = {
275      'foo': {
276        isString: true
277      }
278    };
279
280    await d.createSession({
281      platformName: 'iOS',
282      deviceName: 'Dumb',
283      foo: null
284    });
285    await d.deleteSession();
286
287    await d.createSession({
288      platformName: 'iOS',
289      deviceName: 'Dumb',
290      foo: 1
291    }).should.eventually.be.rejectedWith(/was not valid/);
292
293    await d.createSession({
294      platformName: 'iOS',
295      deviceName: 'Dumb',
296      foo: undefined
297    });
298    await d.deleteSession();
299
300    await d.createSession({
301      platformName: 'iOS',
302      deviceName: 'Dumb',
303      foo: ''
304    });
305    await d.deleteSession();
306  });
307
308  it('should still validate null/undefined/empty caps whose presence is required', async function () {
309    d.desiredCapConstraints = {
310      foo: {
311        presence: true
312      },
313    };
314
315    await d.createSession({
316      platformName: 'iOS',
317      deviceName: 'Dumb',
318      foo: null
319    }).should.eventually.be.rejectedWith(/blank/);
320
321    await d.createSession({
322      platformName: 'iOS',
323      deviceName: 'Dumb',
324      foo: ''
325    }).should.eventually.be.rejectedWith(/blank/);
326
327    await d.createSession({
328      platformName: 'iOS',
329      deviceName: 'Dumb',
330      foo: {}
331    }).should.eventually.be.rejectedWith(/blank/);
332
333    await d.createSession({
334      platformName: 'iOS',
335      deviceName: 'Dumb',
336      foo: []
337    }).should.eventually.be.rejectedWith(/blank/);
338
339    await d.createSession({
340      platformName: 'iOS',
341      deviceName: 'Dumb',
342      foo: '  '
343    }).should.eventually.be.rejectedWith(/blank/);
344  });
345
346  describe('w3c', function () {
347    it('should accept w3c capabilities', async function () {
348      const [sessionId, caps] = await d.createSession(null, null, {
349        alwaysMatch: {
350          platformName: 'iOS',
351          deviceName: 'Delorean'
352        }, firstMatch: [{}],
353      });
354      sessionId.should.exist;
355      caps.should.eql({
356        platformName: 'iOS',
357        deviceName: 'Delorean',
358      });
359      await d.deleteSession();
360    });
361
362    it('should ignore w3c capabilities if it is not a plain JSON object', async function () {
363      for (let val of [true, 'string', [], 100]) {
364        const [sessionId, caps] = await d.createSession({
365          platformName: 'iOS',
366          deviceName: 'Delorean'
367        }, null, val);
368        sessionId.should.exist;
369        caps.should.eql({
370          platformName: 'iOS',
371          deviceName: 'Delorean',
372        });
373        await d.deleteSession();
374      }
375    });
376  });
377});
378
Full Screen

index.js

Source: index.js Github

copy
1var assert  = require("assert");
2var sinon   = require("sinon");
3var path    = require("path");
4var fs      = require("fs");
5
6var connector;
7var Connector;
8
9var noop = function () {};
10
11describe("index.js", function () {
12    var winston = {
13        clear: sinon.stub(),
14        add: sinon.stub(),
15        info: sinon.stub(),
16        debug: sinon.stub(),
17        warn: sinon.stub(),
18        error: sinon.stub(),
19        verbose: sinon.stub(),
20        transports: { Console: {} }
21    };
22
23    beforeEach(function () {
24        winston.clear.reset();
25        winston.add.reset();
26        winston.info.reset();
27        winston.debug.reset();
28        winston.warn.reset();
29        winston.error.reset();
30        winston.verbose.reset();
31    });
32
33    describe("class", function () {
34        describe("before module was initialied", function () {
35            it("should fail", function () {
36                try {
37                    require.uncache("../index.js");
38                    connector   = require("../index.js");
39                    Connector   = connector.Connector;
40                    new Connector();
41                    assert.fail("should not reach here!");
42                } catch (e) {
43                    assert.ok(e instanceof Error);
44                    assert.equal(e.message, "'kido-connector' was not initialized.");
45                }
46            });
47        });
48
49        describe("after module was initialized.", function () {
50            var createSession  = sinon.stub();
51            var refreshSession = sinon.stub();
52            var disposeSession = sinon.stub();
53            var opts;
54
55            before(function () {
56                require.uncache("../index.js");
57                connector   = require("../index.js");
58                Connector   = connector.Connector;
59                connector.init("test", winston);
60
61            });
62
63            beforeEach(function () {
64                createSession.reset();
65                refreshSession.reset();
66                disposeSession.reset();
67                opts = {
68                };
69            });
70
71            describe("constructor", function () {
72                it("should fail on invalid opts", function () {
73
74                    [
75                        0,
76                        "",
77                        "foo",
78                        true,
79                        []
80                    ].forEach(function (opts) {
81                        try {
82                            new Connector(opts);
83                            assert.fail("should not reach here!");
84                        } catch (e) {
85                            assert.ok(e instanceof Error);
86                            assert.equal(e.message, "'opts' argument must be an object instance.");
87                        }
88                    });
89                });
90
91                it("should fail on invalid opts.config.", function () {
92
93                    [
94                        10,
95                        "foo",
96                        false,
97                        true,
98                        []
99                    ]
100                        .forEach(function (config) {
101                            try {
102                                opts.config = config;
103                                new Connector(opts);
104                                assert.fail("should not reach here!");
105                            } catch (e) {
106                                assert.ok(e instanceof Error);
107                                assert.equal(e.message, "'opts.config' property is missing or invalid.");
108                            }
109                        });
110                });
111
112                it("should fail on invalid opts.config.timeout.", function () {
113
114                    [
115                        10,
116                        "1000",
117                        [],
118                        {}
119                    ]
120                        .forEach(function (value) {
121                            try {
122                                opts.config = { timeout: value };
123                                new Connector(opts);
124                                assert.fail("should not reach here!");
125                            } catch (e) {
126                                assert.ok(e instanceof Error);
127                                assert.equal(e.message, "'opts.config.timeout' property must be a number equal or greater than 100.");
128                            }
129                        });
130                });
131
132
133                it("should fail on invalid opts.credentialProps", function () {
134
135                    [
136                        0,
137                        "",
138                        "foo",
139                        true,
140                        {}
141                    ].forEach(function (credentialProps) {
142                        try {
143                                opts.credentialProps = credentialProps;
144                            new Connector(opts);
145                            assert.fail("should not reach here!");
146                        } catch (e) {
147                            assert.ok(e instanceof Error);
148                            assert.equal(e.message, "'opts.credentialProps' property must be an array of strings.");
149                        }
150                    });
151                });
152
153                it("should fail on invalid opts.createSessionCb", function () {
154
155                    [
156                        0,
157                        "",
158                        "foo",
159                        true,
160                        {},
161                        []
162                    ].forEach(function (createSession) {
163                        try {
164                            opts.createSessionCb = createSession;
165                            new Connector(opts);
166                            assert.fail("should not reach here!");
167                        } catch (e) {
168                            assert.ok(e instanceof Error);
169                            assert.equal(e.message, "'opts.createSessionCb' property is missing or invalid.");
170                        }
171                    });
172                });
173
174                it("should fail on invalid opts.disposeSession", function () {
175
176                    [
177                        1,
178                        "foo",
179                        true,
180                        {},
181                        []
182                    ].forEach(function (disposeSession) {
183                        try {
184                            opts.disposeSessionCb = disposeSession;
185                            new Connector(opts);
186                            assert.fail("should not reach here!");
187                        } catch (e) {
188                            assert.ok(e instanceof Error);
189                            assert.equal(e.message, "'opts.disposeSessionCb' property must be a function.");
190                        }
191                    });
192                });
193
194                it("should fail on invalid opts.refreshSession", function () {
195
196                    [
197                        1,
198                        "foo",
199                        true,
200                        {},
201                        []
202                    ].forEach(function (refreshSession) {
203                        try {
204                            opts.refreshSessionCb = refreshSession;
205                            new Connector(opts);
206                            assert.fail("should not reach here!");
207                        } catch (e) {
208                            assert.ok(e instanceof Error);
209                            assert.equal(e.message, "'opts.refreshSessionCb' property must be a function.");
210                        }
211                    });
212                });
213
214                it("should be able to create an instance.", function (done) {
215                    var c = new Connector(opts);
216                    assert.ok(c instanceof Connector);
217                    done();
218                });
219            });
220
221            describe("getSession", function () {
222
223                beforeEach(function () {
224                    opts.credentialProps = ["username",  "password"];
225                    opts.createSessionCb = createSession;
226                    opts.refreshSessionCb = refreshSession;
227                    opts.disposeSessionCb = disposeSession;
228                });
229
230                it("should fail if no options argument was passed on.", function (done) {
231                    var values = [
232                        null,
233                        undefined,
234                        true,
235                        1000,
236                        "",
237                        "foo"
238                    ];
239                    var c = new Connector(opts);
240
241                    values.forEach(function (value) {
242                        c.getSession(value, function (err, data) {
243                            assert.ok(err instanceof Error);
244                            assert.equal(err.message, "'options' argument must be an object instance.");
245                            if (value===values[values.length-1]) done();
246                        });
247                    });
248                });
249
250                it("should fail when the options that was passed on is not an object instance.", function (done) {
251                    var values = [
252                        "",
253                        true,
254                        1000,
255                        null,
256                        undefined,
257                        []
258                    ];
259
260                    var c = new Connector(opts);
261
262                    values.forEach(function (value) {
263                        c.getSession(value, function (err, data) {
264                            assert.ok(err instanceof Error);
265                            assert.equal(err.message, "'options' argument must be an object instance.");
266                            if (value===values[values.length-1]) done();
267                        });
268                    });
269                });
270
271                it("should return any error returned by createSessionCb callback.", function (done) {
272                    var c = new Connector(opts);
273                    createSession.onCall(0).callsArgWith(1, "some error");
274
275                    c.getSession({ username: "mike" }, function (err, data) {
276                        assert.ok(createSession.calledOnce);
277                        assert.ok(!data);
278                        assert.equal(err, "some error");
279                        done();
280                    });
281                });
282
283                it("should return an error if an invalid 'auth' token was passed on.", function (done) {
284                    var c = new Connector(opts);
285                    c.getSession({ auth: "un existing token" }, function (err, data) {
286                        assert.ok(!data);
287                        assert.ok(err instanceof Error);
288                        assert.equal(err.message, "Invalid 'auth' token.");
289                        done();
290                    });
291                });
292
293                it("should work when valid arguments", function (done) {
294                    var c = new Connector(opts);
295                    createSession.onCall(0).callsArgWith(1, null, "token");
296                    c.getSession({ username: "mike" }, function (err, data) {
297                        assert.ok(createSession.calledOnce);
298                        assert.ok(data);
299                        assert.equal(data, "token");
300                        done();
301                    });
302                });
303
304                it("should only call createSession once when valid arguments", function (done) {
305                    var c = new Connector(opts);
306                    createSession.onCall(0).callsArgWith(1, null, "token");
307                    c.getSession({ username: "mike" }, function (err, data) {
308                        assert.ok(!err);
309                        c.getSession({ username: "mike" }, function (err, data) {
310                            assert.ok(createSession.calledOnce);
311                            done();
312                        });
313                    });
314                });
315
316                it("should ignore cache if 'ignoreCache' option is passed", function (done) {
317                    var c = new Connector(opts);
318                    createSession.onCall(0).callsArgWith(1, null, "token");
319                    createSession.onCall(1).callsArgWith(1, null, "new-token");
320                    c.getSession({ username: "mike" }, function (err, data) {
321                        assert.ok(!err);
322                        c.getSession({ username: "mike", ignoreCache: true }, function (err, data) {
323                            assert.ok(!err);
324                            assert.equal(data, "new-token");
325                            done();
326                        });
327                    });
328                });
329
330                describe("When cache are disabled", function () {
331
332                    it("should invoke createSessionCb always", function (done) {
333
334                        opts.disableCache = true;
335                        delete opts.refreshSessionCb;
336                        delete opts.disposeSessionCb;
337
338                        var c = new Connector(opts);
339
340                        createSession.onCall(0).callsArgWith(1, null, { auth: "custom" });
341                        createSession.onCall(1).callsArgWith(1, null, { auth: "custom2" });
342
343                        c.getSession( {}, function (err, session, auth) {
344                            assert.ok(createSession.calledOnce);
345                            assert.ok(!err);
346                            assert.equal(session.auth, "custom");
347                            assert.equal(auth, "custom");
348
349
350                            c.getSession( {}, function (err, session, auth) {
351                                assert.ok(createSession.calledTwice);
352                                assert.ok(!err);
353                                assert.equal(session.auth, "custom2");
354                                assert.equal(auth, "custom2");
355                                done();
356                            });
357                        });
358                    });
359
360
361                    it("should fail if session doesn't have 'auth' prop", function (done) {
362
363                        opts.disableCache = true;
364                        delete opts.refreshSessionCb;
365                        delete opts.disposeSessionCb;
366
367                        var c = new Connector(opts);
368
369                        createSession.onCall(0).callsArgWith(1, null, {});
370
371                        c.getSession( {}, function (err, session, auth) {
372                            assert.ok(createSession.calledOnce);
373                            assert.ok(err instanceof Error);
374                            assert.equal(err.message, "session doesn't have 'auth' property.");
375                            done();
376                        });
377                    });
378                });
379
380                describe("When an user hasn't a session.", function () {
381
382                    describe("and user credentials were not configured", function () {
383
384                        it("should invoke createSessionCb callback.", function (done) {
385                            var c = new Connector(opts);
386                            createSession.onCall(0).callsArgWith(1, null, "custom");
387
388                            c.getSession({ }, function (err, session, auth) {
389                                assert.ok(createSession.calledOnce);
390                                assert.ok(!err);
391                                assert.equal(session, "custom");
392                                assert.ok(auth);
393                                done();
394                            });
395                        });
396                    });
397
398                    describe("and user credentials were configured", function () {
399
400
401                        beforeEach(function () {
402                            opts.config = { username: "foo", password: "bar" };
403                        });
404
405                        it("should use configured credentials when no credentials were passed on.", function (done) {
406
407                            var c = new Connector(opts);
408                            c.getSession({}, function (err, session, auth) {
409                                assert.ok(!err);
410                                assert.ok(session);
411                                assert.ok(auth);
412
413                                assert.ok(createSession.calledOnce);
414                                var args = createSession.getCall(0).args;
415                                assert.deepEqual(args[0], { username: "foo", password: "bar" });
416                                done();
417                            });
418                        });
419
420                        it("should use passed on credentials.", function (done) {
421
422                            var c = new Connector(opts);
423                            c.getSession({ username: "alfa", password: "beta"}, function (err, session, auth) {
424                                assert.ok(!err);
425                                assert.ok(session);
426                                assert.ok(auth);
427
428                                assert.ok(createSession.calledOnce);
429                                var args = createSession.getCall(0).args;
430                                assert.deepEqual(args[0], { username: "alfa", password: "beta" });
431                                done();
432                            });
433                        });
434                    });
435                });
436
437                describe("When a user has an existing session.", function () {
438                    it("should return data from cache if a valid auth token was passed on.", function (done) {
439                        var c = new Connector(opts);
440
441                        createSession.onCall(0).callsArgWith(1, null, "custom");
442
443                        c.getSession({ username: "mike", password: "1234" }, function (err, session, auth) {
444                            assert.ok(!err);
445                            assert.ok(session);
446                            assert.ok(auth);
447
448                            c.getSession({ auth: auth }, function (err, session2, auth2) {
449                                assert.ok(!refreshSession.called);
450                                assert.ok(!err);
451                                assert.equal(session, session2);
452                                assert.equal(auth, auth2);
453                                done();
454                            });
455                        });
456                    });
457
458                    it("should return data from cache if a valid username and password were passed on.", function (done) {
459                        var c = new Connector(opts);
460
461                        createSession.onCall(0).callsArgWith(1, null, "custom");
462
463                        c.getSession({ username: "mike", password: "1234" }, function (err, session, auth) {
464                            assert.ok(!err);
465                            assert.ok(session);
466                            assert.ok(auth);
467
468                            c.getSession({ username: "mike", password: "1234" }, function (err, session2, auth2) {
469                                assert.ok(!err);
470                                assert.equal(session, session2);
471                                assert.equal(auth, auth2);
472                                done();
473                            });
474                        });
475                    });
476
477                    it("should fail if a valid username but wrong password were passed on.", function (done) {
478                        var c = new Connector(opts);
479
480                        createSession.onCall(0).callsArgWith(1, null, "custom");
481                        createSession.onCall(1).callsArgWith(1, "some error");
482
483                        c.getSession({ username: "mike", password: "1234" }, function (err, session, auth) {
484                            assert.ok(!err);
485                            assert.ok(session);
486                            assert.ok(auth);
487
488                            c.getSession({ username: "mike", password: "5678" }, function (err, session2, auth2) {
489                                assert.ok(!session2);
490                                assert.ok(!auth2);
491                                assert.equal(err, "some error");
492
493                                // valiate createSession calls' arguments
494                                assert.deepEqual(createSession.getCall(0).args[0],  { username: "mike", password: "1234" });
495                                assert.deepEqual(createSession.getCall(1).args[0],  { username: "mike", password: "5678" });
496                                done();
497                            });
498                        });
499                    });
500
501                    describe("And module was initialized with a 'refreshSessionCb' callback", function () {
502
503                        it("should return any error returned by refreshSession callback.", function (done) {
504                            var c = new Connector(opts);
505                            createSession.onCall(0).callsArgWith(1, null, "custom", new Date());
506
507                            c.getSession({ username: "mike" }, function (err, session, auth) {
508                                assert.ok(!err);
509                                assert.ok(session);
510                                assert.ok(auth);
511
512                                // refresh authentication and returns new metadata and new expiration
513                                refreshSession.onCall(0).callsArgWith(1, "some error");
514
515                                // wait until token expires
516                                setTimeout(function () {
517                                    // token is expired, a new getSession must refresh the token
518                                    c.getSession({ auth: auth }, function (err, session2, auth2) {
519                                        assert.ok(refreshSession.calledOnce);
520                                        assert.ok(!session2);
521                                        assert.ok(!auth2);
522                                        assert.equal(err, "some error");
523                                        done();
524                                    });
525                                }, 20);
526                            });
527                        });
528
529                        it("should invoke 'refreshSession' callback  when auth token is expired.", function (done) {
530
531                            var firstDate = new Date();
532                            var secondDate = new Date(firstDate.getTime() + 5000);
533
534                            // authenticates user and returns metadata and expiration
535                            // firstDate is an expired time
536                            createSession.onCall(0).callsArgWith(1, null, "custom", firstDate);
537
538                            // refresh authentication and returns new metadata and new expiration
539                            refreshSession.onCall(0).callsArgWith(1, null, "custom2", secondDate);
540
541
542                            var c = new Connector(opts);
543                            // first getSession users
544                            c.getSession({ username: "mike", password: "1234" }, function (err, session, auth) {
545
546
547                                assert.ok(!err);
548                                assert.ok(auth);
549                                assert.equal(session, "custom");
550
551                                // wait until token expires
552                                setTimeout(function () {
553
554                                    // token is expired, a new getSession must refresh the token
555                                    c.getSession({ auth: auth }, function (err, session2, auth2) {
556
557                                        assert.ok(!err);
558                                        // auth token must remain the same one
559                                        assert.equal(auth2, auth);
560                                        // the session must be the new one
561                                        assert.equal(session2, "custom2");
562
563                                        // Refresh method must be invoked once.
564                                        assert.ok(refreshSession.calledOnce);
565
566                                        // The refresh method must recieve:
567                                        var args = refreshSession.getCall(0).args;
568                                        assert.equal(args[0], session);
569                                        done();
570                                    });
571                                }, 20);
572                            });
573                        });
574
575                        it("should return data from cache if auth token is not expired", function (done) {
576                            var c = new Connector(opts);
577
578                            createSession.onCall(0).callsArgWith(1, null, "custom", new Date(new Date().getTime() + 5000));
579
580                            c.getSession({ username: "mike" }, function (err, session, auth) {
581                                assert.ok(createSession.calledOnce);
582                                assert.ok(!err);
583                                assert.ok(auth);
584                                assert.equal(session, "custom");
585
586                                c.getSession({ auth: auth }, function (err, session2, auth2) {
587                                    assert.ok(!refreshSession.hcalled);
588                                    assert.ok(!err);
589                                    assert.equal(session, session2);
590                                    assert.equal(auth, auth2);
591                                    done();
592                                });
593                            });
594                        });
595
596                        it("should fail when 'createSessionCb' callback returns a token expiration that is not of type Date.", function (done) {
597                            var c = new Connector(opts);
598
599                            createSession.onCall(0).callsArgWith(1, null, "custom", "invalid expiration time");
600
601                            c.getSession({ username: "mike" }, function (err, session, auth) {
602                                assert.ok(createSession.calledOnce);
603                                assert.ok(!session);
604                                assert.ok(!auth);
605                                assert.ok(err instanceof Error);
606                                assert.equal(err.message, "Create session aborted.");
607                                assert.equal(err.description, "When 'createSessionCb' callback returns an 'expire' argument. It must be of type Date.");
608                                done();
609                            });
610                        });
611
612                        it("should invoke 'createSessionCb' callback when 'refreshSessionCb' does not return a new session.", function (done) {
613                            var firstDate = new Date();
614                            var secondDate = new Date(firstDate.getTime() + 5000);
615
616                            // authenticates user and returns session and expiration 
617                            // firstDate is an expired time
618                            createSession.onCall(0).callsArgWith(1, null, "custom", firstDate);
619
620                            // authenticates user and returns sesison and expiration 
621                            createSession.onCall(1).callsArgWith(1, null, "custom2", secondDate);
622
623                            // refresh authentication does NOT return a new session
624                            refreshSession.onCall(0).callsArgWith(1, null, null);
625
626                            var c = new Connector(opts);
627
628                            // first getSession users
629                            c.getSession({ username: "mike", password: "1234" }, function (err, session, auth) {
630
631                                assert.ok(!err);
632                                assert.ok(auth);
633                                assert.equal(session, "custom");
634
635                                // wait until token expires
636                                setTimeout(function () {
637
638                                    // token is expired, a new getSession must refresh the token
639                                    c.getSession({ auth: auth }, function (err, session2, auth2) {
640
641                                        assert.ok(!err);
642                                        // auth token must remain the same one
643                                        assert.equal(auth2, auth);
644                                        // the session must be the new one
645                                        assert.equal(session2, "custom2");
646
647                                        // Refresh method must be invoked once.
648                                        assert.ok(refreshSession.calledOnce);
649
650                                        // Create method must be invoked twice.
651                                        assert.ok(createSession.calledTwice);
652
653                                        // The refresh method must recieve:
654                                        var args = refreshSession.getCall(0).args;
655                                        assert.equal(args[0], session);
656                                        done();
657                                    });
658                                }, 20);
659                            });
660
661                        });
662                    });
663
664                    describe("And module was initialized with a 'disposeSession' callback", function () {
665
666                        it("should invoke disposeSession when an item timeouts", function (done) {
667                            var timeout = 100;
668                            opts.config = { timeout: timeout };
669
670                            var c = new Connector(opts);
671
672                            createSession.onCall(0).callsArgWith(1, null, "custom");
673                            disposeSession.onCall(0).callsArg(1);
674
675                            c.getSession({ username: "mike" }, function (err, session, auth) {
676                                assert.ok(!err);
677                                assert.ok(auth);
678                                assert.equal(session, "custom");
679                            });
680
681                            setTimeout(function () {
682                                assert.ok(disposeSession.calledOnce);
683                                var args = disposeSession.getCall(0).args;
684                                assert.equal(args.length, 2);
685                                assert.equal(args[0], "custom");
686                                assert.equal(typeof args[1], "function");
687                                done();
688                            }, timeout + 20);
689                        });
690                    });
691                });
692            });
693
694            describe("close", function () {
695
696                beforeEach(function () {
697                    opts.credentialProps = ["username",  "password"];
698                    opts.createSessionCb = createSession;
699                    opts.refreshSessionCb = refreshSession;
700                    opts.disposeSessionCb = disposeSession;
701                });
702
703                it("should no fail if there aren't any session.", function (done) {
704                    var c = new Connector(opts);
705                    c.close(done);
706                });
707
708                it("should no fail if caching is disabled.", function (done) {
709                    opts.disableCache = true;
710                    var c = new Connector(opts);
711                    c.close(done);
712                });
713
714                it("should invoke 'disposeSession' callback for each session", function (done) {
715                    var c = new Connector(opts);
716                    createSession.onCall(0).callsArgWith(1, null, "custom");
717                    createSession.onCall(1).callsArgWith(1, null, "custom2");
718
719                    disposeSession.onCall(0).callsArgWith(1);
720                    disposeSession.onCall(1).callsArgWith(1);
721
722                    c.getSession({ username: "mike" }, function (err, session, auth) {
723                        assert.ok(createSession.calledOnce);
724                        assert.ok(!err);
725                        assert.equal(session, "custom");
726                        assert.ok(auth);
727
728                        c.getSession({ username: "john" }, function (err, session2, auth2) {
729                            assert.ok(createSession.calledTwice);
730                            assert.ok(!err);
731                            assert.equal(session2, "custom2");
732                            assert.ok(auth2);
733
734                            c.close(function () {
735                                assert.ok(disposeSession.calledTwice);
736                                assert.equal(disposeSession.getCall(0).args[0], session);
737                                assert.equal(disposeSession.getCall(1).args[0], session2);
738                                done();
739                            });
740                        });
741                    });
742                });
743            });
744        });
745
746        describe("after module was initialized without disposeSession", function () {
747            var createSession = sinon.stub();
748            var disposeSession = sinon.stub();
749            var refreshSession = sinon.stub();
750            var opts;
751
752            before(function () {
753                require.uncache("../index.js");
754                connector   = require("../index.js");
755                Connector   = connector.Connector;
756                connector.init("test", winston);
757            });
758
759            beforeEach(function () {
760                createSession.reset();
761                disposeSession.reset();
762                refreshSession.reset();
763                opts = {
764                    credentialProps: ["username",  "password"],
765                    createSessionCb: createSession,
766                    refreshSessionCb: refreshSession
767                };
768            });
769
770            describe("getSession", function () {
771                describe("When a user has an existing session.", function () {
772                    it("should not fail when a cache item expires by timeout", function (done) {
773                        var expectedAuth = null;
774                        var timeout = 100;
775                        opts.config = { timeout: timeout };
776                        var c = new Connector(opts);
777
778                        createSession.onCall(0).callsArgWith(1, null, "custom");
779                        createSession.onCall(1).callsArgWith(1, null, "custom");
780
781                        c.getSession({ username: "mike" }, function (err, session, auth) {
782                            assert.ok(!err);
783                            assert.ok(auth);
784                            assert.equal(session, "custom");
785                            expectedAuth = auth;
786                        });
787
788                        setTimeout(function () {
789                            // getSession again
790                            c.getSession({ username: "mike" }, function (err, session2, auth2) {
791                                assert.ok(!err);
792                                assert.equal(session2, "custom");
793                                assert.ok(expectedAuth !== auth2);
794                                done();
795                            });
796                        }, timeout + 20);
797                    });
798                });
799            });
800
801            describe("close", function () {
802                it("should not fail", function (done) {
803                    var c = new Connector(opts);
804                    createSession.onCall(0).callsArgWith(1, null, "custom");
805
806                    c.getSession({ username: "mike" }, function (err, session, auth) {
807                        assert.ok(createSession.calledOnce);
808                        assert.ok(!err);
809                        assert.equal(session, "custom");
810                        assert.ok(auth);
811
812                            c.close(function () {
813                            assert.ok(!disposeSession.called);
814                            done();
815                        });
816                    });
817                });
818
819                it("should not fail when caching is disabled", function (done) {
820                    opts.disableCache = true;
821                    var c = new Connector(opts);
822                    createSession.onCall(0).callsArgWith(1, null, { auth: "custom" });
823
824                    c.getSession({ username: "mike" }, function (err, session, auth) {
825                        assert.ok(createSession.calledOnce);
826                        assert.ok(!err);
827                        assert.equal(session.auth, "custom");
828                        assert.equal(auth, "custom");
829
830                            c.close(function () {
831                            assert.ok(disposeSession.notCalled);
832                            done();
833                        });
834                    });
835                });
836            });
837        });
838
839        describe("after module was initialized without refreshSession", function () {
840            var createSession = sinon.stub();
841            var disposeSession = sinon.stub();
842            var refreshSession = sinon.stub();
843            var opts = {};
844
845            before(function () {
846                require.uncache("../index.js");
847                connector = require("../index.js");
848                Connector = connector.Connector;
849                connector.init("test", winston);
850            });
851
852            beforeEach(function () {
853                createSession.reset();
854                disposeSession.reset();
855                refreshSession.reset();
856
857                opts = {
858                    credentialProps: ["username",  "password"],
859                    createSessionCb: createSession,
860                    disposeSessionCb: disposeSession
861                };
862            });
863
864            describe("getSession", function () {
865
866                describe("When a user has an existing session.", function () {
867
868                    it("should fail when 'createSessionCb' callback returns a token's expiration.", function (done) {
869                        var c = new Connector(opts);
870                        createSession.onCall(0).callsArgWith(1, null, "custom", new Date(new Date().getTime() + 5000));
871
872                        c.getSession({ username: "mike" }, function (err, session, auth) {
873                            assert.ok(createSession.calledOnce);
874                            assert.ok(!auth);
875                            assert.ok(!session);
876                            assert.ok(err instanceof Error);
877                            assert.equal(err.message, "Create session aborted.");
878                            assert.equal(err.description, "When 'createSessionCb' callback returned an 'expire' argument but not 'refreshSessionCb' callback was initialized.");
879                            done();
880                        });
881                    });
882                });
883            });
884        });
885    });
886
887    describe("init", function () {
888
889        var dir = path.resolve(process.cwd(), "./logs/");
890
891        beforeEach(function () {
892            if (fs.existsSync(dir)) fs.rmdirSync(dir);
893        });
894
895        it("should fail if no label", function () {
896            try {
897                require.uncache("../index.js");
898                connector   = require("../index.js");
899                Connector   = connector.Connector;
900                connector.init();
901                assert.fail("should not reach here!");
902            } catch (e) {
903                assert.ok(e instanceof Error);
904                assert.equal(e.message, "'label' argument is missing.");
905            }
906        });
907
908        it("should fail if no winston", function () {
909            try {
910                require.uncache("../index.js");
911                connector   = require("../index.js");
912                Connector   = connector.Connector;
913                connector.init("foo");
914                assert.fail("should not reach here!");
915            } catch (e) {
916                assert.ok(e instanceof Error);
917                assert.equal(e.message, "'winston' argument is missing.");
918            }
919        });
920
921        it("should work", function () {
922            require.uncache("../index.js");
923            connector   = require("../index.js");
924            Connector   = connector.Connector;
925            connector.init("test", winston, noop);
926        });
927
928        it("should fail when is initialized by a second time", function () {
929            require.uncache("../index.js");
930            connector   = require("../index.js");
931            Connector   = connector.Connector;
932            connector.init("test", winston, noop);
933            try {
934                connector.init("test", winston, noop);
935                assert.fail("Did not fail.");
936            } catch (e) {
937                assert.ok(e instanceof Error);
938                assert.equal(e.message, "Can't be initialized twice.");
939            }
940        });
941
942        it("should work with --level", function () {
943            require.uncache("../index.js");
944            process.argv.push("--level");
945            process.argv.push("debug");
946            connector = require("../index.js");
947            connector.init("test", winston, noop);
948        });
949
950        it("'timestamp' winston option must be a valid function.", function () {
951            require.uncache("../index.js");
952            process.argv.push("--level");
953            process.argv.push("debug");
954            connector = require("../index.js");
955            connector.init("test", winston);
956            assert.ok(winston.add.calledTwice);
957            var args = winston.add.getCall(0).args;
958            var timestamp = args[1].timestamp;
959            assert.equal(typeof timestamp, "function");
960            assert.ok(timestamp());
961        });
962
963
964        it("should create log folder.", function () {
965            require.uncache("../index.js");
966            process.argv.push("--level");
967            process.argv.push("debug");
968            connector = require("../index.js");
969            connector.init("test", winston);
970            assert.ok(fs.existsSync(dir));
971        });
972
973        it("should not fail id log folder aready exists.", function () {
974
975            fs.mkdirSync(dir);
976            assert.ok(fs.existsSync(dir));
977            require.uncache("../index.js");
978            process.argv.push("--level");
979            process.argv.push("debug");
980            connector = require("../index.js");
981            connector.init("test", winston);
982            assert.ok(fs.existsSync(dir));
983        });
984    });
985
986    describe("isHostAllowed", function () {
987        before(function () {
988            process.env.RUNNING_ON = "hub";
989            connector = require("../index.js");
990        });
991
992        it("Should fail with no host", function (done) {
993            connector.isHostAllowed(function (err, allowed) {
994                assert.ok(!allowed);
995                assert.ok(err);
996                assert.strictEqual(err.message, "host parameter is mandatory");
997                done();
998            });
999        });
1000
1001        it("Should fail with invalid host type", function (done) {
1002            connector.isHostAllowed(123, function (err, allowed) {
1003                assert.ok(!allowed);
1004                assert.ok(err);
1005                assert.strictEqual(err.message, "host must be a string");
1006                done();
1007            });
1008        });
1009
1010        it("Should fail with missing cb host type", function (done) {
1011            connector.isHostAllowed(123, function (err, allowed) {
1012                assert.ok(!allowed);
1013                assert.ok(err);
1014                assert.strictEqual(err.message, "host must be a string");
1015                done();
1016            });
1017        });
1018
1019        it("Should fail with invalid host", function (done) {
1020            connector.isHostAllowed("INVALID", function (err, allowed) {
1021                assert.ok(!allowed);
1022                assert.ok(err);
1023                assert.strictEqual(err.message, "getaddrinfo ENOTFOUND");
1024                done();
1025            });
1026        });
1027
1028        it("Should return invalid with loopback host ipv4", function (done) {
1029            connector.isHostAllowed("localhost", function (err, allowed) {
1030                assert.ok(!err);
1031                assert.ok(!allowed);
1032                done();
1033            });
1034        });
1035
1036        it("Should return invalid with loopback ip ipv4", function (done) {
1037            connector.isHostAllowed("127.0.0.3", function (err, allowed) {
1038                assert.ok(!err);
1039                assert.ok(!allowed);
1040                done();
1041            });
1042        });
1043
1044        it("Should return invalid with loopback host ipv6", function (done) {
1045            connector.isHostAllowed("::1", function (err, allowed) {
1046                assert.ok(!err);
1047                assert.ok(!allowed);
1048                done();
1049            });
1050        });
1051
1052        it("Should return invalid with internal host ipv4", function (done) {
1053            connector.isHostAllowed("10.0.1.10", function (err, allowed) {
1054                assert.ok(!err);
1055                assert.ok(!allowed);
1056                done();
1057            });
1058        });
1059
1060        it("Should return invalid with internal host ipv6", function (done) {
1061            connector.isHostAllowed("fe80::6267:20ff:fe22:4928", function (err, allowed) {
1062                assert.ok(!err);
1063                assert.ok(!allowed);
1064                done();
1065            });
1066        });
1067
1068        it("Should work with valid hostname", function (done) {
1069            connector.isHostAllowed("www.google.com", function (err, allowed) {
1070                assert.ok(!err);
1071                assert.ok(allowed);
1072                done();
1073            });
1074        });
1075
1076        it("Should work with valid IP", function (done) {
1077            connector.isHostAllowed("64.233.186.147", function (err, allowed) {
1078                assert.ok(!err);
1079                assert.ok(allowed);
1080                done();
1081            });
1082        });
1083
1084        it("Should work when not running on hub", function (done) {
1085            process.env.RUNNING_ON = "agent";
1086            connector.isHostAllowed("localhost", function (err, allowed) {
1087                assert.ok(!err);
1088                assert.ok(allowed);
1089
1090                process.env.RUNNING_ON = "hub";
1091                done();
1092            });
1093        });
1094    });
1095});
1096
1097
1098
1099/**
1100 * Removes a module from the cache
1101 */
1102require.uncache = function (moduleName) {
1103    // Run over the cache looking for the files
1104    // loaded by the specified module name
1105    require.searchCache(moduleName, function (mod) {
1106        delete require.cache[mod.id];
1107    });
1108};
1109
1110/**
1111 * Runs over the cache to search for all the cached
1112 * files
1113 */
1114require.searchCache = function (moduleName, callback) {
1115    // Resolve the module identified by the specified name
1116    var mod = require.resolve(moduleName);
1117
1118    // Check if the module has been resolved and found within
1119    // the cache
1120    if (mod && ((mod = require.cache[mod]) !== undefined)) {
1121        // Recursively go over the results
1122        (function run(mod) {
1123            // Go over each of the module's children and
1124            // run over it
1125            mod.children.forEach(function (child) {
1126                run(child);
1127            });
1128
1129            // Call the specified callback providing the
1130            // found module
1131            callback(mod);
1132        })(mod);
1133    }
1134};
1135
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Appium Base Driver on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)