Skip to content

Commit b262a92

Browse files
author
HugoFara
committed
fix(ci): resolve Psalm and frontend test failures
- Fix MixedAssignment errors in Migrations.php and Restore.php by restructuring loops to check types before variable assignments - Add UndefinedConstant suppressions in psalm.xml for cURL constants in WhisperClient, ViteHelper, GoogleTranslate, and GoogleTimeToken - Update feed_index.test.ts and feed_multi_load.test.ts to use correct RESTful URL defaults (/feeds/manage, /feeds/multi-load) - Update confirmDelete test to properly mock fetch for DELETE method
1 parent b0fa141 commit b262a92

File tree

5 files changed

+63
-42
lines changed

5 files changed

+63
-42
lines changed

psalm.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@
4545
</errorLevel>
4646
</UndefinedGlobalVariable>
4747

48+
<!-- cURL constants not recognized without ext-curl stub -->
49+
<UndefinedConstant>
50+
<errorLevel type="suppress">
51+
<file name="src/Modules/Text/Infrastructure/WhisperClient.php" />
52+
<file name="src/Shared/UI/Assets/ViteHelper.php" />
53+
<file name="src/backend/Core/Entity/GoogleTranslate.php" />
54+
<file name="src/backend/Core/Integration/GoogleTimeToken.php" />
55+
</errorLevel>
56+
</UndefinedConstant>
57+
4858
<!-- Mixed* issues in views and curl constant usage -->
4959
<MixedArgument>
5060
<errorLevel type="suppress">

src/Shared/Infrastructure/Database/Migrations.php

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,21 @@ public static function dropAllForeignKeys(): void
5656
);
5757

5858
foreach ($constraints as $constraint) {
59-
$tableName = $constraint['TABLE_NAME'] ?? null;
60-
$constraintName = $constraint['CONSTRAINT_NAME'] ?? null;
61-
if (is_string($tableName) && is_string($constraintName)) {
62-
// Use backtick escaping for identifiers
63-
$escapedTable = '`' . str_replace('`', '``', $tableName) . '`';
64-
$escapedConstraint = '`' . str_replace('`', '``', $constraintName) . '`';
65-
try {
66-
Connection::execute(
67-
"ALTER TABLE $escapedTable DROP FOREIGN KEY $escapedConstraint"
68-
);
69-
} catch (\RuntimeException $e) {
70-
// FK might already be dropped, continue
71-
}
59+
if (
60+
!isset($constraint['TABLE_NAME']) || !is_string($constraint['TABLE_NAME'])
61+
|| !isset($constraint['CONSTRAINT_NAME']) || !is_string($constraint['CONSTRAINT_NAME'])
62+
) {
63+
continue;
64+
}
65+
// Use backtick escaping for identifiers
66+
$escapedTable = '`' . str_replace('`', '``', $constraint['TABLE_NAME']) . '`';
67+
$escapedConstraint = '`' . str_replace('`', '``', $constraint['CONSTRAINT_NAME']) . '`';
68+
try {
69+
Connection::execute(
70+
"ALTER TABLE $escapedTable DROP FOREIGN KEY $escapedConstraint"
71+
);
72+
} catch (\RuntimeException $e) {
73+
// FK might already be dropped, continue
7274
}
7375
}
7476
}

