const assert = require('assert'); const proxyquire = require('proxyquire').noCallThru(); const stream = {}; class MockStorage { length() { return Promise.resolve(12); } getStream() { return stream; } set() { return Promise.resolve(); } del() { return Promise.resolve(); } ping() { return Promise.resolve(); } } const config = { s3_bucket: 'foo', default_expire_seconds: 20, expire_times_seconds: [10, 20, 30], env: 'development', redis_host: 'mock' }; const storage = proxyquire('../../server/storage', { '../config': config, '../log': () => {}, './s3': MockStorage }); describe('Storage', function() { describe('ttl', function() { it('returns milliseconds remaining', async function() { const time = 40; await storage.set('x', null, { foo: 'bar' }, time); const ms = await storage.ttl('x'); await storage.del('x'); assert.equal(ms, time * 1000); }); }); describe('length', function() { it('returns the file size', async function() { const len = await storage.length('x'); assert.equal(len, 12); }); }); describe('get', function() { it('returns a stream', async function() { const { stream: s } = await storage.get('x'); assert.equal(s, stream); }); }); describe('set', function() { it('sets expiration to expire time', async function() { const seconds = 100; await storage.set('x', null, { foo: 'bar' }, seconds); const s = await storage.redis.ttlAsync('x'); await storage.del('x'); assert.equal(Math.ceil(s), seconds); }); it('adds right prefix based on expire time', async function() { await storage.set('x', null, { foo: 'bar' }, 300); const { filePath: path_x } = await storage.getPrefixedInfo('x'); assert.equal(path_x, '1-x'); await storage.del('x'); await storage.set('y', null, { foo: 'bar' }, 86400); const { filePath: path_y } = await storage.getPrefixedInfo('y'); assert.equal(path_y, '1-y'); await storage.del('y'); await storage.set('z', null, { foo: 'bar' }, 86400 * 7); const { filePath: path_z } = await storage.getPrefixedInfo('z'); assert.equal(path_z, '7-z'); await storage.del('z'); }); it('sets metadata', async function() { const m = { foo: 'bar' }; await storage.set('x', null, m); const meta = await storage.redis.hgetallAsync('x'); delete meta.prefix; await storage.del('x'); assert.deepEqual(meta, m); }); }); describe('setField', function() { it('works', async function() { await storage.set('x', null); storage.setField('x', 'y', 'z'); const z = await storage.redis.hgetAsync('x', 'y'); assert.equal(z, 'z'); await storage.del('x'); }); }); describe('del', function() { it('works', async function() { await storage.set('x', null, { foo: 'bar' }); await storage.del('x'); const meta = await storage.metadata('x'); assert.equal(meta, null); }); }); describe('ping', function() { it('works', async function() { await storage.ping(); }); }); describe('metadata', function() { it('returns all metadata fields', async function() { const m = { id: 'a1', pwd: 0, dl: 1, dlimit: 1, fxa: 1, auth: 'foo', metadata: 'bar', nonce: 'baz', owner: 'bmo' }; await storage.set('x', null, m); const meta = await storage.metadata('x'); assert.deepEqual( { ...meta, storage: 'excluded' }, { ...m, dead: false, flagged: false, dlToken: 0, fxa: true, pwd: false, storage: 'excluded' } ); }); }); });