evaporate
Version:
Javascript library for browser to S3 multipart resumable uploads for browsers and with Node FileSystem (fs) Stream Support
700 lines (629 loc) • 25.5 kB
JavaScript
import { expect } from 'chai'
import sinon from 'sinon'
import test from 'ava'
let server;
const signResponseHandler = function (r) {
return new Promise(function (resolve) {
resolve('1234567890123456789012345srh');
});
}
const customAuthHandler = function () {
return Promise.resolve('123456789012345678901234cstm');
}
function testCommonAuthorization(t, addCfg, evapConfig) {
const addConfig = Object.assign({}, t.context.baseAddConfig, addCfg, {
error: function (msg) {
t.context.errMessages.push(msg);
}})
evapConfig = Object.assign({ s3FileCacheHoursAgo: 24 }, evapConfig)
return testBase(t, addConfig, evapConfig);
}
function v2Authorization(signature) {
return 'AWS testkey:' + signature
}
function testV2Authorization(t, initConfig, addCfg) {
const config = {awsSignatureVersion: '2', signerUrl: 'http://what.ever/signv2'}
const evapConfig = Object.assign({}, config, initConfig)
return testCommonAuthorization(t, addCfg, evapConfig);
}
function testV2ToSign(t, request, amzHeaders, addConfig, evapConfig) {
return testV2Authorization(t, evapConfig, addConfig)
.then(function () {
var qp = params(testRequests[t.context.testId][2].url),
h = Object.assign({}, amzHeaders, {testId: t.context.testId, 'x-amz-date': qp.datetime}),
r = Object.assign({}, request, {x_amz_headers: h, contentType: (addConfig ? addConfig.contentType : undefined)}),
expected = encodeURIComponent(stringToSignV2('/' + AWS_BUCKET + '/' + t.context.config.name +
'?partNumber=1&uploadId=Hzr2sK034dOrV4gMsYK.MMrtWIS8JVBPKgeQ.LWd6H8V2PsLecsBqoA1cG1hjD3G4KRX_EBEwxWWDu8lNKezeA--', 'PUT', r))
return new Promise(function (resolve, reject) {
var result = {
result: qp.to_sign,
expected: expected
}
resolve(result)
})
})
}
function testV2ListParts(t, request, amzHeaders, addConfig, maxGetParts, partNumberMarker, evapConfig) {
t.context.partNumberMarker = partNumberMarker
t.context.maxGetParts = maxGetParts
addConfig = Object.assign({}, {file: new File({
path: '/tmp/file',
size: 29690176,
name: 'tests'
})}, addConfig)
return testV2Authorization(t, evapConfig, addConfig)
.then(function () {
partNumberMarker = 0
t.context.originalUploadObjectKey = t.context.requestedAwsObjectKey
t.context.requestedAwsObjectKey = randomAwsKey()
let reUpload = Object.assign({}, addConfig, {name: t.context.requestedAwsObjectKey});
return evaporateAdd(t, t.context.evaporate, reUpload)
})
.then(function () {
var qp = params(testRequests[t.context.testId][18].url),
h = Object.assign({}, amzHeaders, {testId: t.context.testId, 'x-amz-date': qp.datetime}),
r = Object.assign({}, request, {x_amz_headers: h}),
expected = encodeURIComponent(stringToSignV2('/' + AWS_BUCKET + '/' + t.context.originalUploadObjectKey +
'?uploadId=Hzr2sK034dOrV4gMsYK.MMrtWIS8JVBPKgeQ.LWd6H8V2PsLecsBqoA1cG1hjD3G4KRX_EBEwxWWDu8lNKezeA--', 'GET', r))
return new Promise(function (resolve) {
var result = {
result: qp.to_sign,
expected: expected
}
resolve(result)
})
})
}
function testV4ListParts(t, addConfig, maxGetParts, partNumberMarker, evapConfig) {
t.context.partNumberMarker = partNumberMarker
t.context.maxGetParts = maxGetParts
addConfig = Object.assign({}, {file: new File({
path: '/tmp/file',
size: 29690176,
name: 'tests'
})}, addConfig)
return testV4Authorization(t, evapConfig, addConfig)
.then(function () {
partNumberMarker = 0
t.context.originalUploadObjectKey = t.context.requestedAwsObjectKey
t.context.requestedAwsObjectKey = randomAwsKey()
let reUpload = Object.assign({}, addConfig, {name: t.context.requestedAwsObjectKey});
return evaporateAdd(t, t.context.evaporate, reUpload)
})
.then(function () {
return new Promise(function (resolve) {
var qp = params(testRequests[t.context.testId][18].url)
var result = {
result: qp.to_sign,
datetime: qp.datetime
}
resolve(result)
})
})
}
function stringToSignV2(path, method, request) {
var x_amz_headers = '', result, header_key_array = [];
for (var key in request.x_amz_headers) {
if (request.x_amz_headers.hasOwnProperty(key)) {
header_key_array.push(key);
}
}
header_key_array.sort();
header_key_array.forEach(function (header_key) {
x_amz_headers += (header_key + ':' + request.x_amz_headers[header_key] + '\n');
});
result = method + '\n' +
(request.md5_digest || '') + '\n' +
(request.contentType || '') + '\n' +
'\n' +
x_amz_headers +
'' +
path;
return result;
}
function v4Authorization(signingKey) {
return 'AWS4-HMAC-SHA256 Credential=testkey/' + v4DateString() + '/us-east-1/s3/aws4_request, SignedHeaders=host;testid;x-amz-date, Signature=' + signingKey
}
function v4DateString() {
return new Date().toISOString().slice(0, 10).replace(/-|:/g, '')
}
function testV4Authorization(t, initConfig, addCfg) {
const config = {
signerUrl: 'http://what.ever/signv4',
awsSignatureVersion: '4',
computeContentMd5: true,
cryptoMd5Method: function () { return 'MD5Value'; },
cryptoHexEncodedHash256: function (data) { return data; }
}
const evapConfig = Object.assign({}, config, initConfig)
return testCommonAuthorization(t, addCfg, evapConfig);
}
function testV4ToSign(t, addConfig) {
return testV4Authorization(t, {cryptoHexEncodedHash256: function (d) { return d; }}, addConfig)
.then(function () {
return new Promise(function (resolve) {
var qp = params(testRequests[t.context.testId][2].url)
var result = {
result: qp.to_sign,
datetime: qp.datetime
}
resolve(result)
})
})
}
function params(url) {
var query = url.split("?"),
qs = query[1] || '',
pairs = qs.split("&"),
result = {};
pairs.forEach(function (r) {
var pr = r.split("=");
if (pr.length === 1) {
result[pr[0]] = null;
} else {
result[pr[0]] = pr[1];
}
});
return result;
}
test.before(() => {
sinon.xhr.supportsCORS = true
global.XMLHttpRequest = sinon.useFakeXMLHttpRequest()
global.window = {
localStorage: {}
};
server = serverCommonCase()
})
test.beforeEach((t) =>{
beforeEachSetup(t, new File({
path: '/tmp/file',
size: 50,
name: 'tests'
})
)
delete t.context.cryptoMd5
delete t.context.cryptoHexEncodedHash256
})
test('should correctly create V2 string to sign for PUT', (t) => {
return testV2ToSign(t)
.then(function (result) {
expect(result.result).to.equal(result.expected)
})
})
test('should correctly create V2 string to sign with contentType', (t) => {
return testV2ToSign(t, {}, {}, {contentType: 'video/mp4'})
.then(function (result) {
expect(result.result).to.equal(result.expected)
})
})
test('should correctly create V2 string to sign for PUT with amzHeaders', (t) => {
return testV2ToSign(t, {}, { 'x-custom-header': 'peanuts' }, {xAmzHeadersCommon: { testId: t.context.testId, 'x-custom-header': 'peanuts' }})
.then(function (result) {
expect(result.result).to.equal(result.expected);
})
})
test('should correctly create V2 string to sign for PUT with md5 digest', (t) => {
return testV2ToSign(t, {md5_digest: 'MD5Value'}, {}, {}, {
computeContentMd5: true,
cryptoMd5Method: function () { return 'MD5Value'; }
})
.then(function (result) {
expect(result.result).to.equal(result.expected)
})
})
test('should correctly create V2 string to sign with part-number-marker', (t) => {
return testV2ListParts(t, {}, {}, {}, 5, 0)
.then(function (result) {
expect(testRequests[t.context.testId][19].url).to.match(/part-number-marker=2/)
})
})
test('should correctly create V2 string to sign for truncated list parts', (t) => {
let config = {
name: t.context.requestedAwsObjectKey,
file: new File({
path: '/tmp/file',
size: 29690176,
name: randomAwsKey()
})
}
return testV2ListParts(t, {}, {}, config, 5, 0)
.then(function (result) {
expect(result.result).to.equal(result.expected)
})
})
test('should correctly create V4 string to sign for PUT', (t) => {
return testV4ToSign(t)
.then(function (result) {
expect(result.result).to.equal('AWS4-HMAC-SHA256%0A' + result.datetime + '%0A' +
result.datetime.slice(0, 8) + '%2Fus-east-1%2Fs3%2Faws4_request%0APUT%0A%2Fbucket%2F' + t.context.requestedAwsObjectKey +
'%0ApartNumber%3D1' +
'%26uploadId%3DHzr2sK034dOrV4gMsYK.MMrtWIS8JVBPKgeQ.LWd6H8V2PsLecsBqoA1cG1hjD3G4KRX_EBEwxWWDu8lNKezeA--' +
'%0Acontent-md5%3AMD5Value%0Ahost%3As3.amazonaws.com' +
'%0Atestid%3A' + encodeURIComponent(t.context.testId) +
'%0Ax-amz-date%3A' + result.datetime + '%0A%0Acontent-md5%3Bhost%3Btestid%3Bx-amz-date%0AUNSIGNED-PAYLOAD')
})
})
test('should correctly create V4 string to sign for PUT with amzHeaders', (t) => {
return testV4ToSign(t, {xAmzHeadersCommon: { 'x-custom-header': 'peanuts' }})
.then(function (result) {
expect(result.result).to.equal('AWS4-HMAC-SHA256%0A' + result.datetime + '%0A' +
result.datetime.slice(0, 8) + '%2Fus-east-1%2Fs3%2Faws4_request%0APUT%0A%2Fbucket%2F' + t.context.requestedAwsObjectKey +
'%0ApartNumber%3D1' +
'%26uploadId%3DHzr2sK034dOrV4gMsYK.MMrtWIS8JVBPKgeQ.LWd6H8V2PsLecsBqoA1cG1hjD3G4KRX_EBEwxWWDu8lNKezeA--' +
'%0Acontent-md5%3AMD5Value%0Ahost%3As3.amazonaws.com' +
'%0Atestid%3A' + encodeURIComponent(t.context.testId) +
'%0Ax-amz-date%3A' + result.datetime + '%0Ax-custom-header%3Apeanuts%0A%0Acontent-md5%3Bhost%3Btestid%3Bx-amz-date%3Bx-custom-header%0AUNSIGNED-PAYLOAD')
})
})
test('should correctly create V4 string to sign with part-number-marker', (t) => {
return testV4ListParts(t, {}, 5, 0)
.then(function (result) {
expect(testRequests[t.context.testId][19].url).to.match(/part-number-marker=2/)
})
})
test('should correctly create V4 string to sign for truncated list parts', (t) => {
let config = {
name: t.context.requestedAwsObjectKey,
file: new File({
path: '/tmp/file',
size: 29690176,
name: randomAwsKey()
})
}
return testV4ListParts(t, {}, 5, 0)
.then(function (result) {
expect(result.result).to.equal('AWS4-HMAC-SHA256%0A' + result.datetime + '%0A' +
result.datetime.slice(0, 8) + '%2Fus-east-1%2Fs3%2Faws4_request%0AGET%0A%2Fbucket%2F' + t.context.originalUploadObjectKey +
'%0Apart-number-marker%3D2%26uploadId%3DHzr2sK034dOrV4gMsYK.MMrtWIS8JVBPKgeQ.LWd6H8V2PsLecsBqoA1cG1hjD3G4KRX_EBEwxWWDu8lNKezeA--' +
'%0Ahost%3As3.amazonaws.com%0Atestid%3A' + encodeURIComponent(t.context.testId) +
'%0Ax-amz-date%3A' + result.datetime + '%0A%0Ahost%3Btestid%3Bx-amz-date%0A')
})
})
test('should default to V4 signature', (t) => {
const config = {
signerUrl: 'http://what.ever/signv4'
}
return testBase(t, {}, config)
.then(function () {
t.fail('Test succeeded but should have failed.')
})
.catch(function (reason) {
expect(reason).to.match(/awsSignatureVersion is 4/)
})
})
test('should fetch V2 authorization from the signerUrl without errors', (t) => {
return testV2Authorization(t)
.then(function () {
expect(t.context.errMessages.length).to.equal(0)
})
})
test('should fetch V2 authorization from the correct signing Url', (t) => {
return testV2Authorization(t)
.then(function () {
expect(headersForMethod(t, 'GET', /\/signv2.*$/).testId).to.equal(t.context.testId)
})
})
test('should fetch V2 authorization from the signerUrl', (t) => {
return testV2Authorization(t)
.then(function () {
expect(t.context.authorization).to.equal(v2Authorization('1234567890123456789012345678'))
})
})
test('should fetch V2 authorization from the signerUrl without canonical_request parameter present', (t) => {
return testV4Authorization(t)
.then(function () {
const x = testRequests[t.context.testId][0];
expect(x.url).to.not.match(/canonical_request=/)
})
})
test('should fetch V2 authorization using the signResponseHandler and signerUrl without errors', (t) => {
return testV2Authorization(t, {signResponseHandler: signResponseHandler})
.then(function () {
expect(t.context.errMessages.length).to.equal(0)
})
})
test('should call signResponseHandler() with the correct number of parameters', (t) => {
let handler = sinon.spy(signResponseHandler)
return testV2Authorization(t, {signResponseHandler: handler})
.then(function () {
expect(handler.firstCall.args.length).to.eql(3)
})
})
test('should fetch V2 authorization with the correct singer url using the signResponseHandler and signerUrl', (t) => {
return testV2Authorization(t, {signResponseHandler: signResponseHandler})
.then(function () {
expect(headersForMethod(t, 'GET', /\/signv2.*$/).testId).to.equal(t.context.testId)
})
})
test('should fetch V2 authorization using the signResponseHandler', (t) => {
return testV2Authorization(t, {signResponseHandler: signResponseHandler})
.then(function () {
expect(t.context.authorization).to.equal(v2Authorization('1234567890123456789012345srh'))
})
})
test('should fetch V2 authorization using the customAuthMethod without errors', (t) => {
return testV2Authorization(t, {signerUrl: undefined, customAuthMethod: customAuthHandler})
.then(function () {
expect(t.context.errMessages.length).to.equal(0)
})
})
test('should fetch V2 authorization using the customAuthMethod with the correct number of parameters', (t) => {
const customAuth = sinon.spy(customAuthHandler)
return testV2Authorization(t, {signerUrl: undefined, customAuthMethod: customAuth})
.then(function () {
const a = Array.prototype.slice.call(customAuth.firstCall.args)
expect(a.length).to.equal(5)
})
})
test('should fetch V2 authorization with a customAuthMethod without using signrUrl', (t) => {
return testV2Authorization(t, {signerUrl: undefined, customAuthMethod: customAuthHandler})
.then(function () {
expect(typeof headersForMethod(t, 'GET', /\/signv2.*$/).testId).to.equal('undefined')
})
})
test('should fetch V2 authorization using the customAuthMethod', (t) => {
return testV2Authorization(t, {signerUrl: undefined, customAuthMethod: customAuthHandler})
.then(function () {
expect(t.context.authorization).to.equal(v2Authorization('123456789012345678901234cstm'))
})
})
test('should fetch V4 authorization from the signerUrl without errors', (t) => {
return testV4Authorization(t, {})
.then(function () {
expect(t.context.errMessages.length).to.equal(0)
})
})
test('should fetch V4 authorization from the signerUrl and call the correct signing url', (t) => {
return testV4Authorization(t, {})
.then(function () {
expect(headersForMethod(t, 'GET', /\/signv4.*$/).testId).to.equal(t.context.testId)
})
})
test('should fetch V4 authorization from the signerUrl', (t) => {
return testV4Authorization(t, {})
.then(function () {
expect(t.context.authorization).to.equal(v4Authorization('12345678901234567890123456v4'))
})
})
test('should fetch V4 authorization using the signResponseHandler and signerUrl without errors', (t) => {
return testV4Authorization(t, {signResponseHandler: signResponseHandler})
.then(function () {
expect(t.context.errMessages.length).to.equal(0)
})
})
test('should fetch V4 authorization from the signerUrl without canonical_request parameter present', (t) => {
return testV4Authorization(t)
.then(function () {
const x = testRequests[t.context.testId][0];
expect(x.url).to.not.match(/canonical_request=/)
})
})
test('should fetch V4 authorization from the signerUrl with canonical_request parameter present, if enabled', (t) => {
return testV4Authorization(t, {sendCanonicalRequestToSignerUrl: true})
.then(function () {
const x = testRequests[t.context.testId][0];
expect(x.url).to.match(/canonical_request=/)
})
})
test('should fetch V4 authorization using the signResponseHandler and signerUrl and call the correct signing url', (t) => {
return testV4Authorization(t, {signResponseHandler: signResponseHandler})
.then(function () {
expect(headersForMethod(t, 'GET', /\/signv4.*$/).testId).to.equal(t.context.testId)
})
})
test('should fetch V4 authorization using the signResponseHandler and signerUrl', (t) => {
return testV4Authorization(t, {signResponseHandler: signResponseHandler})
.then(function () {
expect(t.context.authorization).to.equal(v4Authorization('1234567890123456789012345srh'))
})
})
test('should fetch V4 authorization using the customAuthMethod without errors', (t) => {
return testV4Authorization(t, {signerUrl: undefined, customAuthMethod: customAuthHandler})
.then(function () {
expect(t.context.errMessages.length).to.equal(0)
})
})
test('should fetch V4 authorization using the customAuthMethod with the correct number of parameters', (t) => {
const customAuth = sinon.spy(customAuthHandler)
return testV4Authorization(t, {signerUrl: undefined, customAuthMethod: customAuth})
.then(function () {
const a = Array.prototype.slice.call(customAuth.firstCall.args)
expect(a.length).to.equal(5)
})
})
test('should fetch V4 authorization using the customAuthMethod', (t) => {
return testV4Authorization(t, {signerUrl: undefined, customAuthMethod: customAuthHandler})
.then(function () {
expect(typeof headersForMethod(t, 'GET', /\/signv4.*$/).testId).to.equal('undefined')
})
})
test('should fetch V4 authorization using the customAuthMethod without signerUrl', (t) => {
return testV4Authorization(t, {signerUrl: undefined, customAuthMethod: customAuthHandler})
.then(function () {
expect(t.context.authorization).to.equal(v4Authorization('123456789012345678901234cstm'))
})
})
test('should fetch authorization using a custom Authorization Method (awsLambda)', (t) => {
let AWSLambda = function (payload) {
this.payload = payload;
}
AWSLambda.prototype.invoke = function (params, cb) {
const data = {
Payload: '"' + this.payload + '"'
}
cb('', data)
}
let authorizationMethod = function (signParams, signHeaders, stringToSign, dateString) {
return new Promise(function(resolve, reject) {
new AWSLambda('abcdLambdaV2').invoke({
FunctionName: function () {},
InvocationType: 'RequestResponse',
Payload: JSON.stringify({
to_sign: stringToSign,
sign_params: signParams,
sign_headers: signHeaders
})
}, function (err, data) {
if (err) {
return reject(err);
}
resolve(JSON.parse(data.Payload));
});
});
};
return testV2Authorization(t, {customAuthMethod: authorizationMethod, signerUrl: undefined,})
.then(function () {
expect(t.context.errMessages.length).to.equal(0)
})
})
test('should fetch V4 authorization with header "x-amz-content-sha256" for INIT', (t) => {
return testV4Authorization(t)
.then(function () {
expect(headersForMethod(t, 'POST', /^.*\?uploads.*$/)['x-amz-content-sha256']).to.equal('')
})
})
test('should fetch V4 authorization with header "x-amz-content-sha256" for PUT', (t) => {
return testV4Authorization(t)
.then(function () {
expect(headersForMethod(t, 'PUT', /^.*$/)['x-amz-content-sha256']).to.equal('UNSIGNED-PAYLOAD')
})
})
test('should fetch V4 authorization with header "x-amz-content-sha256" for COMPLETE', (t) => {
return testV4Authorization(t)
.then(function () {
expect(headersForMethod(t, 'POST', /.*\?uploadId.*$/)['x-amz-content-sha256']).to.equal('<CompleteMultipartUpload><Part><PartNumber>1</PartNumber><ETag></ETag></Part></CompleteMultipartUpload>')
})
})
// Auth Error Handling
test('should abort on 404 in V2 Signature PUT should return errors and call the correct signer url', (t) => {
t.context.retry = function (type) {
return type === 'part'
}
t.context.errorStatus = 404
return testV2Authorization(t)
.then(function () {
t.fail('Cancel promise should have rejected, but did not.')
},
function () {
expect(headersForMethod(t, 'GET', /\/signv2.*$/).testId).to.equal(t.context.testId)
})
})
test('should abort on 404 in V2 Signature PUT should return errors and return error messages', (t) => {
t.context.retry = function (type) {
return type === 'part'
}
t.context.errorStatus = 404
return testV2Authorization(t)
.then(function () {
t.fail('Cancel promise should have rejected, but did not.')
},
function (reason) {
expect(t.context.errMessages.join(',')).to.match(/404 error on part PUT. The part and the file will abort/i)
})
})
test('should abort on 404 in V2 Signature PUT promise should reject with reason', (t) => {
t.context.retry = function (type) {
return type === 'part'
}
t.context.errorStatus = 404
return testV2Authorization(t)
.then(function () {
t.fail('Cancel promise should have rejected, but did not.')
},
function (reason) {
expect(reason).to.match(/part failing to upload/i)
})
})
test('should return error when ABORT fails and call the correct signing url', (t) => {
t.context.retry = function (type) {
return type === 'part'
}
t.context.errorStatus = 404
t.context.deleteStatus = 403
return testV2Authorization(t)
.then(function () {
t.fail('Expected an error but found none: ' + t.context.testId)
}, function (reason) {
expect(headersForMethod(t, 'GET', /\/signv2.*$/).testId).to.equal(t.context.testId)
}
)
})
test('should return error when ABORT fails and return error messages (1)', (t) => {
t.context.retry = function (type) {
return type === 'part'
}
t.context.errorStatus = 404
t.context.deleteStatus = 403
return testV2Authorization(t)
.then(function () {
t.fail('Expected an error but found none: ' + t.context.testId)
}, function (reason) {
expect(t.context.errMessages.join(',')).to.match(/status:403/)
}
)
})
test('should return error when listParts fails in Abort after part upload failure (404) and call the signing url', (t) => {
t.context.retry = function (type) {
return type === 'part'
}
t.context.errorStatus = 404
t.context.getPartsStatus = 403
return testV2Authorization(t)
.then(function () {
t.fail('Expected an error but found none: ' + t.context.testId)
},
function (reason) {
expect(headersForMethod(t, 'GET', /\/signv2.*$/).testId).to.equal(t.context.testId)
})
})
test('should return error when listParts fails in Abort after part upload failure (404) and return error messages (1)', (t) => {
t.context.retry = function (type) {
return type === 'part'
}
t.context.errorStatus = 404
t.context.getPartsStatus = 403
return testV2Authorization(t)
.then(function () {
t.fail('Expected an error but found none: ' + t.context.testId)
},
function (reason) {
expect(t.context.errMessages.join(',')).to.match(/404 error on part PUT\. The part and the file will abort/i)
})
})
// signParams and signHeaders
test('should apply signParams in the V2 signature request', (t) => {
return testV2Authorization(t, {
awsSignatureVersion: '2',
signParams: { 'signing-auth': 'token' }
})
.then(function () {
expect(testRequests[t.context.testId][0].url).to.match(/signing-auth=token/)
})
})
test('should pass signHeaders to the V2 signature request', (t) => {
return testV2Authorization(t, {
awsSignatureVersion: '2',
signHeaders: { 'signing-auth': 'token' }
})
.then(function () {
expect(headersForMethod(t, 'GET', /\/sign.*$/)['signing-auth']).to.equal('token')
})
})
test('should apply signParams in the V4 signature request', (t) => {
return testV4Authorization(t, {
awsSignatureVersion: '2',
signParams: { 'signing-auth': 'token' }
})
.then(function () {
expect(testRequests[t.context.testId][0].url).to.match(/signing-auth=token/)
})
})
test('should pass signHeaders to the V4 signature request', (t) => {
return testV4Authorization(t, {
awsSignatureVersion: '2',
signHeaders: { 'signing-auth': 'token' }
})
.then(function () {
expect(headersForMethod(t, 'GET', /\/sign.*$/)['signing-auth']).to.equal('token')
})
})