Skip to content

Commit ac93058

Browse files
PR changes
1 parent 4ca7bac commit ac93058

File tree

9 files changed

+281
-130
lines changed

9 files changed

+281
-130
lines changed

src/components/ControlPlane/ActionsMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function ActionsMenu<T>({ item, actions }: ActionsMenuProps<T>) {
3434
<Menu
3535
ref={popoverRef}
3636
open={open}
37-
data-component-name="ActionsMenu"
37+
data-testid="ActionsMenu"
3838
onItemClick={(event) => {
3939
const element = event.detail.item as HTMLElement & { disabled?: boolean };
4040
const actionKey = element.dataset.actionKey;

src/components/ControlPlane/GitRepositories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { ResourceStatusCell } from '../Shared/ResourceStatusCell.tsx';
1313
import { Resource } from '../../utils/removeManagedFieldsAndFilterData.ts';
1414
import { useSplitter } from '../Splitter/SplitterContext.tsx';
1515
import { YamlSidePanel } from '../Yaml/YamlSidePanel.tsx';
16-
import { useHandleResourcePatch } from '../../lib/api/types/crossplane/useHandleResourcePatch.ts';
16+
import { useHandleResourcePatch } from '../../hooks/useHandleResourcePatch.ts';
1717
import { ErrorDialog, ErrorDialogHandle } from '../Shared/ErrorMessageBox.tsx';
1818
import type { GitReposResponse } from '../../lib/api/types/flux/listGitRepo';
1919
import { ActionsMenu, type ActionItem } from './ActionsMenu';

src/components/ControlPlane/Kustomizations.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { ResourceStatusCell } from '../Shared/ResourceStatusCell.tsx';
1313
import { Resource } from '../../utils/removeManagedFieldsAndFilterData.ts';
1414
import { useSplitter } from '../Splitter/SplitterContext.tsx';
1515
import { YamlSidePanel } from '../Yaml/YamlSidePanel.tsx';
16-
import { useHandleResourcePatch } from '../../lib/api/types/crossplane/useHandleResourcePatch.ts';
16+
import { useHandleResourcePatch } from '../../hooks/useHandleResourcePatch.ts';
1717
import { ErrorDialog, ErrorDialogHandle } from '../Shared/ErrorMessageBox.tsx';
1818
import type { KustomizationsResponse } from '../../lib/api/types/flux/listKustomization';
1919
import { ActionsMenu, type ActionItem } from './ActionsMenu';

src/components/ControlPlane/ManagedResources.cy.tsx

Lines changed: 117 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import { ManagedResources } from './ManagedResources.tsx';
33
import { SplitterProvider } from '../Splitter/SplitterContext.tsx';
44
import { ManagedResourceGroup } from '../../lib/shared/types.ts';
55
import { MemoryRouter } from 'react-router-dom';
6-
import { useApiResourceMutation } from '../../lib/api/useApiResource.ts';
6+
import { useApiResourceMutation, useApiResource } from '../../lib/api/useApiResource.ts';
77
import '@ui5/webcomponents-cypress-commands';
8-
import { useHandleResourcePatch } from '../../lib/api/types/crossplane/useHandleResourcePatch.ts';
8+
import { useHandleResourcePatch } from '../../hooks/useHandleResourcePatch.ts';
9+
import { SplitterLayout } from '../Splitter/SplitterLayout.tsx';
10+
import { useResourcePluralNames } from '../../hooks/useResourcePluralNames';
911

1012
describe('ManagedResources - Delete Resource', () => {
1113
let deleteCalled = false;
@@ -30,6 +32,24 @@ describe('ManagedResources - Delete Resource', () => {
3032
};
3133
};
3234

35+
const fakeUseApiResource: typeof useApiResource = (): any => {
36+
return {
37+
data: mockManagedResources,
38+
error: undefined,
39+
isLoading: false,
40+
isValidating: false,
41+
mutate: async () => undefined,
42+
};
43+
};
44+
45+
const fakeUseResourcePluralNames: typeof useResourcePluralNames = (): any => {
46+
return {
47+
getPluralKind: (kind: string) => `${kind.toLowerCase()}s`,
48+
isLoading: false,
49+
error: undefined,
50+
};
51+
};
52+
3353
const mockManagedResources: ManagedResourceGroup[] = [
3454
{
3555
items: [
@@ -63,30 +83,6 @@ describe('ManagedResources - Delete Resource', () => {
6383
},
6484
];
6585

66-
before(() => {
67-
// Set up interceptors once for all tests
68-
cy.intercept('GET', '**/managed', {
69-
statusCode: 200,
70-
body: mockManagedResources,
71-
}).as('getManagedResources');
72-
73-
cy.intercept('GET', '**/customresourcedefinitions*', {
74-
statusCode: 200,
75-
body: {
76-
items: [
77-
{
78-
spec: {
79-
names: {
80-
kind: 'Subaccount',
81-
plural: 'subaccounts',
82-
},
83-
},
84-
},
85-
],
86-
},
87-
}).as('getCRDs');
88-
});
89-
9086
beforeEach(() => {
9187
deleteCalled = false;
9288
patchCalled = false;
@@ -97,108 +93,96 @@ describe('ManagedResources - Delete Resource', () => {
9793
cy.mount(
9894
<MemoryRouter>
9995
<SplitterProvider>
100-
<ManagedResources useApiResourceMutation={fakeUseApiResourceMutation} />
96+
<ManagedResources
97+
useApiResourceMutation={fakeUseApiResourceMutation}
98+
useApiResource={fakeUseApiResource}
99+
useResourcePluralNames={fakeUseResourcePluralNames}
100+
/>
101101
</SplitterProvider>
102102
</MemoryRouter>,
103103
);
104104

105-
cy.wait('@getManagedResources');
106-
cy.wait('@getCRDs');
107-
105+
// Expand resource group
108106
cy.get('button[aria-label*="xpand"]').first().click({ force: true });
109-
cy.wait(500);
110-
111107
cy.contains('test-subaccount').should('be.visible');
108+
109+
// Open actions menu and click Delete
112110
cy.get('[data-testid="ActionsMenu-opener"]').first().click({ force: true });
113111
cy.contains('Delete').click({ force: true });
112+
113+
// Type confirmation text
114114
cy.get('ui5-dialog[open]').find('ui5-input').typeIntoUi5Input('test-subaccount');
115115

116+
// Verify delete not called yet
116117
cy.then(() => cy.wrap(deleteCalled).should('equal', false));
118+
119+
// Click delete button
117120
cy.get('ui5-dialog[open]').find('ui5-button').contains('Delete').click();
121+
122+
// Verify delete was called
118123
cy.then(() => cy.wrap(deleteCalled).should('equal', true));
119124
});
120125

121126
it('force deletes a managed resource', () => {
122127
cy.mount(
123128
<MemoryRouter>
124129
<SplitterProvider>
125-
<ManagedResources useApiResourceMutation={fakeUseApiResourceMutation} />
130+
<ManagedResources
131+
useApiResourceMutation={fakeUseApiResourceMutation}
132+
useApiResource={fakeUseApiResource}
133+
useResourcePluralNames={fakeUseResourcePluralNames}
134+
/>
126135
</SplitterProvider>
127136
</MemoryRouter>,
128137
);
129138

130-
cy.wait(1000);
131-
139+
// Expand resource group
132140
cy.get('button[aria-label*="xpand"]').first().click({ force: true });
133-
cy.wait(500);
134-
135141
cy.contains('test-subaccount').should('be.visible');
142+
143+
// Open actions menu and click Delete
136144
cy.get('[data-testid="ActionsMenu-opener"]').first().click({ force: true });
137145
cy.contains('Delete').click({ force: true });
138146

139147
// Expand Advanced section
140148
cy.contains('Advanced').click();
141-
cy.wait(500);
142149

143-
// Click directly on "Force deletion" text - this should toggle the checkbox
150+
// Enable force deletion checkbox
144151
cy.contains('Force deletion').click({ force: true });
145-
cy.wait(500);
146152

153+
// Type confirmation text
147154
cy.get('ui5-dialog[open]').find('ui5-input').typeIntoUi5Input('test-subaccount');
148155

156+
// Verify neither delete nor patch called yet
149157
cy.then(() => cy.wrap(deleteCalled).should('equal', false));
150158
cy.then(() => cy.wrap(patchCalled).should('equal', false));
151159

160+
// Click delete button
152161
cy.get('ui5-dialog[open]').find('ui5-button').contains('Delete').click();
153162

154-
cy.wait(2000);
155-
156-
cy.then(() => {
157-
cy.log(`deleteCalled: ${deleteCalled}, patchCalled: ${patchCalled}`);
158-
});
159-
163+
// Verify both delete and patch were called
160164
cy.then(() => cy.wrap(deleteCalled).should('equal', true));
161165
cy.then(() => cy.wrap(patchCalled).should('equal', true));
162166
});
163167

164168
it('keeps delete button disabled until confirmation text is entered', () => {
165-
// Setup interceptors for this test
166-
cy.intercept('GET', '**/managed', {
167-
statusCode: 200,
168-
body: mockManagedResources,
169-
}).as('getManagedResourcesValidation');
170-
171-
cy.intercept('GET', '**/customresourcedefinitions*', {
172-
statusCode: 200,
173-
body: {
174-
items: [
175-
{
176-
spec: {
177-
names: {
178-
kind: 'Subaccount',
179-
plural: 'subaccounts',
180-
},
181-
},
182-
},
183-
],
184-
},
185-
}).as('getCRDsValidation');
186-
187169
cy.mount(
188170
<MemoryRouter>
189171
<SplitterProvider>
190-
<ManagedResources useApiResourceMutation={fakeUseApiResourceMutation} />
172+
<ManagedResources
173+
useApiResourceMutation={fakeUseApiResourceMutation}
174+
useApiResource={fakeUseApiResource}
175+
useResourcePluralNames={fakeUseResourcePluralNames}
176+
/>
191177
</SplitterProvider>
192178
</MemoryRouter>,
193179
);
194180

195-
cy.wait('@getManagedResourcesValidation');
196-
cy.wait('@getCRDsValidation');
197-
181+
// Expand resource group
198182
cy.get('button[aria-label*="xpand"]').first().click({ force: true });
199-
cy.wait(500);
200-
201183
cy.contains('test-subaccount').should('be.visible');
184+
185+
// Open actions menu and click Delete
202186
cy.get('[data-testid="ActionsMenu-opener"]').first().click({ force: true });
203187
cy.contains('Delete').click({ force: true });
204188

@@ -207,18 +191,13 @@ describe('ManagedResources - Delete Resource', () => {
207191

208192
// Type wrong text
209193
cy.get('ui5-dialog[open]').find('ui5-input').typeIntoUi5Input('wrong-text');
210-
cy.wait(300);
211194

212195
// Delete button should still be disabled
213196
cy.get('ui5-dialog[open]').find('ui5-button').contains('Delete').should('have.attr', 'disabled');
214197

215-
// Clear input by selecting all and deleting
198+
// Clear input and type correct text
216199
cy.get('ui5-dialog[open]').find('ui5-input').find('input[id*="inner"]').clear({ force: true });
217-
cy.wait(300);
218-
219-
// Type correct text
220200
cy.get('ui5-dialog[open]').find('ui5-input').typeIntoUi5Input('test-subaccount');
221-
cy.wait(300);
222201

223202
// Delete button should now be enabled
224203
cy.get('ui5-dialog[open]').find('ui5-button').contains('Delete').should('not.have.attr', 'disabled');
@@ -227,14 +206,36 @@ describe('ManagedResources - Delete Resource', () => {
227206

228207
describe('ManagedResources - Edit Resource', () => {
229208
let patchHandlerCreated = false;
209+
let patchCalled = false;
210+
let patchedItem: any = null;
230211

231212
const fakeUseHandleResourcePatch: typeof useHandleResourcePatch = () => {
232213
patchHandlerCreated = true;
233-
return async () => {
214+
return async (item: any) => {
215+
patchCalled = true;
216+
patchedItem = item;
234217
return true;
235218
};
236219
};
237220

221+
const fakeUseApiResource: typeof useApiResource = (): any => {
222+
return {
223+
data: mockManagedResources,
224+
error: undefined,
225+
isLoading: false,
226+
isValidating: false,
227+
mutate: async () => undefined,
228+
};
229+
};
230+
231+
const fakeUseResourcePluralNames: typeof useResourcePluralNames = (): any => {
232+
return {
233+
getPluralKind: (kind: string) => `${kind.toLowerCase()}s`,
234+
isLoading: false,
235+
error: undefined,
236+
};
237+
};
238+
238239
const mockManagedResources: ManagedResourceGroup[] = [
239240
{
240241
items: [
@@ -269,60 +270,62 @@ describe('ManagedResources - Edit Resource', () => {
269270
];
270271

271272
before(() => {
272-
cy.intercept('GET', '**/managed', {
273-
statusCode: 200,
274-
body: mockManagedResources,
275-
}).as('getManagedResources');
276-
277-
cy.intercept('GET', '**/customresourcedefinitions*', {
278-
statusCode: 200,
279-
body: {
280-
items: [
281-
{
282-
spec: {
283-
names: {
284-
kind: 'Subaccount',
285-
plural: 'subaccounts',
286-
},
287-
},
288-
},
289-
],
290-
},
291-
}).as('getCRDs');
273+
// Ignore Monaco Editor disposal errors
274+
cy.on('uncaught:exception', (err) => {
275+
if (err.message.includes('TextModel got disposed')) {
276+
return false;
277+
}
278+
return true;
279+
});
292280
});
293281

294282
beforeEach(() => {
295283
patchHandlerCreated = false;
284+
patchCalled = false;
285+
patchedItem = null;
296286
});
297287

298-
it('initializes patch handler and edit button is available', () => {
288+
it('opens edit panel and can apply changes', () => {
299289
cy.mount(
300290
<MemoryRouter>
301291
<SplitterProvider>
302-
<ManagedResources useHandleResourcePatch={fakeUseHandleResourcePatch} />
292+
<SplitterLayout>
293+
<ManagedResources
294+
useHandleResourcePatch={fakeUseHandleResourcePatch}
295+
useApiResource={fakeUseApiResource}
296+
useResourcePluralNames={fakeUseResourcePluralNames}
297+
/>
298+
</SplitterLayout>
303299
</SplitterProvider>
304300
</MemoryRouter>,
305301
);
306302

307-
cy.wait('@getManagedResources');
308-
cy.wait('@getCRDs');
309-
310303
// Verify patch handler was initialized
311304
cy.then(() => cy.wrap(patchHandlerCreated).should('equal', true));
312305

306+
// Expand resource group
313307
cy.get('button[aria-label*="xpand"]').first().click({ force: true });
314-
cy.wait(500);
315-
316308
cy.contains('test-subaccount').should('be.visible');
309+
310+
// Open actions menu and click Edit
317311
cy.get('[data-testid="ActionsMenu-opener"]').first().click({ force: true });
312+
cy.contains('Edit').click({ force: true });
318313

319-
// Verify Edit button exists
320-
cy.contains('Edit').should('exist');
314+
// Verify YAML panel opened
315+
cy.contains('YAML').should('be.visible');
316+
cy.contains('test-subaccount').should('be.visible');
321317

322-
// Verify Edit button is not disabled (check separately)
323-
cy.contains('Edit').should('not.have.attr', 'disabled');
318+
// Verify patch not called yet
319+
cy.then(() => cy.wrap(patchCalled).should('equal', false));
324320

325-
// Click Edit button
326-
cy.contains('Edit').click({ force: true });
321+
// Click Apply button
322+
cy.contains('Apply changes').click();
323+
324+
// Confirm in dialog
325+
cy.contains('Yes').click({ force: true });
326+
327+
// Verify patch was called
328+
cy.then(() => cy.wrap(patchCalled).should('equal', true));
329+
cy.then(() => cy.wrap(patchedItem).should('not.be.null'));
327330
});
328331
});

0 commit comments

Comments
 (0)