src/Shared/Infrastructure/Database/Restore.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ private static function dropAllLwtTables(): void
5858
Connection::execute("SET FOREIGN_KEY_CHECKS = 0");
5959
try {
6060
foreach ($tables as $table) {
61-
$tableName = $table['TABLE_NAME'] ?? null;
62-
if (is_string($tableName)) {
63-
$escapedTable = '`' . str_replace('`', '``', $tableName) . '`';
64-
try {
65-
Connection::execute("DROP TABLE IF EXISTS $escapedTable");
66-
} catch (\RuntimeException $e) {
67-
// Ignore errors, table might already be gone
68-
}
61+
if (!isset($table['TABLE_NAME']) || !is_string($table['TABLE_NAME'])) {
62+
continue;
63+
}
64+
$escapedTable = '`' . str_replace('`', '``', $table['TABLE_NAME']) . '`';
65+
try {
66+
Connection::execute("DROP TABLE IF EXISTS $escapedTable");
67+
} catch (\RuntimeException $e) {
68+
// Ignore errors, table might already be gone
6969
}
7070
}
7171
} finally {

tests/frontend/feeds/feed_index.test.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ describe('feed_index_component.ts', () => {
5656
it('creates component with default values', () => {
5757
const component = feedIndexData();
5858

59-
expect(component.resetUrl).toBe('/feeds/edit');
60-
expect(component.filterUrl).toBe('/feeds/edit?manage_feeds=1');
61-
expect(component.pageBaseUrl).toBe('/feeds/edit');
59+
expect(component.resetUrl).toBe('/feeds/manage');
60+
expect(component.filterUrl).toBe('/feeds/manage');
61+
expect(component.pageBaseUrl).toBe('/feeds/manage');
6262
expect(component.query).toBe('');
6363
});
6464

@@ -85,7 +85,7 @@ describe('feed_index_component.ts', () => {
8585

8686
const component = feedIndexData(config);
8787

88-
expect(component.resetUrl).toBe('/feeds/edit'); // Default
88+
expect(component.resetUrl).toBe('/feeds/manage'); // Default
8989
expect(component.query).toBe('search term');
9090
});
9191
});
@@ -113,7 +113,7 @@ describe('feed_index_component.ts', () => {
113113
const component = feedIndexData();
114114
component.init();
115115

116-
expect(component.resetUrl).toBe('/feeds/edit');
116+
expect(component.resetUrl).toBe('/feeds/manage');
117117
expect(component.query).toBe('');
118118
});
119119

@@ -149,7 +149,7 @@ describe('feed_index_component.ts', () => {
149149

150150
component.handleReset();
151151

152-
expect(resetAll).toHaveBeenCalledWith('/feeds/edit');
152+
expect(resetAll).toHaveBeenCalledWith('/feeds/manage');
153153
});
154154
});
155155

@@ -175,7 +175,7 @@ describe('feed_index_component.ts', () => {
175175

176176
component.handleLanguageFilter(event);
177177

178-
expect(setLang).toHaveBeenCalledWith(select, '/feeds/edit?manage_feeds=1');
178+
expect(setLang).toHaveBeenCalledWith(select, '/feeds/manage');
179179
});
180180
});
181181

@@ -199,7 +199,7 @@ describe('feed_index_component.ts', () => {
199199

200200
component.handleQueryFilter();
201201

202-
expect(window.location.href).toBe('/feeds/edit?page=1&query=');
202+
expect(window.location.href).toBe('/feeds/manage?page=1&query=');
203203
});
204204

205205
it('handles special characters in query', () => {
@@ -208,7 +208,7 @@ describe('feed_index_component.ts', () => {
208208

209209
component.handleQueryFilter();
210210

211-
expect(window.location.href).toBe('/feeds/edit?page=1&query=test%26query%3Dvalue');
211+
expect(window.location.href).toBe('/feeds/manage?page=1&query=test%26query%3Dvalue');
212212
});
213213
});
214214

@@ -224,7 +224,7 @@ describe('feed_index_component.ts', () => {
224224
component.handleClearQuery();
225225

226226
expect(component.query).toBe('');
227-
expect(window.location.href).toBe('/feeds/edit?page=1&query=');
227+
expect(window.location.href).toBe('/feeds/manage?page=1&query=');
228228
});
229229
});
230230

@@ -353,7 +353,7 @@ describe('feed_index_component.ts', () => {
353353

354354
component.handleSort(event);
355355

356-
expect(window.location.href).toBe('/feeds/edit?page=1&sort=name%26asc');
356+
expect(window.location.href).toBe('/feeds/manage?page=1&sort=name%26asc');
357357
});
358358
});
359359

