@storybook/manager-api 7.0.19 → 7.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +9 -9
- package/src/tests/addons.test.js +167 -0
- package/src/tests/layout.test.js +168 -0
- package/src/tests/notifications.test.js +35 -0
- package/src/tests/shortcut.test.js +111 -0
- package/src/tests/shortcuts.test.js +287 -0
- package/src/tests/store.test.js +153 -0
- package/src/tests/url.test.js +211 -0
- package/src/tests/versions.test.js +397 -0
- package/src/typings.d.ts +14 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { themes } from '@storybook/theming';
|
|
2
|
+
import { init as initLayout } from '../modules/layout';
|
|
3
|
+
|
|
4
|
+
let layoutApi;
|
|
5
|
+
let store;
|
|
6
|
+
let provider;
|
|
7
|
+
let currentState;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
currentState = {
|
|
11
|
+
ui: {
|
|
12
|
+
enableShortcuts: true,
|
|
13
|
+
},
|
|
14
|
+
layout: {
|
|
15
|
+
showToolbar: true,
|
|
16
|
+
isFullscreen: false,
|
|
17
|
+
showPanel: true,
|
|
18
|
+
showNav: true,
|
|
19
|
+
panelPosition: 'bottom',
|
|
20
|
+
},
|
|
21
|
+
selectedPanel: 'storybook/actions/panel',
|
|
22
|
+
theme: themes.light,
|
|
23
|
+
};
|
|
24
|
+
store = {
|
|
25
|
+
getState: () => currentState,
|
|
26
|
+
setState: jest.fn((patch) => {
|
|
27
|
+
currentState = {
|
|
28
|
+
...currentState,
|
|
29
|
+
...(typeof patch === 'function' ? patch(currentState) : patch),
|
|
30
|
+
};
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
provider = { getConfig: jest.fn(() => ({})) };
|
|
34
|
+
layoutApi = initLayout({ store, provider }).api;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('layout API', () => {
|
|
38
|
+
describe('toggleFullscreen', () => {
|
|
39
|
+
it('should toggle isFullscreen', () => {
|
|
40
|
+
currentState.layout.isFullscreen = false;
|
|
41
|
+
layoutApi.toggleFullscreen();
|
|
42
|
+
expect(currentState.layout.isFullscreen).toBe(true);
|
|
43
|
+
layoutApi.toggleFullscreen();
|
|
44
|
+
expect(currentState.layout.isFullscreen).toBe(false);
|
|
45
|
+
layoutApi.toggleFullscreen(false);
|
|
46
|
+
expect(currentState.layout.isFullscreen).toBe(false);
|
|
47
|
+
layoutApi.toggleFullscreen(true);
|
|
48
|
+
expect(currentState.layout.isFullscreen).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should not affect nav or panel state when enabling fullscreen', () => {
|
|
52
|
+
currentState.layout.isFullscreen = false;
|
|
53
|
+
layoutApi.toggleFullscreen();
|
|
54
|
+
expect(currentState.layout.showNav).toBe(true);
|
|
55
|
+
expect(currentState.layout.showNav).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should enable nav when exiting fullscreen', () => {
|
|
59
|
+
currentState.layout.isFullscreen = true;
|
|
60
|
+
currentState.layout.showNav = false;
|
|
61
|
+
layoutApi.toggleFullscreen();
|
|
62
|
+
expect(currentState.layout).toEqual(
|
|
63
|
+
expect.objectContaining({
|
|
64
|
+
isFullscreen: false,
|
|
65
|
+
showPanel: true,
|
|
66
|
+
showNav: true,
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('singleStory=true', () => {
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
layoutApi = initLayout({ store, provider, singleStory: true }).api;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should NOT enable nav when exiting fullscreen', () => {
|
|
77
|
+
currentState.layout.showNav = false;
|
|
78
|
+
layoutApi.toggleFullscreen();
|
|
79
|
+
expect(currentState.layout).toEqual(
|
|
80
|
+
expect.objectContaining({
|
|
81
|
+
isFullscreen: true,
|
|
82
|
+
showPanel: true,
|
|
83
|
+
showNav: false,
|
|
84
|
+
})
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('toggleNav', () => {
|
|
91
|
+
it('should toggle showNav', () => {
|
|
92
|
+
currentState.layout.showNav = true;
|
|
93
|
+
layoutApi.toggleNav();
|
|
94
|
+
expect(currentState.layout.showNav).toBe(false);
|
|
95
|
+
layoutApi.toggleNav();
|
|
96
|
+
expect(currentState.layout.showNav).toBe(true);
|
|
97
|
+
layoutApi.toggleNav(true);
|
|
98
|
+
expect(currentState.layout.showNav).toBe(true);
|
|
99
|
+
layoutApi.toggleNav(false);
|
|
100
|
+
expect(currentState.layout.showNav).toBe(false);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('singleStory=true', () => {
|
|
104
|
+
beforeEach(() => {
|
|
105
|
+
layoutApi = initLayout({ store, provider, singleStory: true }).api;
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should NOT toggle showNav', () => {
|
|
109
|
+
currentState.layout.showNav = false;
|
|
110
|
+
layoutApi.toggleNav();
|
|
111
|
+
expect(currentState.layout.showNav).toBe(false);
|
|
112
|
+
layoutApi.toggleNav(true);
|
|
113
|
+
expect(currentState.layout.showNav).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('setOptions', () => {
|
|
119
|
+
const getLastSetStateArgs = () => {
|
|
120
|
+
const { calls } = store.setState.mock;
|
|
121
|
+
return calls[calls.length - 1];
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
it('should not change selectedPanel if it is undefined in the options', () => {
|
|
125
|
+
layoutApi.setOptions({});
|
|
126
|
+
|
|
127
|
+
expect(getLastSetStateArgs()).toBeUndefined();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('should not change selectedPanel if it is undefined in the options, but something else has changed', () => {
|
|
131
|
+
layoutApi.setOptions({ panelPosition: 'right' });
|
|
132
|
+
|
|
133
|
+
expect(getLastSetStateArgs()[0].selectedPanel).toBeUndefined();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should not change selectedPanel if it is currently the same', () => {
|
|
137
|
+
const panelName = currentState.selectedPanel;
|
|
138
|
+
layoutApi.setOptions({});
|
|
139
|
+
// second call is needed to overwrite initial layout
|
|
140
|
+
layoutApi.setOptions({ selectedPanel: panelName });
|
|
141
|
+
|
|
142
|
+
expect(getLastSetStateArgs()).toBeUndefined();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should not change selectedPanel if it is currently the same, but something else has changed', () => {
|
|
146
|
+
layoutApi.setOptions({});
|
|
147
|
+
// second call is needed to overwrite initial layout
|
|
148
|
+
layoutApi.setOptions({ panelPosition: 'right', selectedPanel: currentState.selectedPanel });
|
|
149
|
+
|
|
150
|
+
expect(getLastSetStateArgs()[0].selectedPanel).toBeUndefined();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should set selectedPanel initially', () => {
|
|
154
|
+
const panelName = 'storybook/a11y/panel';
|
|
155
|
+
layoutApi.setOptions({ selectedPanel: panelName });
|
|
156
|
+
|
|
157
|
+
expect(getLastSetStateArgs()[0].selectedPanel).toEqual(panelName);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should change selectedPanel if it is defined in the options and is different', () => {
|
|
161
|
+
const panelName = 'storybook/a11y/panel';
|
|
162
|
+
layoutApi.setOptions({});
|
|
163
|
+
layoutApi.setOptions({ selectedPanel: panelName });
|
|
164
|
+
|
|
165
|
+
expect(getLastSetStateArgs()[0].selectedPanel).toEqual(panelName);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { init as initNotifications } from '../modules/notifications';
|
|
2
|
+
|
|
3
|
+
describe('notifications API', () => {
|
|
4
|
+
it('allows adding notifications', () => {
|
|
5
|
+
const store = {
|
|
6
|
+
getState: () => ({
|
|
7
|
+
notifications: [],
|
|
8
|
+
}),
|
|
9
|
+
setState: jest.fn(),
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const { api } = initNotifications({ store });
|
|
13
|
+
|
|
14
|
+
api.addNotification({ id: '1' });
|
|
15
|
+
expect(store.setState).toHaveBeenCalledWith({
|
|
16
|
+
notifications: [{ id: '1' }],
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('allows removing notifications', () => {
|
|
21
|
+
const store = {
|
|
22
|
+
getState: () => ({
|
|
23
|
+
notifications: [{ id: '1' }, { id: '2' }, { id: '3' }],
|
|
24
|
+
}),
|
|
25
|
+
setState: jest.fn(),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const { api } = initNotifications({ store });
|
|
29
|
+
|
|
30
|
+
api.clearNotification('2');
|
|
31
|
+
expect(store.setState).toHaveBeenCalledWith({
|
|
32
|
+
notifications: [{ id: '1' }, { id: '3' }],
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { global } from '@storybook/global';
|
|
6
|
+
import { eventToShortcut, keyToSymbol } from '../lib/shortcut';
|
|
7
|
+
|
|
8
|
+
const { KeyboardEvent } = global;
|
|
9
|
+
const ev = (attr) => new KeyboardEvent('keydown', { ...attr });
|
|
10
|
+
|
|
11
|
+
describe('eventToShortcut', () => {
|
|
12
|
+
test('it handles alt key inputs', () => {
|
|
13
|
+
const output = eventToShortcut(ev({ altKey: true, key: 'Alt' }));
|
|
14
|
+
|
|
15
|
+
expect(output).toEqual(null);
|
|
16
|
+
});
|
|
17
|
+
test('it handles ctrl key inputs', () => {
|
|
18
|
+
const output = eventToShortcut(ev({ ctrlKey: true, key: 'Control' }));
|
|
19
|
+
expect(output).toEqual(null);
|
|
20
|
+
});
|
|
21
|
+
test('it handles meta key inputs', () => {
|
|
22
|
+
const output = eventToShortcut(ev({ metaKey: true, key: 'Meta' }));
|
|
23
|
+
expect(output).toEqual(null);
|
|
24
|
+
});
|
|
25
|
+
test('it handles shift key inputs', () => {
|
|
26
|
+
const output = eventToShortcut(ev({ shiftKey: true, key: 'Shift' }));
|
|
27
|
+
expect(output).toEqual(null);
|
|
28
|
+
});
|
|
29
|
+
test('it handles enter key inputs', () => {
|
|
30
|
+
const output = eventToShortcut(ev({ key: 'Enter' }));
|
|
31
|
+
expect(output).toEqual(null);
|
|
32
|
+
});
|
|
33
|
+
test('it handles tab key inputs', () => {
|
|
34
|
+
const output = eventToShortcut(ev({ key: 'Tab' }));
|
|
35
|
+
expect(output).toEqual(null);
|
|
36
|
+
});
|
|
37
|
+
test('it handles space bar inputs', () => {
|
|
38
|
+
const output = eventToShortcut(ev({ key: ' ' }));
|
|
39
|
+
expect(output).toEqual(['space']);
|
|
40
|
+
});
|
|
41
|
+
test('it handles escape inputs', () => {
|
|
42
|
+
const output = eventToShortcut(ev({ key: 'Escape' }));
|
|
43
|
+
expect(output).toEqual(['escape']);
|
|
44
|
+
});
|
|
45
|
+
test('it capitalizes a letter key through', () => {
|
|
46
|
+
const output = eventToShortcut(ev({ key: 'a', code: 'KeyA' }));
|
|
47
|
+
expect(output).toEqual(['A']);
|
|
48
|
+
});
|
|
49
|
+
test('it passes regular key through', () => {
|
|
50
|
+
const output = eventToShortcut(ev({ key: '1', code: 'Digit1' }));
|
|
51
|
+
expect(output).toEqual(['1']);
|
|
52
|
+
});
|
|
53
|
+
test('it passes modified regular key through', () => {
|
|
54
|
+
const output = eventToShortcut(ev({ altKey: true, key: '1', code: 'Digit1' }));
|
|
55
|
+
expect(output).toEqual(['alt', '1']);
|
|
56
|
+
// on macos
|
|
57
|
+
const outputMacOs = eventToShortcut(ev({ altKey: true, key: '√', code: 'KeyV' }));
|
|
58
|
+
expect(outputMacOs).toEqual(['alt', ['√', 'V']]);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('keyToSymbol', () => {
|
|
63
|
+
test('control returns a caret', () => {
|
|
64
|
+
const result = keyToSymbol('control');
|
|
65
|
+
expect(result).toBe('⌃');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('meta returns ⌘', () => {
|
|
69
|
+
const result = keyToSymbol('meta');
|
|
70
|
+
expect(result).toEqual('⌘');
|
|
71
|
+
});
|
|
72
|
+
test('shift returns ⇧', () => {
|
|
73
|
+
const result = keyToSymbol('shift');
|
|
74
|
+
expect(result).toBe('⇧');
|
|
75
|
+
});
|
|
76
|
+
test('enter returns an empty string', () => {
|
|
77
|
+
const result = keyToSymbol('Enter');
|
|
78
|
+
expect(result).toBe('');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("' ' returns SPACE", () => {
|
|
82
|
+
const result = keyToSymbol(' ');
|
|
83
|
+
expect(result).toEqual('SPACE');
|
|
84
|
+
});
|
|
85
|
+
test('escape returns esc', () => {
|
|
86
|
+
const result = keyToSymbol('escape');
|
|
87
|
+
expect(result).toEqual('');
|
|
88
|
+
});
|
|
89
|
+
test('ArrowUp returns ↑', () => {
|
|
90
|
+
const result = keyToSymbol('ArrowUp');
|
|
91
|
+
expect(result).toBe('↑');
|
|
92
|
+
});
|
|
93
|
+
test('ArrowDown returns ↓', () => {
|
|
94
|
+
const result = keyToSymbol('ArrowDown');
|
|
95
|
+
expect(result).toBe('↓');
|
|
96
|
+
});
|
|
97
|
+
test('ArrowLeft returns ←', () => {
|
|
98
|
+
const result = keyToSymbol('ArrowLeft');
|
|
99
|
+
expect(result).toBe('←');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('ArrowRight returns →', () => {
|
|
103
|
+
const result = keyToSymbol('ArrowRight');
|
|
104
|
+
expect(result).toBe('→');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('it capitalizes a lowercase key', () => {
|
|
108
|
+
const output = keyToSymbol('a');
|
|
109
|
+
expect(output).toBe('A');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { init as initShortcuts } from '../modules/shortcuts';
|
|
2
|
+
|
|
3
|
+
function createMockStore() {
|
|
4
|
+
let state = {};
|
|
5
|
+
return {
|
|
6
|
+
getState: jest.fn().mockImplementation(() => state),
|
|
7
|
+
setState: jest.fn().mockImplementation((s) => {
|
|
8
|
+
state = { ...state, ...s };
|
|
9
|
+
}),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const mockAddonShortcut = {
|
|
14
|
+
addon: 'my-addon',
|
|
15
|
+
shortcut: {
|
|
16
|
+
label: 'Do something',
|
|
17
|
+
defaultShortcut: ['O'],
|
|
18
|
+
actionName: 'doSomething',
|
|
19
|
+
action: () => {
|
|
20
|
+
//
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const mockAddonSecondShortcut = {
|
|
26
|
+
addon: 'my-addon',
|
|
27
|
+
shortcut: {
|
|
28
|
+
label: 'Do something else',
|
|
29
|
+
defaultShortcut: ['P'],
|
|
30
|
+
actionName: 'doSomethingElse',
|
|
31
|
+
action: () => {
|
|
32
|
+
//
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const mockSecondAddonShortcut = {
|
|
38
|
+
addon: 'my-other-addon',
|
|
39
|
+
shortcut: {
|
|
40
|
+
label: 'Create issue',
|
|
41
|
+
defaultShortcut: ['N'],
|
|
42
|
+
actionName: 'createIssue',
|
|
43
|
+
action: () => {
|
|
44
|
+
//
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
describe('shortcuts api', () => {
|
|
50
|
+
it('gets defaults', () => {
|
|
51
|
+
const store = createMockStore();
|
|
52
|
+
|
|
53
|
+
const { api, state } = initShortcuts({ store });
|
|
54
|
+
store.setState(state);
|
|
55
|
+
|
|
56
|
+
expect(api.getDefaultShortcuts()).toHaveProperty('fullScreen', ['F']);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('gets defaults including addon ones', async () => {
|
|
60
|
+
const store = createMockStore();
|
|
61
|
+
|
|
62
|
+
const { api, state } = initShortcuts({ store });
|
|
63
|
+
store.setState(state);
|
|
64
|
+
|
|
65
|
+
await api.setAddonShortcut(mockAddonShortcut.addon, mockAddonShortcut.shortcut);
|
|
66
|
+
await api.setAddonShortcut(mockAddonSecondShortcut.addon, mockAddonSecondShortcut.shortcut);
|
|
67
|
+
await api.setAddonShortcut(mockSecondAddonShortcut.addon, mockSecondAddonShortcut.shortcut);
|
|
68
|
+
|
|
69
|
+
expect(api.getDefaultShortcuts()).toHaveProperty('fullScreen', ['F']);
|
|
70
|
+
expect(api.getDefaultShortcuts()).toHaveProperty(
|
|
71
|
+
`${mockAddonShortcut.addon}-${mockAddonShortcut.shortcut.actionName}`,
|
|
72
|
+
mockAddonShortcut.shortcut.defaultShortcut
|
|
73
|
+
);
|
|
74
|
+
expect(api.getDefaultShortcuts()).toHaveProperty(
|
|
75
|
+
`${mockAddonSecondShortcut.addon}-${mockAddonSecondShortcut.shortcut.actionName}`,
|
|
76
|
+
mockAddonSecondShortcut.shortcut.defaultShortcut
|
|
77
|
+
);
|
|
78
|
+
expect(api.getDefaultShortcuts()).toHaveProperty(
|
|
79
|
+
`${mockSecondAddonShortcut.addon}-${mockSecondAddonShortcut.shortcut.actionName}`,
|
|
80
|
+
mockSecondAddonShortcut.shortcut.defaultShortcut
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('gets addons shortcuts', async () => {
|
|
85
|
+
const store = createMockStore();
|
|
86
|
+
|
|
87
|
+
const { api, state } = initShortcuts({ store });
|
|
88
|
+
store.setState(state);
|
|
89
|
+
|
|
90
|
+
await api.setAddonShortcut(mockAddonShortcut.addon, mockAddonShortcut.shortcut);
|
|
91
|
+
await api.setAddonShortcut(mockAddonSecondShortcut.addon, mockAddonSecondShortcut.shortcut);
|
|
92
|
+
await api.setAddonShortcut(mockSecondAddonShortcut.addon, mockSecondAddonShortcut.shortcut);
|
|
93
|
+
|
|
94
|
+
expect(api.getAddonsShortcuts()).toStrictEqual({
|
|
95
|
+
[`${mockAddonShortcut.addon}-${mockAddonShortcut.shortcut.actionName}`]:
|
|
96
|
+
mockAddonShortcut.shortcut,
|
|
97
|
+
[`${mockAddonSecondShortcut.addon}-${mockAddonSecondShortcut.shortcut.actionName}`]:
|
|
98
|
+
mockAddonSecondShortcut.shortcut,
|
|
99
|
+
[`${mockSecondAddonShortcut.addon}-${mockSecondAddonShortcut.shortcut.actionName}`]:
|
|
100
|
+
mockSecondAddonShortcut.shortcut,
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('gets addons shortcut labels', async () => {
|
|
105
|
+
const store = createMockStore();
|
|
106
|
+
|
|
107
|
+
const { api, state } = initShortcuts({ store });
|
|
108
|
+
store.setState(state);
|
|
109
|
+
|
|
110
|
+
await api.setAddonShortcut(mockAddonShortcut.addon, mockAddonShortcut.shortcut);
|
|
111
|
+
await api.setAddonShortcut(mockAddonSecondShortcut.addon, mockAddonSecondShortcut.shortcut);
|
|
112
|
+
await api.setAddonShortcut(mockSecondAddonShortcut.addon, mockSecondAddonShortcut.shortcut);
|
|
113
|
+
|
|
114
|
+
expect(api.getAddonsShortcutLabels()).toStrictEqual({
|
|
115
|
+
[`${mockAddonShortcut.addon}-${mockAddonShortcut.shortcut.actionName}`]:
|
|
116
|
+
mockAddonShortcut.shortcut.label,
|
|
117
|
+
[`${mockAddonSecondShortcut.addon}-${mockAddonSecondShortcut.shortcut.actionName}`]:
|
|
118
|
+
mockAddonSecondShortcut.shortcut.label,
|
|
119
|
+
[`${mockSecondAddonShortcut.addon}-${mockSecondAddonShortcut.shortcut.actionName}`]:
|
|
120
|
+
mockSecondAddonShortcut.shortcut.label,
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('gets addons shortcut defaults', async () => {
|
|
125
|
+
const store = createMockStore();
|
|
126
|
+
|
|
127
|
+
const { api, state } = initShortcuts({ store });
|
|
128
|
+
store.setState(state);
|
|
129
|
+
|
|
130
|
+
await api.setAddonShortcut(mockAddonShortcut.addon, mockAddonShortcut.shortcut);
|
|
131
|
+
await api.setAddonShortcut(mockAddonSecondShortcut.addon, mockAddonSecondShortcut.shortcut);
|
|
132
|
+
await api.setAddonShortcut(mockSecondAddonShortcut.addon, mockSecondAddonShortcut.shortcut);
|
|
133
|
+
|
|
134
|
+
expect(api.getAddonsShortcutDefaults()).toStrictEqual({
|
|
135
|
+
[`${mockAddonShortcut.addon}-${mockAddonShortcut.shortcut.actionName}`]:
|
|
136
|
+
mockAddonShortcut.shortcut.defaultShortcut,
|
|
137
|
+
[`${mockAddonSecondShortcut.addon}-${mockAddonSecondShortcut.shortcut.actionName}`]:
|
|
138
|
+
mockAddonSecondShortcut.shortcut.defaultShortcut,
|
|
139
|
+
[`${mockSecondAddonShortcut.addon}-${mockSecondAddonShortcut.shortcut.actionName}`]:
|
|
140
|
+
mockSecondAddonShortcut.shortcut.defaultShortcut,
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('sets defaults', () => {
|
|
145
|
+
const store = createMockStore();
|
|
146
|
+
|
|
147
|
+
const { api, state } = initShortcuts({ store });
|
|
148
|
+
store.setState(state);
|
|
149
|
+
|
|
150
|
+
expect(api.getShortcutKeys().fullScreen).toEqual(['F']);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('sets addon shortcut with default value', async () => {
|
|
154
|
+
const store = createMockStore();
|
|
155
|
+
|
|
156
|
+
const { api, state } = initShortcuts({ store });
|
|
157
|
+
store.setState(state);
|
|
158
|
+
|
|
159
|
+
await api.setAddonShortcut(mockAddonShortcut.addon, mockAddonShortcut.shortcut);
|
|
160
|
+
await api.setAddonShortcut(mockAddonSecondShortcut.addon, mockAddonSecondShortcut.shortcut);
|
|
161
|
+
await api.setAddonShortcut(mockSecondAddonShortcut.addon, mockSecondAddonShortcut.shortcut);
|
|
162
|
+
|
|
163
|
+
expect(api.getDefaultShortcuts()).toHaveProperty('fullScreen', ['F']);
|
|
164
|
+
expect(api.getDefaultShortcuts()).toHaveProperty(
|
|
165
|
+
`${mockAddonShortcut.addon}-${mockAddonShortcut.shortcut.actionName}`,
|
|
166
|
+
mockAddonShortcut.shortcut.defaultShortcut
|
|
167
|
+
);
|
|
168
|
+
expect(api.getDefaultShortcuts()).toHaveProperty(
|
|
169
|
+
`${mockAddonSecondShortcut.addon}-${mockAddonSecondShortcut.shortcut.actionName}`,
|
|
170
|
+
mockAddonSecondShortcut.shortcut.defaultShortcut
|
|
171
|
+
);
|
|
172
|
+
expect(api.getDefaultShortcuts()).toHaveProperty(
|
|
173
|
+
`${mockSecondAddonShortcut.addon}-${mockSecondAddonShortcut.shortcut.actionName}`,
|
|
174
|
+
mockSecondAddonShortcut.shortcut.defaultShortcut
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('sets defaults, augmenting anything that was persisted', () => {
|
|
179
|
+
const store = createMockStore();
|
|
180
|
+
store.setState({ shortcuts: { fullScreen: ['Z'] } });
|
|
181
|
+
|
|
182
|
+
const { api, state } = initShortcuts({ store });
|
|
183
|
+
store.setState(state);
|
|
184
|
+
|
|
185
|
+
expect(api.getShortcutKeys().fullScreen).toEqual(['Z']);
|
|
186
|
+
expect(api.getShortcutKeys().togglePanel).toEqual(['A']);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('sets defaults, ignoring anything persisted that is out of date', () => {
|
|
190
|
+
const store = createMockStore();
|
|
191
|
+
store.setState({ shortcuts: { randomKey: ['Z'] } });
|
|
192
|
+
|
|
193
|
+
const { api, state } = initShortcuts({ store });
|
|
194
|
+
store.setState(state);
|
|
195
|
+
|
|
196
|
+
expect(api.getShortcutKeys().randomKey).not.toBeDefined();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('sets new values', async () => {
|
|
200
|
+
const store = createMockStore();
|
|
201
|
+
|
|
202
|
+
const { api, state } = initShortcuts({ store });
|
|
203
|
+
store.setState(state);
|
|
204
|
+
|
|
205
|
+
await api.setShortcut('fullScreen', ['X']);
|
|
206
|
+
expect(api.getShortcutKeys().fullScreen).toEqual(['X']);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('sets new values for addon shortcuts', async () => {
|
|
210
|
+
const store = createMockStore();
|
|
211
|
+
|
|
212
|
+
const { api, state } = initShortcuts({ store });
|
|
213
|
+
store.setState(state);
|
|
214
|
+
|
|
215
|
+
const { addon, shortcut } = mockAddonShortcut;
|
|
216
|
+
await api.setAddonShortcut(addon, shortcut);
|
|
217
|
+
|
|
218
|
+
await api.setShortcut(`${addon}-${shortcut.actionName}`, ['I']);
|
|
219
|
+
expect(api.getShortcutKeys()[`${addon}-${shortcut.actionName}`]).toEqual(['I']);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('restores all defaults', async () => {
|
|
223
|
+
const store = createMockStore();
|
|
224
|
+
|
|
225
|
+
const { api, state } = initShortcuts({ store });
|
|
226
|
+
store.setState(state);
|
|
227
|
+
|
|
228
|
+
const { addon, shortcut } = mockAddonShortcut;
|
|
229
|
+
await api.setAddonShortcut(addon, shortcut);
|
|
230
|
+
|
|
231
|
+
await api.setShortcut('fullScreen', ['X']);
|
|
232
|
+
await api.setShortcut('togglePanel', ['B']);
|
|
233
|
+
await api.setShortcut(`${addon}-${shortcut.actionName}`, ['I']);
|
|
234
|
+
|
|
235
|
+
await api.restoreAllDefaultShortcuts();
|
|
236
|
+
expect(api.getShortcutKeys().fullScreen).toEqual(['F']);
|
|
237
|
+
expect(api.getShortcutKeys().togglePanel).toEqual(['A']);
|
|
238
|
+
expect(api.getShortcutKeys()[`${addon}-${shortcut.actionName}`]).toEqual(
|
|
239
|
+
shortcut.defaultShortcut
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('restores single default', async () => {
|
|
244
|
+
const store = createMockStore();
|
|
245
|
+
|
|
246
|
+
const { api, state } = initShortcuts({ store });
|
|
247
|
+
store.setState(state);
|
|
248
|
+
|
|
249
|
+
await api.setAddonShortcut(mockAddonShortcut.addon, mockAddonShortcut.shortcut);
|
|
250
|
+
await api.setAddonShortcut(mockAddonSecondShortcut.addon, mockAddonSecondShortcut.shortcut);
|
|
251
|
+
await api.setAddonShortcut(mockSecondAddonShortcut.addon, mockSecondAddonShortcut.shortcut);
|
|
252
|
+
|
|
253
|
+
await api.setShortcut('fullScreen', ['X']);
|
|
254
|
+
await api.setShortcut('togglePanel', ['B']);
|
|
255
|
+
await api.setShortcut(`${mockAddonShortcut.addon}-${mockAddonShortcut.shortcut.actionName}`, [
|
|
256
|
+
'I',
|
|
257
|
+
]);
|
|
258
|
+
await api.setShortcut(
|
|
259
|
+
`${mockAddonSecondShortcut.addon}-${mockAddonSecondShortcut.shortcut.actionName}`,
|
|
260
|
+
['H']
|
|
261
|
+
);
|
|
262
|
+
await api.setShortcut(
|
|
263
|
+
`${mockSecondAddonShortcut.addon}-${mockSecondAddonShortcut.shortcut.actionName}`,
|
|
264
|
+
['G']
|
|
265
|
+
);
|
|
266
|
+
await api.restoreDefaultShortcut('fullScreen');
|
|
267
|
+
await api.restoreDefaultShortcut(
|
|
268
|
+
`${mockAddonShortcut.addon}-${mockAddonShortcut.shortcut.actionName}`
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
expect(api.getShortcutKeys().fullScreen).toEqual(['F']);
|
|
272
|
+
expect(api.getShortcutKeys().togglePanel).toEqual(['B']);
|
|
273
|
+
expect(
|
|
274
|
+
api.getShortcutKeys()[`${mockAddonShortcut.addon}-${mockAddonShortcut.shortcut.actionName}`]
|
|
275
|
+
).toEqual(mockAddonShortcut.shortcut.defaultShortcut);
|
|
276
|
+
expect(
|
|
277
|
+
api.getShortcutKeys()[
|
|
278
|
+
`${mockAddonSecondShortcut.addon}-${mockAddonSecondShortcut.shortcut.actionName}`
|
|
279
|
+
]
|
|
280
|
+
).toEqual(['H']);
|
|
281
|
+
expect(
|
|
282
|
+
api.getShortcutKeys()[
|
|
283
|
+
`${mockSecondAddonShortcut.addon}-${mockSecondAddonShortcut.shortcut.actionName}`
|
|
284
|
+
]
|
|
285
|
+
).toEqual(['G']);
|
|
286
|
+
});
|
|
287
|
+
});
|