mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 08:09:18 +02:00
Add PHPUnit setup (Phase 0) and pure-logic tests (Phase 1): Crypto, EmailObfuscator, SystemController helpers, StudentEmail, TfeController OG tags
This commit is contained in:
199
tests/phpunit/TfeControllerOgTest.php
Normal file
199
tests/phpunit/TfeControllerOgTest.php
Normal file
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* TfeControllerOgTest — Pure logic tests for TfeController::buildOgTags()
|
||||
* and buildMetaDescription().
|
||||
*
|
||||
* These methods are protected; we use a thin subclass to expose them.
|
||||
*/
|
||||
class TfeControllerOgTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Subclass that exposes protected methods for testing.
|
||||
*/
|
||||
private static function makeController(): object
|
||||
{
|
||||
return new class extends TfeController {
|
||||
public function __construct()
|
||||
{
|
||||
// Skip parent constructor — we don't need DB for these pure methods
|
||||
}
|
||||
|
||||
public function exposedBuildOgTags(array $data, int $thesisId, string $metaDescription): array
|
||||
{
|
||||
return $this->buildOgTags($data, $thesisId, $metaDescription);
|
||||
}
|
||||
|
||||
public function exposedBuildMetaDescription(string $synopsis): string
|
||||
{
|
||||
return $this->buildMetaDescription($synopsis);
|
||||
}
|
||||
|
||||
public function exposedResolveOgImage(array $files): string
|
||||
{
|
||||
return $this->resolveOgImage($files);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ── buildOgTags() ─────────────────────────────────────────────────────────
|
||||
|
||||
public function testBuildOgTagsReturnsAllRequiredKeys(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$data = [
|
||||
'title' => 'My Thesis',
|
||||
'authors' => 'Jane Doe',
|
||||
'year' => '2024',
|
||||
'files' => [],
|
||||
];
|
||||
|
||||
$tags = $ctrl->exposedBuildOgTags($data, 42, 'A description');
|
||||
|
||||
$requiredKeys = ['type', 'title', 'description', 'url', 'image', 'image_alt', 'site_name', 'article_author', 'article_published_time'];
|
||||
foreach ($requiredKeys as $key) {
|
||||
$this->assertArrayHasKey($key, $tags);
|
||||
$this->assertIsString($tags[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
public function testBuildOgTagsTitleIncludesAuthors(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$data = [
|
||||
'title' => 'The Title',
|
||||
'authors' => 'Author Name',
|
||||
'year' => '2024',
|
||||
'files' => [],
|
||||
];
|
||||
|
||||
$tags = $ctrl->exposedBuildOgTags($data, 1, 'desc');
|
||||
|
||||
$this->assertStringContainsString('The Title – Author Name', $tags['title']);
|
||||
|
||||
// Without authors, just the title
|
||||
$data['authors'] = '';
|
||||
$tags2 = $ctrl->exposedBuildOgTags($data, 1, 'desc');
|
||||
$this->assertSame('The Title', $tags2['title']);
|
||||
}
|
||||
|
||||
public function testBuildOgTagsImageEmptyWhenNoFiles(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$data = [
|
||||
'title' => 'No Files',
|
||||
'authors' => 'A',
|
||||
'year' => '2023',
|
||||
'files' => [],
|
||||
];
|
||||
|
||||
$tags = $ctrl->exposedBuildOgTags($data, 5, 'desc');
|
||||
$this->assertSame('', $tags['image']);
|
||||
}
|
||||
|
||||
public function testBuildOgTagsImageFromCover(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$data = [
|
||||
'title' => 'Cover Test',
|
||||
'authors' => 'Author',
|
||||
'year' => '2024',
|
||||
'files' => [
|
||||
['file_path' => 'documents/2024-001/cover.jpg', 'file_type' => 'cover'],
|
||||
],
|
||||
];
|
||||
|
||||
$tags = $ctrl->exposedBuildOgTags($data, 1, 'desc');
|
||||
|
||||
$this->assertStringContainsString('cover.jpg', $tags['image']);
|
||||
}
|
||||
|
||||
public function testBuildOgTagsImageFallbackToFirstImage(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$data = [
|
||||
'title' => 'Image Test',
|
||||
'authors' => 'B',
|
||||
'year' => '2024',
|
||||
'files' => [
|
||||
['file_path' => 'documents/2024-001/doc.pdf', 'file_type' => 'tfe'],
|
||||
['file_path' => 'documents/2024-001/screenshot.png', 'file_type' => 'tfe'],
|
||||
],
|
||||
];
|
||||
|
||||
$tags = $ctrl->exposedBuildOgTags($data, 2, 'desc');
|
||||
|
||||
$this->assertStringContainsString('screenshot.png', $tags['image']);
|
||||
}
|
||||
|
||||
public function testBuildOgTagsUrlIncludesThesisId(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$data = ['title' => 'URL Test', 'authors' => '', 'year' => '2024', 'files' => []];
|
||||
|
||||
$tags = $ctrl->exposedBuildOgTags($data, 99, 'desc');
|
||||
|
||||
$this->assertStringContainsString('tfe?id=99', $tags['url']);
|
||||
}
|
||||
|
||||
public function testBuildOgTagsPublishedTimeFormatted(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$data = ['title' => 'T', 'authors' => '', 'year' => '2025', 'files' => []];
|
||||
|
||||
$tags = $ctrl->exposedBuildOgTags($data, 1, 'desc');
|
||||
|
||||
$this->assertSame('2025-01-01', $tags['article_published_time']);
|
||||
}
|
||||
|
||||
public function testBuildOgTagsPublishedTimeEmptyWhenNoYear(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$data = ['title' => 'T', 'authors' => '', 'files' => []];
|
||||
|
||||
$tags = $ctrl->exposedBuildOgTags($data, 1, 'desc');
|
||||
|
||||
$this->assertSame('', $tags['article_published_time']);
|
||||
}
|
||||
|
||||
// ── buildMetaDescription() ────────────────────────────────────────────────
|
||||
|
||||
public function testBuildMetaDescriptionTruncatesLongSynopsis(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$long = str_repeat('abcdefghij', 20); // 200 chars
|
||||
$desc = $ctrl->exposedBuildMetaDescription($long);
|
||||
|
||||
$this->assertLessThanOrEqual(160, strlen($desc));
|
||||
$this->assertStringEndsWith('…', $desc);
|
||||
}
|
||||
|
||||
public function testBuildMetaDescriptionKeepsShortSynopsis(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$desc = $ctrl->exposedBuildMetaDescription('A short synopsis.');
|
||||
|
||||
$this->assertSame('A short synopsis.', $desc);
|
||||
}
|
||||
|
||||
public function testBuildMetaDescriptionEmptySynopsisReturnsDefault(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$desc = $ctrl->exposedBuildMetaDescription('');
|
||||
|
||||
$this->assertStringContainsString('Mémoire', $desc);
|
||||
$this->assertStringContainsString('XAMXAM', $desc);
|
||||
}
|
||||
|
||||
public function testBuildMetaDescriptionStripsHtmlTags(): void
|
||||
{
|
||||
$ctrl = self::makeController();
|
||||
$desc = $ctrl->exposedBuildMetaDescription('<p>Hello <b>world</b></p>');
|
||||
|
||||
$this->assertStringNotContainsString('<p>', $desc);
|
||||
$this->assertStringNotContainsString('<b>', $desc);
|
||||
$this->assertStringContainsString('Hello world', $desc);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user