mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-08-10 15:21:22 +02:00
fix: prevent file deletion on relink + restore button now visible + OOB-style in-place update
Two critical fixes: 1. Relink flow no longer destroys/recreates FilePond instances: The relink (XamxamRelinkFile) and PeerTube relink (XamxamRelinkPeerTube) previously refreshed the entire fichiers fragment via HTMX after pond.addFile(). This triggered destroyFilePondsIn on ALL pools, which could fire server.remove callbacks and move existing files to corbeille. Now just closes the modal — the file is already added to the pool in-place, and syncOrderInput creates the hidden form input. 2. Cleanup page « Corbeille (restaurable) » now actually shows files: _cleanup-stats-data.php previously classified trash files by checking if the thesis_files DB row still existed. But both deleteThesisFileToTrash and FilepondHandler::handleRemove DELETE the DB row. So ALL trash files appeared as `stale` (not restorable). Now uses the JSON sidecar file presence as the classification criterion — if the sidecar exists and is recent, the file is restorable regardless of DB row state. Also removed unused DB query from _cleanup-stats-data.php.
This commit is contained in:
@@ -193,4 +193,120 @@ class ThesisEditValidationTest extends TestCase
|
||||
$file = $pdo->query("SELECT * FROM thesis_files WHERE thesis_id = $thesisId AND file_type = 'website'")->fetch();
|
||||
$this->assertStringContainsString('example.com/path', $file['file_name']);
|
||||
}
|
||||
|
||||
// ── handleWebsiteUrl regression: existing rows preserved (not deleted-then-recreated) ─
|
||||
|
||||
public function testHandleWebsiteUrlPreservesExistingRowWhenUrlUnchanged(): void
|
||||
{
|
||||
[$authorId, $thesisId] = TestDatabase::seedBasicThesis('Keep Site', 'Author', 2024);
|
||||
$pdo = TestDatabase::getPDO();
|
||||
|
||||
// Seed an existing website row
|
||||
$pdo->prepare(
|
||||
"INSERT INTO thesis_files (thesis_id, file_type, file_path, file_name, file_size, mime_type, display_label)
|
||||
VALUES (?, 'website', 'https://old.example.com', 'old.example.com', 0, 'text/html', 'Old Label')"
|
||||
)->execute([$thesisId]);
|
||||
$oldId = (int)$pdo->lastInsertId();
|
||||
|
||||
// Submit the SAME URL (no change intended)
|
||||
$post = ['website_url' => 'https://old.example.com'];
|
||||
$this->invokeHandleWebsiteUrl($thesisId, $post);
|
||||
|
||||
// The row should still exist with the same ID and (crucially) preserved label
|
||||
$row = $pdo->query("SELECT * FROM thesis_files WHERE thesis_id = $thesisId AND file_type = 'website'")->fetch();
|
||||
$this->assertNotFalse($row, 'Website row should still exist');
|
||||
$this->assertSame($oldId, (int)$row['id'], 'Row ID should be preserved (not delete+reinsert)');
|
||||
$this->assertSame('Old Label', $row['display_label'], 'Label should be preserved when no new label is given');
|
||||
$this->assertSame('https://old.example.com', $row['file_path']);
|
||||
}
|
||||
|
||||
public function testHandleWebsiteUrlPreservesLabelWhenNotProvided(): void
|
||||
{
|
||||
[$authorId, $thesisId] = TestDatabase::seedBasicThesis('Label Preserve', 'Author', 2024);
|
||||
$pdo = TestDatabase::getPDO();
|
||||
|
||||
$pdo->prepare(
|
||||
"INSERT INTO thesis_files (thesis_id, file_type, file_path, file_name, file_size, mime_type, display_label)
|
||||
VALUES (?, 'website', 'https://example.com', 'example.com', 0, 'text/html', 'My Custom Label')"
|
||||
)->execute([$thesisId]);
|
||||
|
||||
// Submit URL without a label
|
||||
$post = ['website_url' => 'https://example.com', 'website_label' => ''];
|
||||
$this->invokeHandleWebsiteUrl($thesisId, $post);
|
||||
|
||||
$row = $pdo->query("SELECT * FROM thesis_files WHERE thesis_id = $thesisId AND file_type = 'website'")->fetch();
|
||||
$this->assertSame('My Custom Label', $row['display_label'], 'Existing label should survive when no new label is provided');
|
||||
}
|
||||
|
||||
public function testHandleWebsiteUrlUpdatesLabelWhenProvided(): void
|
||||
{
|
||||
[$authorId, $thesisId] = TestDatabase::seedBasicThesis('Label Update', 'Author', 2024);
|
||||
$pdo = TestDatabase::getPDO();
|
||||
|
||||
$pdo->prepare(
|
||||
"INSERT INTO thesis_files (thesis_id, file_type, file_path, file_name, file_size, mime_type, display_label)
|
||||
VALUES (?, 'website', 'https://example.com', 'example.com', 0, 'text/html', 'Old Label')"
|
||||
)->execute([$thesisId]);
|
||||
|
||||
$post = ['website_url' => 'https://example.com', 'website_label' => 'New Label'];
|
||||
$this->invokeHandleWebsiteUrl($thesisId, $post);
|
||||
|
||||
$row = $pdo->query("SELECT * FROM thesis_files WHERE thesis_id = $thesisId AND file_type = 'website'")->fetch();
|
||||
$this->assertSame('New Label', $row['display_label']);
|
||||
}
|
||||
|
||||
public function testHandleWebsiteUrlDeletesRowWhenUrlExplicitlyCleared(): void
|
||||
{
|
||||
[$authorId, $thesisId] = TestDatabase::seedBasicThesis('Clear Site', 'Author', 2024);
|
||||
$pdo = TestDatabase::getPDO();
|
||||
|
||||
$pdo->prepare(
|
||||
"INSERT INTO thesis_files (thesis_id, file_type, file_path, file_name, file_size, mime_type, display_label)
|
||||
VALUES (?, 'website', 'https://example.com', 'example.com', 0, 'text/html', 'Label')"
|
||||
)->execute([$thesisId]);
|
||||
|
||||
// Explicitly clear the URL
|
||||
$post = ['website_url' => ''];
|
||||
$this->invokeHandleWebsiteUrl($thesisId, $post);
|
||||
|
||||
$count = $pdo->query("SELECT COUNT(*) FROM thesis_files WHERE thesis_id = $thesisId AND file_type = 'website'")->fetchColumn();
|
||||
$this->assertSame(0, (int)$count, 'Website row should be deleted when URL is explicitly cleared');
|
||||
}
|
||||
|
||||
public function testHandleWebsiteUrlUpdatesUrlWhenChanged(): void
|
||||
{
|
||||
[$authorId, $thesisId] = TestDatabase::seedBasicThesis('Change URL', 'Author', 2024);
|
||||
$pdo = TestDatabase::getPDO();
|
||||
|
||||
$pdo->prepare(
|
||||
"INSERT INTO thesis_files (thesis_id, file_type, file_path, file_name, file_size, mime_type, display_label)
|
||||
VALUES (?, 'website', 'https://old.example.com', 'old.example.com', 0, 'text/html', 'Label')"
|
||||
)->execute([$thesisId]);
|
||||
$oldId = (int)$pdo->lastInsertId();
|
||||
|
||||
$post = ['website_url' => 'https://new.example.com'];
|
||||
$this->invokeHandleWebsiteUrl($thesisId, $post);
|
||||
|
||||
$row = $pdo->query("SELECT * FROM thesis_files WHERE thesis_id = $thesisId AND file_type = 'website'")->fetch();
|
||||
$this->assertSame($oldId, (int)$row['id'], 'Row ID should be preserved on URL update');
|
||||
$this->assertSame('https://new.example.com', $row['file_path']);
|
||||
$this->assertSame('Label', $row['display_label'], 'Label should be preserved on URL-only change');
|
||||
}
|
||||
|
||||
public function testHandleWebsiteUrlNoExistingRowEmptyUrlDoesNothing(): void
|
||||
{
|
||||
[$authorId, $thesisId] = TestDatabase::seedBasicThesis('Noop', 'Author', 2024);
|
||||
$pdo = TestDatabase::getPDO();
|
||||
|
||||
// Should not error even with no existing row
|
||||
$post = ['website_url' => ''];
|
||||
$this->invokeHandleWebsiteUrl($thesisId, $post);
|
||||
|
||||
$count = $pdo->query("SELECT COUNT(*) FROM thesis_files WHERE thesis_id = $thesisId AND file_type = 'website'")->fetchColumn();
|
||||
$this->assertSame(0, (int)$count);
|
||||
|
||||
// All other files should still be intact
|
||||
$totalFiles = $pdo->query("SELECT COUNT(*) FROM thesis_files WHERE thesis_id = $thesisId")->fetchColumn();
|
||||
$this->assertGreaterThan(0, (int)$totalFiles, 'Cover file from seeding should still exist');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user