withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get('api/tests'); $result->assertStatus(200); $result->assertJSONExact([ 'status' => 'success', 'message' => 'Data fetched successfully', 'data' => $result->getJSON(true)['data'] ]); } /** * Test listing all tests returns array */ public function testIndexReturnsArray(): void { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get('api/tests'); $result->assertStatus(200); $response = $result->getJSON(true); $this->assertIsArray($response['data']); } /** * Test index contains test type information */ public function testIndexContainsTypeInformation(): void { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get('api/tests'); $result->assertStatus(200); $response = $result->getJSON(true); if (!empty($response['data'])) { $test = $response['data'][0]; $this->assertArrayHasKey('TypeCode', $test); $this->assertArrayHasKey('TypeName', $test); } } /** * Test filtering by test type */ public function testIndexFiltersByTestType(): void { // Test filtering by TEST type (VID = 1) $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get('api/tests?TestType=1'); $result->assertStatus(200); $response = $result->getJSON(true); foreach ($response['data'] as $test) { $this->assertEquals('TEST', $test['TypeCode']); } } /** * Test filtering by keyword */ public function testIndexFiltersByKeyword(): void { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get('api/tests?TestSiteName=HB'); $result->assertStatus(200); $response = $result->getJSON(true); if (!empty($response['data'])) { foreach ($response['data'] as $test) { $this->assertStringContainsString('HB', $test['TestSiteName']); } } } /** * Test showing single test returns success */ public function testShowReturnsSuccess(): void { // Get a test ID from the seeder data $model = new TestDefSiteModel(); $test = $model->first(); if ($test) { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get("api/tests/{$test['TestSiteID']}"); $result->assertStatus(200); $response = $result->getJSON(true); $this->assertArrayHasKey('data', $response); } else { $this->markTestSkipped('No test data available'); } } /** * Test showing single test includes type-specific details for TEST type */ public function testShowIncludesTechDetailsForTestType(): void { $model = new TestDefSiteModel(); $test = $model->first(); if ($test && $test['TypeCode'] === 'TEST') { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get("api/tests/{$test['TestSiteID']}"); $result->assertStatus(200); $response = $result->getJSON(true); $this->assertArrayHasKey('testdeftech', $response['data']); } else { $this->markTestSkipped('No TEST type data available'); } } /** * Test showing single test includes type-specific details for CALC type */ public function testShowIncludesCalcDetailsForCalcType(): void { $model = new TestDefSiteModel(); $test = $model->first(); if ($test && $test['TypeCode'] === 'CALC') { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get("api/tests/{$test['TestSiteID']}"); $result->assertStatus(200); $response = $result->getJSON(true); $this->assertArrayHasKey('testdefcal', $response['data']); } else { $this->markTestSkipped('No CALC type data available'); } } /** * Test showing single test includes type-specific details for GROUP type */ public function testShowIncludesGrpDetailsForGroupType(): void { $model = new TestDefSiteModel(); $test = $model->first(); if ($test && $test['TypeCode'] === 'GROUP') { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get("api/tests/{$test['TestSiteID']}"); $result->assertStatus(200); $response = $result->getJSON(true); $this->assertArrayHasKey('testdefgrp', $response['data']); } else { $this->markTestSkipped('No GROUP type data available'); } } /** * Test creating a new test */ public function testCreateTest(): void { $testData = [ 'SiteID' => 1, 'TestSiteCode' => 'NEWTEST', 'TestSiteName' => 'New Test', 'TestType' => 1, // TEST type 'Description' => 'Test description', 'SeqScr' => 100, 'SeqRpt' => 100, 'VisibleScr' => 1, 'VisibleRpt' => 1, 'CountStat' => 1 ]; $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->post('api/tests', $testData); $result->assertStatus(201); $response = $result->getJSON(true); $this->assertArrayHasKey('data', $response); $this->assertArrayHasKey('TestSiteId', $response['data']); } /** * Test creating test with validation error (missing required fields) */ public function testCreateTestValidationError(): void { $testData = [ 'SiteID' => 1 // Missing required fields ]; $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->post('api/tests', $testData); $result->assertStatus(400); } /** * Test updating a test */ public function testUpdateTest(): void { $model = new TestDefSiteModel(); $test = $model->first(); if ($test) { $updateData = [ 'TestSiteID' => $test['TestSiteID'], 'TestSiteName' => 'Updated Test Name', 'Description' => 'Updated description' ]; $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->patch('api/tests', $updateData); $result->assertStatus(200); $response = $result->getJSON(true); $this->assertEquals('success', $response['status']); } else { $this->markTestSkipped('No test data available'); } } /** * Test deleting a test (soft delete) */ public function testDeleteTest(): void { $model = new TestDefSiteModel(); $test = $model->first(); if ($test) { $deleteData = [ 'TestSiteID' => $test['TestSiteID'] ]; $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->delete('api/tests', $deleteData); $result->assertStatus(200); $response = $result->getJSON(true); $this->assertEquals('success', $response['status']); $this->assertArrayHasKey('EndDate', $response['data']); } else { $this->markTestSkipped('No test data available'); } } /** * Test getting non-existent test returns empty data */ public function testShowNonExistentTest(): void { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get('api/tests/999999'); $result->assertStatus(200); $response = $result->getJSON(true); $this->assertNull($response['data']); } /** * Test test types are correctly mapped from valueset */ public function testTestTypesAreMapped(): void { $model = new TestDefSiteModel(); $tests = $model->findAll(); $validTypes = ['TEST', 'PARAM', 'CALC', 'GROUP', 'TITLE']; foreach ($tests as $test) { if (isset($test['TypeCode'])) { $this->assertContains($test['TypeCode'], $validTypes); } } } /** * Test filtering by visible on screen */ public function testIndexFiltersByVisibleScr(): void { $result = $this->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ])->get('api/tests?VisibleScr=1'); $result->assertStatus(200); $response = $result->getJSON(true); foreach ($response['data'] as $test) { $this->assertEquals(1, $test['VisibleScr']); } } /** * Test all test types from seeder are present */ public function testAllTestTypesArePresent(): void { $model = new TestDefSiteModel(); $tests = $model->findAll(); $typeCodes = array_column($tests, 'TypeCode'); $uniqueTypes = array_unique($typeCodes); // Check that we have at least TEST and PARAM types from seeder $this->assertContains('TEST', $uniqueTypes); $this->assertContains('PARAM', $uniqueTypes); $this->assertContains('CALC', $uniqueTypes); $this->assertContains('GROUP', $uniqueTypes); } }