UNPKG

6.64 kBJavaScriptView Raw
1/* eslint-disable import/no-duplicates */
2import Storage from './storage__local';
3import FallbackStorage from './storage__fallback';
4
5import MockedStorage from 'imports-loader?window=storage-mock!./storage__local';
6
7function noop() {}
8
9function testStorage(storage) {
10 describe('set', () => {
11 it('should be fulfilled', () => storage.set('empty', {}).should.be.fulfilled);
12
13 it('should correctly set url incompatible characters', async () => {
14 await storage.set('test;', 'value;');
15 const value = await storage.get('test;');
16 value.should.equal('value;');
17 });
18
19 it('should fail on wrong input (e.g. on circular objects)', () => {
20 const circular = {};
21 circular.circular = circular;
22
23 return storage.set('circular', circular).should.be.rejected;
24 });
25 });
26
27 describe('get', () => {
28 const test = {a: 666};
29
30 it('should get items', async () => {
31 await storage.set('test2', test);
32 const value = await storage.get('test2');
33 value.should.deep.equal(test);
34 });
35
36 it('should not return same objects', async () => {
37 await storage.set('test', test);
38 const value = await storage.get('test');
39 value.should.not.equal(test);
40 });
41
42 it('should return null when there is no item', () => storage.get('test').should.become(null));
43 });
44
45 describe('remove', () => {
46 it('should remove present items', async () => {
47 await storage.set('empty', {});
48 await storage.remove('empty');
49 storage.get('empty').should.become(null);
50 });
51
52 it('should be fulfilled when is correct', async () => {
53 await storage.set('empty', {});
54 storage.remove('empty').
55 should.be.fulfilled;
56 });
57
58 it('should be fulfilled for missing element', () => (
59 storage.remove('missing').should.be.fulfilled
60 ));
61 });
62
63 describe('each', () => {
64 it('should be fulfilled', async () => {
65 await storage.set('test1', '');
66 storage.each(noop).
67 should.be.fulfilled;
68 });
69
70 it('should iterate over items', async () => {
71 const iterator = sandbox.stub();
72 await storage.set('test', 'value');
73 await storage.each(iterator);
74 iterator.should.have.been.calledWith('test', 'value');
75 });
76
77 it('should not iterate without items', async () => {
78 const iterator = sandbox.stub();
79 await storage.each(iterator);
80 iterator.should.not.been.called;
81 });
82
83 it('should iterate over all items', async () => {
84 const iterator = sandbox.stub();
85 await storage.set('test1', '');
86 await storage.set('test2', '');
87 await storage.set('test3', '');
88 await storage.each(iterator);
89 iterator.should.have.been.calledThrice;
90 });
91
92 it('should fail on wrong callback', async () => {
93 await storage.set('test', '');
94 storage.each().should.be.rejected;
95 });
96 });
97}
98
99function testStorageEvents(storage) {
100 describe('events', () => {
101 let stop;
102
103 afterEach(() => {
104 stop();
105 });
106
107 it('on after set should be fired', () => {
108 const testEvent = 'testKey';
109
110 const change = new Promise(resolve => {
111 stop = storage.on(testEvent, resolve);
112 });
113
114 storage.set(testEvent, 'testValue');
115
116 return change.should.be.fulfilled;
117 });
118
119 it('on after set should be fired with correct value', () => {
120 const testEvent = 'testKey2';
121 const testValue = 'testValue';
122
123 const change = new Promise(resolve => {
124 stop = storage.on(testEvent, resolve);
125 });
126
127 storage.set(testEvent, testValue);
128
129 return change.should.become(testValue);
130 });
131
132 it('on after remove should be fired with null', async () => {
133 const testEvent = 'testKey3';
134 const testValue = 'test2Value';
135
136 // Set test value and wait for it
137 storage.set(testEvent, testValue);
138
139 const disposer = await new Promise(resolve => {
140 const stopSetListening = storage.on(testEvent, () => {
141 resolve(stopSetListening);
142 });
143 });
144 disposer();
145
146 // Set up listening for test target change
147 const change = new Promise(resolve => {
148 stop = storage.on(testEvent, resolve);
149 });
150
151 // Trigger target remove action
152 storage.remove(testEvent);
153
154 change.should.become(null);
155 });
156
157 it('on after set with other key shouldn\'t be fired', () => {
158 const clock = sandbox.useFakeTimers({toFake: ['setTimeout']});
159 const spy = sandbox.stub();
160
161 stop = storage.on('testKey4', spy);
162 storage.set('testWrong', 'testValue');
163
164 clock.tick(1);
165 spy.should.not.have.been.called;
166 });
167
168 it('stop should stop', () => {
169 const clock = sandbox.useFakeTimers({toFake: ['setTimeout']});
170 const spy = sandbox.spy();
171
172 const testEvent = 'testKey5';
173 stop = storage.on(testEvent, spy);
174 stop();
175 storage.set(testEvent, 'testValue');
176
177 clock.tick(1);
178 spy.should.not.have.been.called;
179 });
180 });
181}
182
183describe('Storage', () => {
184 describe('Local', () => {
185 beforeEach(() => {
186 localStorage.clear();
187 sessionStorage.clear();
188 });
189
190 const storage = new Storage();
191 const storageSession = new Storage({
192 type: 'session'
193 });
194
195 describe('Long-term', () => {
196 testStorage(storage);
197 });
198 describe('Session', () => {
199 testStorage(storageSession);
200 });
201 testStorageEvents(new MockedStorage());
202
203 describe('specific', () => {
204 beforeEach(() => {
205 localStorage.setItem('invalid-json', 'invalid-json');
206 });
207
208 it('should get non-parseable values', () => (
209 storage.get('invalid-json').should.be.become('invalid-json')
210 ));
211
212 it('shouldn\'t break iteration on non-parseable values', () => storage.each(noop).should.be.fulfilled);
213
214 it('should iterate over items with non-parseable values', async () => {
215 const iterator = sandbox.stub();
216 await storage.set('test', 'value');
217 await storage.each(iterator);
218 iterator.should.have.been.calledWith('invalid-json', 'invalid-json');
219 });
220 });
221 });
222
223 describe('Fallback', () => {
224 const cookieName = 'testCookie';
225
226 beforeEach(() => {
227 document.cookie = `${cookieName}=;`;
228 });
229
230 const storage = new FallbackStorage({
231 cookieName,
232 checkDelay: 200
233 });
234
235 const storageSession = new FallbackStorage({
236 cookieName,
237 checkDelay: 200,
238 type: 'session'
239 });
240 describe('Long-term', () => {
241 testStorage(storage);
242 });
243 describe('Session', () => {
244 testStorage(storageSession);
245 });
246 testStorageEvents(storage);
247 });
248});