180 lines
6.6 KiB
PHP
180 lines
6.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace TekDek\Employees\Tests;
|
|
|
|
use PDO;
|
|
use PHPUnit\Framework\TestCase;
|
|
use TekDek\Employees\EmployeeRepository;
|
|
|
|
/**
|
|
* Tests for EmployeeRepository using SQLite in-memory.
|
|
*/
|
|
class EmployeeRepositoryTest extends TestCase
|
|
{
|
|
private PDO $pdo;
|
|
private EmployeeRepository $repo;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->pdo = new PDO('sqlite::memory:');
|
|
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|
|
|
// Create table (SQLite-compatible schema)
|
|
$this->pdo->exec("
|
|
CREATE TABLE employees (
|
|
id TEXT PRIMARY KEY,
|
|
slug TEXT UNIQUE NOT NULL,
|
|
name TEXT NOT NULL,
|
|
title TEXT NOT NULL,
|
|
role TEXT NOT NULL,
|
|
tagline TEXT,
|
|
bio TEXT NOT NULL,
|
|
mythology TEXT NOT NULL,
|
|
avatar_url TEXT,
|
|
accent_color TEXT,
|
|
symbol TEXT,
|
|
skills TEXT,
|
|
quote TEXT,
|
|
sort_order INTEGER DEFAULT 0,
|
|
created_at TEXT DEFAULT (datetime('now')),
|
|
updated_at TEXT DEFAULT (datetime('now'))
|
|
)
|
|
");
|
|
|
|
$this->seedTestData();
|
|
$this->repo = new EmployeeRepository($this->pdo);
|
|
}
|
|
|
|
private function seedTestData(): void
|
|
{
|
|
$employees = [
|
|
[
|
|
'id' => 'uuid-daedalus',
|
|
'slug' => 'daedalus',
|
|
'name' => 'Daedalus',
|
|
'title' => 'Chief Architect',
|
|
'role' => 'Architecture & Systems Design',
|
|
'tagline' => 'The master builder.',
|
|
'bio' => 'Daedalus is the architectural mind behind TekDek.',
|
|
'mythology' => 'Named for the mythological master craftsman.',
|
|
'avatar_url' => null,
|
|
'accent_color' => '#C4A24E',
|
|
'symbol' => 'labyrinth',
|
|
'skills' => '["System Architecture", "Database Design"]',
|
|
'quote' => 'A well-designed system is indistinguishable from inevitability.',
|
|
'sort_order' => 1,
|
|
],
|
|
[
|
|
'id' => 'uuid-talos',
|
|
'slug' => 'talos',
|
|
'name' => 'Talos',
|
|
'title' => 'Lead Backend Engineer',
|
|
'role' => 'Backend Engineering & Implementation',
|
|
'tagline' => 'The bronze guardian.',
|
|
'bio' => 'Talos is the engine room of TekDek.',
|
|
'mythology' => 'Named for the giant bronze automaton.',
|
|
'avatar_url' => null,
|
|
'accent_color' => '#7B8794',
|
|
'symbol' => 'gear',
|
|
'skills' => '["PHP", "MySQL", "REST APIs"]',
|
|
'quote' => 'If it compiles but can\'t survive production, it doesn\'t exist.',
|
|
'sort_order' => 2,
|
|
],
|
|
[
|
|
'id' => 'uuid-icarus',
|
|
'slug' => 'icarus',
|
|
'name' => 'Icarus',
|
|
'title' => 'Lead Frontend Engineer',
|
|
'role' => 'Frontend & UI Design',
|
|
'tagline' => 'Flying close to the sun.',
|
|
'bio' => 'Icarus is the face of TekDek.',
|
|
'mythology' => 'Named for the son of Daedalus.',
|
|
'avatar_url' => null,
|
|
'accent_color' => '#E07A2F',
|
|
'symbol' => 'wings',
|
|
'skills' => '["UI/UX Design", "React", "CSS/Animation"]',
|
|
'quote' => 'Users don\'t remember backends. They remember how it felt.',
|
|
'sort_order' => 3,
|
|
],
|
|
];
|
|
|
|
$stmt = $this->pdo->prepare("
|
|
INSERT INTO employees (id, slug, name, title, role, tagline, bio, mythology, avatar_url, accent_color, symbol, skills, quote, sort_order)
|
|
VALUES (:id, :slug, :name, :title, :role, :tagline, :bio, :mythology, :avatar_url, :accent_color, :symbol, :skills, :quote, :sort_order)
|
|
");
|
|
|
|
foreach ($employees as $emp) {
|
|
$stmt->execute($emp);
|
|
}
|
|
}
|
|
|
|
public function testGetAllReturnsAllEmployees(): void
|
|
{
|
|
$result = $this->repo->getAll();
|
|
$this->assertCount(3, $result);
|
|
}
|
|
|
|
public function testGetAllReturnsSortedBySortOrder(): void
|
|
{
|
|
$result = $this->repo->getAll();
|
|
$this->assertSame('daedalus', $result[0]['slug']);
|
|
$this->assertSame('talos', $result[1]['slug']);
|
|
$this->assertSame('icarus', $result[2]['slug']);
|
|
}
|
|
|
|
public function testGetAllDecodesSkillsJson(): void
|
|
{
|
|
$result = $this->repo->getAll();
|
|
$this->assertIsArray($result[0]['skills']);
|
|
$this->assertContains('System Architecture', $result[0]['skills']);
|
|
}
|
|
|
|
public function testGetAllCastsSortOrder(): void
|
|
{
|
|
$result = $this->repo->getAll();
|
|
$this->assertSame(1, $result[0]['sort_order']);
|
|
$this->assertSame(2, $result[1]['sort_order']);
|
|
}
|
|
|
|
public function testGetBySlugReturnsEmployee(): void
|
|
{
|
|
$result = $this->repo->getBySlug('talos');
|
|
$this->assertNotNull($result);
|
|
$this->assertSame('Talos', $result['name']);
|
|
$this->assertSame('#7B8794', $result['accent_color']);
|
|
$this->assertSame('gear', $result['symbol']);
|
|
}
|
|
|
|
public function testGetBySlugReturnsNullForMissing(): void
|
|
{
|
|
$result = $this->repo->getBySlug('nonexistent');
|
|
$this->assertNull($result);
|
|
}
|
|
|
|
public function testGetBySlugDecodesSkills(): void
|
|
{
|
|
$result = $this->repo->getBySlug('icarus');
|
|
$this->assertIsArray($result['skills']);
|
|
$this->assertContains('React', $result['skills']);
|
|
}
|
|
|
|
public function testGetAllReturnsEmptyWhenNoData(): void
|
|
{
|
|
$this->pdo->exec('DELETE FROM employees');
|
|
$result = $this->repo->getAll();
|
|
$this->assertSame([], $result);
|
|
}
|
|
|
|
public function testGetBySlugReturnsAllFields(): void
|
|
{
|
|
$result = $this->repo->getBySlug('daedalus');
|
|
$expectedKeys = ['id', 'slug', 'name', 'title', 'role', 'tagline', 'bio', 'mythology', 'avatar_url', 'accent_color', 'symbol', 'skills', 'quote', 'sort_order', 'created_at', 'updated_at'];
|
|
foreach ($expectedKeys as $key) {
|
|
$this->assertArrayHasKey($key, $result, "Missing key: {$key}");
|
|
}
|
|
}
|
|
}
|