@@ -362,15 +362,24 @@ describe('feed_index_component.ts', () => {
362362
// ===========================================================================
363363

364364
describe('confirmDelete()', () => {
365-
it('navigates to delete URL when confirmed', () => {
365+
it('navigates to delete URL when confirmed', async () => {
366366
vi.spyOn(window, 'confirm').mockReturnValue(true);
367+
const fetchMock = vi.spyOn(global, 'fetch').mockResolvedValue(new Response());
367368

368369
const component = feedIndexData();
369370

370371
component.confirmDelete('42');
371372

372373
expect(window.confirm).toHaveBeenCalledWith('Are you sure?');
373-
expect(window.location.href).toBe('/feeds/edit?markaction=del&selected_feed=42');
374+
expect(fetchMock).toHaveBeenCalledWith('/feeds/42', {
375+
method: 'DELETE',
376+
headers: { 'X-Requested-With': 'XMLHttpRequest' }
377+
});
378+
379+
// Wait for the promise to resolve
380+
await vi.waitFor(() => {
381+
expect(window.location.href).toBe('/feeds/manage');
382+
});
374383
});
375384

376385
it('does not navigate when cancelled', () => {

tests/frontend/feeds/feed_multi_load.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ describe('feed_multi_load_component.ts', () => {
4949
it('creates component with default values', () => {
5050
const component = feedMultiLoadData();
5151

52-
expect(component.cancelUrl).toBe('/feeds?selected_feed=0');
53-
expect(component.filterUrl).toBe('/feeds/edit?multi_load_feed=1&page=1');
52+
expect(component.cancelUrl).toBe('/feeds');
53+
expect(component.filterUrl).toBe('/feeds/multi-load');
5454
});
5555

5656
it('creates component with provided config values', () => {
@@ -73,7 +73,7 @@ describe('feed_multi_load_component.ts', () => {
7373
const component = feedMultiLoadData(config);
7474

7575
expect(component.cancelUrl).toBe('/custom/cancel');
76-
expect(component.filterUrl).toBe('/feeds/edit?multi_load_feed=1&page=1');
76+
expect(component.filterUrl).toBe('/feeds/multi-load');
7777
});
7878
});
7979

@@ -100,8 +100,8 @@ describe('feed_multi_load_component.ts', () => {
100100
const component = feedMultiLoadData();
101101
component.init();
102102

103-
expect(component.cancelUrl).toBe('/feeds?selected_feed=0');
104-
expect(component.filterUrl).toBe('/feeds/edit?multi_load_feed=1&page=1');
103+
expect(component.cancelUrl).toBe('/feeds');
104+
expect(component.filterUrl).toBe('/feeds/multi-load');
105105
});
106106

107107
it('handles invalid JSON gracefully', () => {
@@ -114,7 +114,7 @@ describe('feed_multi_load_component.ts', () => {
114114
const component = feedMultiLoadData();
115115

116116
expect(() => component.init()).not.toThrow();
117-
expect(component.cancelUrl).toBe('/feeds?selected_feed=0');
117+
expect(component.cancelUrl).toBe('/feeds');
118118
});
119119
});
120120

@@ -314,7 +314,7 @@ describe('feed_multi_load_component.ts', () => {
314314

315315
component.handleLanguageFilter(event);
316316

317-
expect(setLang).toHaveBeenCalledWith(select, '/feeds/edit?multi_load_feed=1&page=1');
317+
expect(setLang).toHaveBeenCalledWith(select, '/feeds/multi-load');
318318
});
319319
});
320320

@@ -338,7 +338,7 @@ describe('feed_multi_load_component.ts', () => {
338338

339339
component.cancel();
340340

341-
expect(window.location.href).toBe('/feeds?selected_feed=0');
341+
expect(window.location.href).toBe('/feeds');
342342
});
343343
});
344344
});

0 commit comments

Comments
 (0)