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 / state / store.test.js

store.test.js in Extendify 3.1.1, at tests/unit/QuickEdit/state/store.test.js

238 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useQuickEditStore } from '@quick-edit/state/store';
2
3 const initialState = useQuickEditStore.getState();
4
5 describe('useQuickEditStore', () => {
6 beforeEach(() => {
7 useQuickEditStore.setState({
8 hovered: null,
9 selected: null,
10 dirty: {},
11 saving: false,
12 error: null,
13 agentBlock: null,
14 agentBlockCode: null,
15 committedSelection: null,
16 });
17 });
18
19 describe('initial state', () => {
20 it('seeds with empty hover/select/dirty + idle flags', () => {
21 expect(initialState.hovered).toBeNull();
22 expect(initialState.selected).toBeNull();
23 expect(initialState.dirty).toEqual({});
24 expect(initialState.saving).toBe(false);
25 expect(initialState.error).toBeNull();
26 expect(initialState.agentBlock).toBeNull();
27 expect(initialState.agentBlockCode).toBeNull();
28 expect(initialState.committedSelection).toBeNull();
29 });
30 });
31
32 describe('setHovered', () => {
33 it('replaces hovered target', () => {
34 const { setHovered } = useQuickEditStore.getState();
35 setHovered({ blockId: 'b-1' });
36 expect(useQuickEditStore.getState().hovered).toEqual({ blockId: 'b-1' });
37 setHovered(null);
38 expect(useQuickEditStore.getState().hovered).toBeNull();
39 });
40
41 it('does not touch other slices', () => {
42 useQuickEditStore.setState({
43 selected: { blockId: 'b-1' },
44 dirty: { text: 'x' },
45 error: 'oops',
46 saving: true,
47 });
48 useQuickEditStore.getState().setHovered({ blockId: 'b-2' });
49 const s = useQuickEditStore.getState();
50 expect(s.selected).toEqual({ blockId: 'b-1' });
51 expect(s.dirty).toEqual({ text: 'x' });
52 expect(s.error).toBe('oops');
53 expect(s.saving).toBe(true);
54 });
55 });
56
57 describe('setSelected', () => {
58 it('replaces selected and resets dirty + error', () => {
59 useQuickEditStore.setState({
60 dirty: { text: 'unsaved' },
61 error: 'prior',
62 });
63 useQuickEditStore.getState().setSelected({ blockId: 'b-1' });
64 const s = useQuickEditStore.getState();
65 expect(s.selected).toEqual({ blockId: 'b-1' });
66 expect(s.dirty).toEqual({});
67 expect(s.error).toBeNull();
68 });
69
70 it('does not touch hovered or saving', () => {
71 useQuickEditStore.setState({
72 hovered: { blockId: 'h-1' },
73 saving: true,
74 });
75 useQuickEditStore.getState().setSelected({ blockId: 'b-1' });
76 const s = useQuickEditStore.getState();
77 expect(s.hovered).toEqual({ blockId: 'h-1' });
78 expect(s.saving).toBe(true);
79 });
80 });
81
82 describe('clearSelected', () => {
83 it('nulls selected and resets dirty + error', () => {
84 useQuickEditStore.setState({
85 selected: { blockId: 'b-1' },
86 dirty: { text: 'unsaved' },
87 error: 'prior',
88 });
89 useQuickEditStore.getState().clearSelected();
90 const s = useQuickEditStore.getState();
91 expect(s.selected).toBeNull();
92 expect(s.dirty).toEqual({});
93 expect(s.error).toBeNull();
94 });
95 });
96
97 describe('setField', () => {
98 it('merges values into dirty', () => {
99 const { setField } = useQuickEditStore.getState();
100 setField('text', 'hello');
101 setField('href', 'https://example.com');
102 expect(useQuickEditStore.getState().dirty).toEqual({
103 text: 'hello',
104 href: 'https://example.com',
105 });
106 });
107
108 it('overwrites existing keys', () => {
109 useQuickEditStore.getState().setField('text', 'first');
110 useQuickEditStore.getState().setField('text', 'second');
111 expect(useQuickEditStore.getState().dirty).toEqual({ text: 'second' });
112 });
113
114 it('keeps undefined and null distinct from "missing"', () => {
115 const { setField } = useQuickEditStore.getState();
116 setField('a', null);
117 setField('b', undefined);
118 const d = useQuickEditStore.getState().dirty;
119 expect('a' in d).toBe(true);
120 expect('b' in d).toBe(true);
121 expect(d.a).toBeNull();
122 expect(d.b).toBeUndefined();
123 });
124 });
125
126 describe('setSaving / setError', () => {
127 it('sets saving in isolation', () => {
128 useQuickEditStore.getState().setSaving(true);
129 expect(useQuickEditStore.getState().saving).toBe(true);
130 useQuickEditStore.getState().setSaving(false);
131 expect(useQuickEditStore.getState().saving).toBe(false);
132 });
133
134 it('sets error in isolation (does not clear dirty)', () => {
135 useQuickEditStore.setState({ dirty: { text: 'x' } });
136 useQuickEditStore.getState().setError('boom');
137 const s = useQuickEditStore.getState();
138 expect(s.error).toBe('boom');
139 expect(s.dirty).toEqual({ text: 'x' });
140 });
141 });
142
143 describe('setAgentBlock', () => {
144 it('replaces agentBlock and clears agentBlockCode', () => {
145 useQuickEditStore.setState({ agentBlockCode: 'cached html' });
146 useQuickEditStore.getState().setAgentBlock({
147 id: 'b-1',
148 target: 'data-extendify-agent-block-id',
149 hasText: true,
150 });
151 const s = useQuickEditStore.getState();
152 expect(s.agentBlock).toMatchObject({ id: 'b-1', hasText: true });
153 expect(s.agentBlockCode).toBeNull();
154 });
155
156 it('clearing agentBlock with null also clears agentBlockCode', () => {
157 useQuickEditStore.setState({
158 agentBlock: { id: 'b-1' },
159 agentBlockCode: 'html',
160 });
161 useQuickEditStore.getState().setAgentBlock(null);
162 const s = useQuickEditStore.getState();
163 expect(s.agentBlock).toBeNull();
164 expect(s.agentBlockCode).toBeNull();
165 });
166
167 it('does not touch QuickEdit canvas state (selected / dirty)', () => {
168 useQuickEditStore.setState({
169 selected: { blockId: 's-1' },
170 dirty: { text: 'unsaved' },
171 });
172 useQuickEditStore.getState().setAgentBlock({ id: 'b-1' });
173 const s = useQuickEditStore.getState();
174 expect(s.selected).toEqual({ blockId: 's-1' });
175 expect(s.dirty).toEqual({ text: 'unsaved' });
176 });
177 });
178
179 describe('setCommittedSelection', () => {
180 it('writes the slot', () => {
181 const target = { el: 'fake-el', blockType: 'core/paragraph', blockId: 5 };
182 useQuickEditStore.getState().setCommittedSelection(target);
183 expect(useQuickEditStore.getState().committedSelection).toBe(target);
184 });
185
186 it('clears the slot when set to null', () => {
187 useQuickEditStore.setState({
188 committedSelection: { el: 'fake', blockType: 'core/group' },
189 });
190 useQuickEditStore.getState().setCommittedSelection(null);
191 expect(useQuickEditStore.getState().committedSelection).toBeNull();
192 });
193
194 it('does not touch selected / agentBlock / dirty', () => {
195 useQuickEditStore.setState({
196 selected: { blockId: 's-1' },
197 agentBlock: { id: 'a-1' },
198 dirty: { text: 'unsaved' },
199 });
200 useQuickEditStore.getState().setCommittedSelection({ el: 'x' });
201 const s = useQuickEditStore.getState();
202 expect(s.selected).toEqual({ blockId: 's-1' });
203 expect(s.agentBlock).toEqual({ id: 'a-1' });
204 expect(s.dirty).toEqual({ text: 'unsaved' });
205 });
206 });
207
208 describe('setAgentBlockCode', () => {
209 it('writes agentBlockCode without touching agentBlock', () => {
210 useQuickEditStore.setState({ agentBlock: { id: 'b-1' } });
211 useQuickEditStore.getState().setAgentBlockCode('<p>hi</p>');
212 const s = useQuickEditStore.getState();
213 expect(s.agentBlockCode).toBe('<p>hi</p>');
214 expect(s.agentBlock).toEqual({ id: 'b-1' });
215 });
216 });
217
218 describe('getPatches', () => {
219 it('returns one { fieldKey, value } per dirty entry', () => {
220 useQuickEditStore.setState({
221 dirty: { text: 'hello', href: 'https://example.com' },
222 });
223 const patches = useQuickEditStore.getState().getPatches();
224 expect(patches).toEqual(
225 expect.arrayContaining([
226 { fieldKey: 'text', value: 'hello' },
227 { fieldKey: 'href', value: 'https://example.com' },
228 ]),
229 );
230 expect(patches).toHaveLength(2);
231 });
232
233 it('returns [] when dirty is empty', () => {
234 expect(useQuickEditStore.getState().getPatches()).toEqual([]);
235 });
236 });
237 });
238