1
0

UserRepositoryTest.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Tests\Repositories;
  4. use App\Repositories\UserRepository;
  5. use App\Tests\TestCase;
  6. /**
  7. * Covers the first-user-is-admin bootstrap rule from spec §4.
  8. */
  9. final class UserRepositoryTest extends TestCase
  10. {
  11. public function testFirstUserBecomesAdminWhenPromoted(): void
  12. {
  13. $pdo = $this->makeDb();
  14. $users = new UserRepository($pdo);
  15. $this->assertSame(0, $users->count());
  16. $r = $users->upsertFromOidc(
  17. oid: 'oid-alice',
  18. email: 'alice@example.com',
  19. name: 'Alice',
  20. promoteToAdmin: true, // caller's decision — normally based on count === 0
  21. );
  22. $this->assertTrue($r['user']->isAdmin);
  23. $this->assertNull($r['before']);
  24. }
  25. public function testSecondUserDoesNotBecomeAdmin(): void
  26. {
  27. $pdo = $this->makeDb();
  28. $users = new UserRepository($pdo);
  29. $users->upsertFromOidc('oid-alice', 'alice@x', 'Alice', true);
  30. $secondPromote = $users->count() === 0; // false
  31. $r2 = $users->upsertFromOidc('oid-bob', 'bob@x', 'Bob', $secondPromote);
  32. $this->assertFalse($r2['user']->isAdmin);
  33. }
  34. public function testReLoginDoesNotRegressAdminStatus(): void
  35. {
  36. $pdo = $this->makeDb();
  37. $users = new UserRepository($pdo);
  38. $users->upsertFromOidc('oid-alice', 'alice@x', 'Alice', true);
  39. // simulate a later login: count > 0 so promoteToAdmin=false
  40. $r = $users->upsertFromOidc('oid-alice', 'alice@x', 'Alice', false);
  41. $this->assertTrue($r['user']->isAdmin, 're-login must not demote admin');
  42. $this->assertNotNull($r['before']);
  43. }
  44. public function testForceAdminPromotesEvenOnUpdate(): void
  45. {
  46. // Local-admin login path sets forceAdmin=true so a demoted user gets
  47. // promoted back on next sign-in.
  48. $pdo = $this->makeDb();
  49. $users = new UserRepository($pdo);
  50. $r1 = $users->upsertFromOidc('local:admin@x', 'admin@x', 'Admin', true, true);
  51. $this->assertTrue($r1['user']->isAdmin);
  52. // Manually demote.
  53. $pdo->exec('UPDATE users SET is_admin = 0 WHERE id = ' . $r1['user']->id);
  54. $r2 = $users->upsertFromOidc('local:admin@x', 'admin@x', 'Admin', false, true);
  55. $this->assertTrue($r2['user']->isAdmin, 'forceAdmin must re-promote on update');
  56. }
  57. public function testUpsertUpdatesEmailAndName(): void
  58. {
  59. $pdo = $this->makeDb();
  60. $users = new UserRepository($pdo);
  61. $users->upsertFromOidc('oid-alice', 'old@x', 'Old Name', true);
  62. $r = $users->upsertFromOidc('oid-alice', 'new@x', 'New Name', false);
  63. $this->assertSame('new@x', $r['user']->email);
  64. $this->assertSame('New Name', $r['user']->displayName);
  65. }
  66. public function testCountReflectsInsertedUsers(): void
  67. {
  68. $pdo = $this->makeDb();
  69. $users = new UserRepository($pdo);
  70. $this->assertSame(0, $users->count());
  71. $users->upsertFromOidc('oid-1', 'a@x', 'A', true);
  72. $this->assertSame(1, $users->count());
  73. $users->upsertFromOidc('oid-2', 'b@x', 'B', false);
  74. $this->assertSame(2, $users->count());
  75. // Re-upsert existing user shouldn't add a row.
  76. $users->upsertFromOidc('oid-1', 'a@x', 'A', false);
  77. $this->assertSame(2, $users->count());
  78. }
  79. }