Add integration tests (Phase 2: DatabaseExtended, ShareLinkExtended, RateLimitExtended) and controller validation tests (Phase 3: ThesisCreate, ThesisEdit, AutofocusField)

This commit is contained in:
Pontoporeia
2026-05-20 01:51:41 +02:00
parent 7a4d0fafb2
commit 93625d09b5
10 changed files with 1543 additions and 8 deletions

View File

@@ -0,0 +1,204 @@
<?php
use PHPUnit\Framework\TestCase;
/**
* ShareLinkExtendedTest — Integration tests for ShareLink methods that need a DB.
*/
class ShareLinkExtendedTest extends TestCase
{
private ShareLink $shareLink;
private PDO $pdo;
protected function setUp(): void
{
TestDatabase::resetData();
$db = TestDatabase::getInstance();
$this->shareLink = new ShareLink($db);
$this->pdo = TestDatabase::getPDO();
}
/**
* Create a share link and return its row.
*/
private function createLink(?string $name = null, ?string $expiresAt = null, ?string $objetRestriction = null): array
{
$link = $this->shareLink->create(1, $expiresAt, $objetRestriction, $name);
$this->assertNotNull($link);
return $link;
}
// ── listActive / listArchived ─────────────────────────────────────────────
public function testListActiveReturnsOnlyActiveLinks(): void
{
$this->createLink('Active One');
$active = $this->shareLink->listActive();
$this->assertCount(1, $active);
// Archive the link
$link = $this->shareLink->findBySlug($active[0]['slug']);
$this->shareLink->archive($link['id']);
$active = $this->shareLink->listActive();
$this->assertCount(0, $active);
}
public function testListArchivedReturnsOnlyArchivedLinks(): void
{
$this->createLink('To Archive');
$archived = $this->shareLink->listArchived();
$this->assertCount(0, $archived);
$link = $this->shareLink->findBySlug($this->shareLink->listActive()[0]['slug']);
$this->shareLink->archive($link['id']);
$archived = $this->shareLink->listArchived();
$this->assertCount(1, $archived);
}
// ── findBySlug ────────────────────────────────────────────────────────────
public function testFindBySlugHit(): void
{
$created = $this->createLink('Find Me');
$found = $this->shareLink->findBySlug($created['slug']);
$this->assertNotNull($found);
$this->assertSame($created['id'], $found['id']);
$this->assertSame('Find Me', $found['name']);
}
public function testFindBySlugMiss(): void
{
$found = $this->shareLink->findBySlug('nonexistent-slug');
$this->assertNull($found);
}
// ── setPassword + getDecryptedPassword round-trip ─────────────────────────
public function testSetPasswordAndDecryptRoundTrip(): void
{
$created = $this->createLink('Password Test');
// getDecryptedPassword uses encrypted_password from the DB, not _plain_password
$decrypted = $this->shareLink->getDecryptedPassword($created['id']);
$this->assertNotEmpty($decrypted);
}
public function testGetDecryptedPasswordOnNonexistentId(): void
{
$result = $this->shareLink->getDecryptedPassword(999);
$this->assertSame('', $result);
}
// ── update ────────────────────────────────────────────────────────────────
public function testUpdateChangesNameAndExpiration(): void
{
$created = $this->createLink('Original Name');
$this->shareLink->update($created['id'], 'Updated Name', '2099-12-31 23:59:59');
$updated = $this->shareLink->findBySlug($created['slug']);
$this->assertSame('Updated Name', $updated['name']);
$this->assertNotNull($updated['expires_at']);
}
public function testUpdateOnlyNameLeavesExpirationUnchanged(): void
{
$created = $this->createLink('Original', '2099-12-31 23:59:59');
$this->shareLink->update($created['id'], 'Only Name Changed', null);
$updated = $this->shareLink->findBySlug($created['slug']);
$this->assertSame('Only Name Changed', $updated['name']);
$this->assertNotNull($updated['expires_at']);
}
public function testUpdateClearsExpiration(): void
{
$created = $this->createLink('Expiry Test', '2099-12-31 23:59:59');
// Pass empty string to clear
$this->shareLink->update($created['id'], null, '');
$updated = $this->shareLink->findBySlug($created['slug']);
$this->assertNull($updated['expires_at']);
}
// ── locked_year ───────────────────────────────────────────────────────────
public function testCreateWithLockedYear(): void
{
$created = $this->shareLink->create(1, null, null, 'Locked Year Link', 2025);
$found = $this->shareLink->findBySlug($created['slug']);
$this->assertSame(2025, $found['locked_year']);
}
public function testCreateWithInvalidLockedYearRejected(): void
{
$created = $this->shareLink->create(1, null, null, 'Bad Year Link', 1800);
$found = $this->shareLink->findBySlug($created['slug']);
$this->assertNull($found['locked_year']);
}
public function testUpdateLockedYear(): void
{
$created = $this->createLink('Year Upd');
$this->shareLink->update($created['id'], null, null, '2026');
$updated = $this->shareLink->findBySlug($created['slug']);
$this->assertSame(2026, $updated['locked_year']);
}
public function testUpdateClearLockedYear(): void
{
$created = $this->shareLink->create(1, null, null, 'Year Clear', 2025);
// Empty string clears
$this->shareLink->update($created['id'], null, null, '');
$updated = $this->shareLink->findBySlug($created['slug']);
$this->assertNull($updated['locked_year']);
}
// ── incrementUsage ────────────────────────────────────────────────────────
public function testIncrementUsage(): void
{
$created = $this->createLink('Usage Test');
$found = $this->shareLink->findBySlug($created['slug']);
$this->assertSame(0, (int)$found['usage_count']);
$this->shareLink->incrementUsage($created['id']);
$this->shareLink->incrementUsage($created['id']);
$found = $this->shareLink->findBySlug($created['slug']);
$this->assertSame(2, (int)$found['usage_count']);
}
// ── Objet restriction validation ──────────────────────────────────────────
public function testCreateDefaultsToTfeWhenInvalidObjet(): void
{
$created = $this->shareLink->create(1, null, 'invalid_objet', 'Invalid Objet');
$found = $this->shareLink->findBySlug($created['slug']);
$this->assertSame('tfe', $found['objet_restriction']);
}
public function testCreateAcceptsValidObjet(): void
{
$created = $this->shareLink->create(1, null, 'thèse,frart', 'Multi Objet');
$found = $this->shareLink->findBySlug($created['slug']);
$this->assertSame('thèse,frart', $found['objet_restriction']);
}
}