1
0

SprintWeekRepositoryTest.php 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Tests\Repositories;
  4. use App\Domain\SprintWeek;
  5. use App\Repositories\SprintRepository;
  6. use App\Repositories\SprintWeekRepository;
  7. use App\Tests\TestCase;
  8. /**
  9. * Phase 12: per-week weekday selection drives Arbeitstage.
  10. */
  11. final class SprintWeekRepositoryTest extends TestCase
  12. {
  13. /** @return array{SprintRepository, SprintWeekRepository, int} */
  14. private function seedSprint(): array
  15. {
  16. $pdo = $this->makeDb();
  17. $sprints = new SprintRepository($pdo);
  18. $weeks = new SprintWeekRepository($pdo);
  19. $sprint = $sprints->create('S', '2026-01-05', '2026-01-30', 0.2);
  20. $sprints->materializeWeeks($sprint->id, '2026-01-05', 4);
  21. return [$sprints, $weeks, $sprint->id];
  22. }
  23. public function testMaterializeWeeksDefaultsToAllFiveDays(): void
  24. {
  25. [, $weeks, $sprintId] = $this->seedSprint();
  26. $rows = $weeks->allForSprint($sprintId);
  27. $this->assertCount(4, $rows);
  28. foreach ($rows as $w) {
  29. $this->assertSame(SprintWeek::MASK_ALL, $w->activeDaysMask);
  30. $this->assertSame(5.0, $w->maxWorkingDays);
  31. }
  32. }
  33. public function testUpdateActiveDaysWritesBothColumns(): void
  34. {
  35. [, $weeks, $sprintId] = $this->seedSprint();
  36. $first = $weeks->allForSprint($sprintId)[0];
  37. $result = $weeks->updateActiveDays($first->id, 0b01111); // drop Fr
  38. $this->assertSame(SprintWeek::MASK_ALL, $result['before']->activeDaysMask);
  39. $this->assertSame(0b01111, $result['after']->activeDaysMask);
  40. $this->assertSame(4.0, $result['after']->maxWorkingDays);
  41. // Second query hydrates the same row from disk.
  42. $reloaded = $weeks->find($first->id);
  43. $this->assertNotNull($reloaded);
  44. $this->assertSame(0b01111, $reloaded->activeDaysMask);
  45. $this->assertSame(4.0, $reloaded->maxWorkingDays);
  46. }
  47. public function testUpdateActiveDaysClampsBitsOutsideMoFr(): void
  48. {
  49. [, $weeks, $sprintId] = $this->seedSprint();
  50. $first = $weeks->allForSprint($sprintId)[0];
  51. $result = $weeks->updateActiveDays($first->id, 0xFF);
  52. $this->assertSame(SprintWeek::MASK_ALL, $result['after']->activeDaysMask);
  53. $this->assertSame(5.0, $result['after']->maxWorkingDays);
  54. }
  55. public function testUpdateActiveDaysToEmptyMaskZeroesCount(): void
  56. {
  57. [, $weeks, $sprintId] = $this->seedSprint();
  58. $first = $weeks->allForSprint($sprintId)[0];
  59. $result = $weeks->updateActiveDays($first->id, 0);
  60. $this->assertSame(0, $result['after']->activeDaysMask);
  61. $this->assertSame(0.0, $result['after']->maxWorkingDays);
  62. $this->assertSame([], $result['after']->activeDays());
  63. }
  64. public function testSyncCountAppendsWeeksWithAllDaysActive(): void
  65. {
  66. [, $weeks, $sprintId] = $this->seedSprint();
  67. $diff = $weeks->syncCount($sprintId, '2026-01-05', 6);
  68. $this->assertCount(2, $diff['added']);
  69. foreach ($diff['added'] as $w) {
  70. $this->assertSame(SprintWeek::MASK_ALL, $w->activeDaysMask);
  71. $this->assertSame(5.0, $w->maxWorkingDays);
  72. }
  73. }
  74. }