PluginProbe
Extendify / 3.1.1
Extendify v3.1.1
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / tests / unit / QuickEdit / lib / hover-bar.translated.test.js

hover-bar.translated.test.js in Extendify 3.1.1, at tests/unit/QuickEdit/lib/hover-bar.translated.test.js

154 lines 4.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // The hover bar's translated-content guard. On a non-default-language render,
2 // clicking the Quick Edit pill on a text block must (a) show the error right
3 // under the bar — not a top-right pill the Agent sidebar would hide — and
4 // (b) never commit a selection (which renders nothing and, worse, the
5 // unsubSelected cancel-on-clear logic would tear down a co-staged Ask AI
6 // block). The bar (and its Ask AI pill) stays put.
7
8 const mockSetSelected = jest.fn();
9 const mockSetCommittedSelection = jest.fn();
10 let mockStoreState;
11
12 jest.mock('@quick-edit/state/edit-mode', () => ({
13 useEditModeStore: {
14 getState: () => ({ on: true }),
15 subscribe: () => () => {},
16 },
17 }));
18 jest.mock('@quick-edit/state/store', () => ({
19 useQuickEditStore: {
20 getState: () => mockStoreState,
21 subscribe: () => () => {},
22 setState: () => {},
23 },
24 }));
25 jest.mock('@quick-edit/lib/dom', () => ({
26 resolveTarget: (el) => ({
27 el,
28 blockType: el?.dataset?.blockType || 'core/heading',
29 blockId: 1,
30 source: { kind: 'post', id: 1 },
31 }),
32 }));
33 jest.mock('@quick-edit/lib/quick-edit-handlers', () => ({
34 hasQuickEditModalFor: () => true,
35 }));
36 jest.mock('@quick-edit/lib/ask-ai', () => ({
37 isAgentAvailable: () => false,
38 isAgentSidebarOpen: () => false,
39 hasAgentBlockSelected: () => false,
40 askAiAboutElement: jest.fn(),
41 stageAgentBlock: jest.fn(),
42 subscribeToAgentBlock: () => () => {},
43 }));
44 jest.mock('@quick-edit/lib/agent-gate', () => ({
45 isAgentEligibleForTarget: () => false,
46 }));
47 jest.mock('@quick-edit/lib/block-source-cache', () => ({
48 prefetchBlockSource: jest.fn(),
49 }));
50 jest.mock('@quick-edit/lib/click-rule', () => ({
51 decideClickAction: () => ({ action: 'ignore' }),
52 }));
53 jest.mock('@quick-edit/lib/insights', () => ({ track: jest.fn() }));
54 jest.mock('@quick-edit/lib/save-bridge', () => ({
55 hasSaver: () => false,
56 saveSelected: jest.fn(),
57 }));
58
59 const importBar = () => require('@quick-edit/lib/hover-bar');
60
61 const setTranslated = (isTranslated) => {
62 window.extQuickEditData = {
63 quickEditEnabled: true,
64 translatedContext: isTranslated
65 ? { isTranslated: true, plugin: 'translatepress' }
66 : { isTranslated: false, plugin: null },
67 };
68 };
69
70 const heading = () => {
71 const el = document.createElement('h2');
72 el.setAttribute('data-extendify-agent-block-id', '1');
73 el.getBoundingClientRect = () => ({
74 top: 100,
75 bottom: 140,
76 left: 50,
77 right: 250,
78 width: 200,
79 height: 40,
80 });
81 document.body.appendChild(el);
82 return el;
83 };
84
85 const qerPill = () =>
86 document.querySelector(
87 '.extendify-quick-edit-bar [data-extendify-quick-edit-pill]',
88 );
89
90 beforeEach(() => {
91 jest.useFakeTimers();
92 jest.resetModules();
93 jest.clearAllMocks();
94 document.body.innerHTML = '';
95 mockStoreState = {
96 selected: null,
97 committedSelection: null,
98 agentBlock: null,
99 setSelected: mockSetSelected,
100 setCommittedSelection: mockSetCommittedSelection,
101 clearSelected: jest.fn(),
102 };
103 });
104
105 afterEach(() => {
106 jest.runOnlyPendingTimers();
107 jest.useRealTimers();
108 delete window.extQuickEditData;
109 });
110
111 describe('hover-bar — translated text guard', () => {
112 it('Quick Edit pill on a translated text block shows the error under the bar and commits no selection', () => {
113 setTranslated(true);
114 const { showBar } = importBar();
115 showBar(heading());
116
117 const pill = qerPill();
118 expect(pill).not.toBeNull();
119 expect(pill.textContent).toContain('Quick Edit');
120
121 pill.click();
122
123 const alert = document.querySelector('[role="alert"]');
124 expect(alert).not.toBeNull();
125 expect(alert.textContent).toContain('TranslatePress');
126 expect(mockSetSelected).not.toHaveBeenCalled();
127 // The bar (and its Ask AI pill) stays mounted.
128 expect(document.querySelector('.extendify-quick-edit-bar')).not.toBeNull();
129 });
130
131 it('editTarget (block-click / keyboard) commits no selection for translated text', () => {
132 setTranslated(true);
133 const { editTarget } = importBar();
134 editTarget({
135 el: heading(),
136 blockType: 'core/heading',
137 blockId: 1,
138 source: { kind: 'post', id: 1 },
139 });
140 expect(mockSetSelected).not.toHaveBeenCalled();
141 });
142
143 it('on the default language the Quick Edit pill still commits a selection (no error)', () => {
144 setTranslated(false);
145 const { showBar } = importBar();
146 showBar(heading());
147
148 qerPill().click();
149
150 expect(mockSetSelected).toHaveBeenCalledTimes(1);
151 expect(document.querySelector('[role="alert"]')).toBeNull();
152 });
153 });
154