diff --git a/api/tests/Feature/Database/ActivityLogIndexesTest.php b/api/tests/Feature/Database/ActivityLogIndexesTest.php new file mode 100644 index 00000000..62c9885c --- /dev/null +++ b/api/tests/Feature/Database/ActivityLogIndexesTest.php @@ -0,0 +1,92 @@ +assertCompositeIndexExists( + table: 'activity_log', + columns: ['subject_type', 'subject_id'], + description: 'subject composite index (RFC-WS-7 §3.14 / D-06)', + ); + } + + public function test_causer_composite_index_exists(): void + { + $this->assertCompositeIndexExists( + table: 'activity_log', + columns: ['causer_type', 'causer_id'], + description: 'causer composite index (RFC-WS-7 §3.14 / D-06)', + ); + } + + /** + * @param list $columns + */ + private function assertCompositeIndexExists(string $table, array $columns, string $description): void + { + $database = config('database.connections.mysql.database'); + + $rows = DB::select( + 'SELECT INDEX_NAME, COLUMN_NAME, SEQ_IN_INDEX + FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = ? + AND TABLE_NAME = ? + ORDER BY INDEX_NAME, SEQ_IN_INDEX', + [$database, $table], + ); + + $indexColumns = []; + foreach ($rows as $row) { + $indexColumns[$row->INDEX_NAME][(int) $row->SEQ_IN_INDEX] = $row->COLUMN_NAME; + } + + $found = false; + foreach ($indexColumns as $sequence) { + ksort($sequence); + if (array_values($sequence) === $columns) { + $found = true; + break; + } + } + + $this->assertTrue( + $found, + sprintf( + 'Expected composite index on %s(%s) — %s. Found indexes: %s', + $table, + implode(', ', $columns), + $description, + json_encode($indexColumns, JSON_PRETTY_PRINT), + ), + ); + } +}