WorldCupRepositoryNoLockTest.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. namespace Tests\Unit;
  3. use PHPUnit\Framework\TestCase;
  4. class WorldCupRepositoryNoLockTest extends TestCase
  5. {
  6. public function testReadConnectionTableQueriesUseNoLock(): void
  7. {
  8. foreach ($this->repositoryFiles() as $file) {
  9. $content = file_get_contents($file);
  10. preg_match_all(
  11. "/DB::connection\\('read'\\)->table\\([\\s\\S]*?->(?:first|get|exists|pluck|value)\\(/",
  12. $content,
  13. $matches
  14. );
  15. foreach ($matches[0] as $query) {
  16. $this->assertContains(
  17. "->lock('WITH (NOLOCK)')",
  18. $query,
  19. basename($file) . ' has a read query without WITH (NOLOCK): ' . $this->compactQuery($query)
  20. );
  21. }
  22. }
  23. }
  24. public function testJoinedTablesUseNoLockHints(): void
  25. {
  26. foreach ($this->repositoryFiles() as $file) {
  27. $content = file_get_contents($file);
  28. preg_match_all('/->(?:leftJoin|join)\\(([\\s\\S]*?)\\n\\s*\\)/', $content, $matches);
  29. foreach ($matches[0] as $join) {
  30. $this->assertContains(
  31. 'WITH (NOLOCK)',
  32. $join,
  33. basename($file) . ' has a joined table without WITH (NOLOCK): ' . $this->compactQuery($join)
  34. );
  35. }
  36. }
  37. }
  38. public function testDynamicConnectionReadQueriesUseNoLockBranch(): void
  39. {
  40. foreach ($this->repositoryFiles() as $file) {
  41. $content = file_get_contents($file);
  42. preg_match_all(
  43. '/DB::connection\\(\\$connection\\)->table\\([\\s\\S]*?->(?:first|get|exists|pluck|value)\\(/',
  44. $content,
  45. $matches
  46. );
  47. foreach ($matches[0] as $query) {
  48. $this->assertContains(
  49. "if (\$connection === 'read')",
  50. $query,
  51. basename($file) . ' has a dynamic read query without a read-only branch: '
  52. . $this->compactQuery($query)
  53. );
  54. $this->assertContains(
  55. "->lock('WITH (NOLOCK)')",
  56. $query,
  57. basename($file) . ' has a dynamic read query without WITH (NOLOCK): '
  58. . $this->compactQuery($query)
  59. );
  60. }
  61. }
  62. }
  63. public function testSettlementUsesStoredBetOddsInsteadOfCurrentOdds(): void
  64. {
  65. $content = file_get_contents(
  66. __DIR__ . '/../../app/Services/WorldCup/Repositories/SqlWorldCupSettlementRepository.php'
  67. );
  68. $this->assertNotContains('applyCurrentOdds', $content);
  69. $this->assertNotContains('currentOdds', $content);
  70. $this->assertNotContains('self::ODDS_TABLE', $this->methodBody($content, 'payBet'));
  71. }
  72. public function testReferralRewardLogOnlyFiltersCurrentUserAsReferrer(): void
  73. {
  74. $content = file_get_contents(
  75. __DIR__ . '/../../app/Services/WorldCup/Repositories/SqlWorldCupReferralRepository.php'
  76. );
  77. $rewardLogs = $this->methodBody($content, 'rewardLogs');
  78. $rewardStats = $this->methodBody($content, 'rewardStats');
  79. $this->assertContains("->where('rw.referrer_id', \$userId)", $rewardLogs);
  80. $this->assertNotContains("->orWhere('rw.invitee_id', \$userId)", $rewardLogs);
  81. $this->assertContains("->where('referrer_id', \$userId)", $rewardStats);
  82. $this->assertNotContains("->orWhere('invitee_id', \$userId)", $rewardStats);
  83. }
  84. private function repositoryFiles(): array
  85. {
  86. return glob(__DIR__ . '/../../app/Services/WorldCup/Repositories/SqlWorldCup*Repository.php');
  87. }
  88. private function compactQuery(string $query): string
  89. {
  90. return preg_replace('/\\s+/', ' ', trim($query));
  91. }
  92. private function methodBody(string $content, string $method): string
  93. {
  94. $pattern = '/public function ' . preg_quote($method, '/') . '\\([\\s\\S]*?\\n }/';
  95. preg_match($pattern, $content, $matches);
  96. $this->assertNotEmpty($matches, 'Method not found: ' . $method);
  97. return $matches[0];
  98. }
  99. }