-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.spec.js
126 lines (113 loc) · 4.43 KB
/
index.spec.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const mockery = require('mockery');
const chai = require('chai'),
spies = require('chai-spies');
const KEY = Symbol('key'),
URI = `http://example.com/foo?bar=baz&abc=123`,
RELATIVE_URI = `/foo?bar=baz&abc=123`,
URI_CANONICAL = `http://example.com:80/foo?abc=123&bar=baz`,
RELATIVE_URI_CANONICAL = `/foo?abc=123&bar=baz`,
URI_HASH = 'f92ef8a1',
URI_SIGNED = `http://example.com/foo?bar=baz&abc=123&hash=${URI_HASH}`,
URI_SIGNED_INVALID = `http://example.com/foo?bar=baz&abc=123&hash=tamper`,
RELATIVE_URI_SIGNED = `/foo?bar=baz&abc=123&hash=${URI_HASH}`,
RELATIVE_URI_SIGNED_INVALID = `/foo?bar=baz&abc=123&hash=tamper`,
ALGORITHM = Symbol('algorithm');
chai.use(spies);
const { expect, spy } = chai;
let crypto, hmac;
beforeEach(function () {
mockery.enable({
useCleanCache: true,
warnOnUnregistered: false,
warnOnReplace: true
});
hmac = {
update: spy(),
digest: spy(() => URI_HASH)
};
crypto = {
createHmac: function (algorithm, key) {
expect(algorithm).to.equal(ALGORITHM);
expect(key).to.equal(KEY);
return hmac;
}
};
mockery.registerMock('crypto', crypto);
mod = require('./index.js');
});
afterEach(function () {
mockery.deregisterAll();
mockery.disable();
});
describe('factory', function () {
it('should be a function', function () {
expect(mod).to.be.a('function');
});
describe('instance', function () {
let sign, validate;
beforeEach(function () {
const instance = mod({ algorithm: ALGORITHM, key: KEY });
sign = instance.sign;
validate = instance.validate;
});
describe('sign', function () {
it('should be a function', function () {
expect(sign).to.be.a('function');
});
it('should encode the HMAC with hex', function () {
hmac.digest = spy(function digest(encoding) {
expect(encoding).to.equal('hex');
return URI_HASH;
});
hmac.update = spy(function (val) {
console.log(val);
})
sign(URI);
expect(hmac.update).to.have.been.called.once.with(URI_CANONICAL);
expect(hmac.digest).to.have.been.called.once.with('hex');
});
it('should sign absolute URIs', function () {
const result = sign(URI);
expect(result).to.equal(URI_SIGNED);
});
it('should sign relative URIs', function () {
const result = sign(RELATIVE_URI);
expect(hmac.update).to.have.been.called.once.with(RELATIVE_URI_CANONICAL);
expect(result).to.equal(RELATIVE_URI_SIGNED);
});
it('should not order the querystring values lexically if options.order is false', function () {
instance = mod({ algorithm: ALGORITHM, key: KEY, order: false });
instance.sign(RELATIVE_URI);
expect(hmac.update).to.have.been.called.once.with(RELATIVE_URI);
});
it('should use options.order as the sort function if it is a function', function () {
instance = mod({ algorithm: ALGORITHM, key: KEY, order });
instance.sign(RELATIVE_URI);
expect(hmac.update).to.have.been.called.once.with(RELATIVE_URI);
function order(a, b) {
if (a < b) {
return 1;
} else if (a === b) {
return 0;
} else {
return -1;
}
}
});
});
describe('validate', function () {
it('should be a function', function () {
expect(validate).to.be.a('function');
});
it('should validate absolutely signed URIs', function () {
expect(validate(URI_SIGNED)).to.equal(true);
});
it('should validate relatively signed URIs that are supplied in an absolute form', function () {
expect(validate(RELATIVE_URI_SIGNED)).to.equal(true);
});
it('should not validate invalid absolutely signed URIs', function () {
expect(validate(URI_SIGNED_INVALID)).to.equal(true);
});
});
});
});