get($this->endpoint); $result->assertStatus(200); $body = json_decode($result->response()->getBody(), true); $this->assertArrayHasKey('status', $body); $this->assertArrayHasKey('data', $body); $this->assertArrayHasKey('message', $body); } /** * Test index with SiteID filter */ public function testIndexWithSiteFilter(): void { $result = $this->get($this->endpoint . '?SiteID=1'); $result->assertStatus(200); $body = json_decode($result->response()->getBody(), true); $this->assertEquals('success', $body['status']); } /** * Test index with TestType filter */ public function testIndexWithTestTypeFilter(): void { // Filter by TEST type $result = $this->get($this->endpoint . '?TestType=TEST'); $result->assertStatus(200); $body = json_decode($result->response()->getBody(), true); $this->assertEquals('success', $body['status']); } /** * Test index with Visibility filter */ public function testIndexWithVisibilityFilter(): void { $result = $this->get($this->endpoint . '?VisibleScr=1&VisibleRpt=1'); $result->assertStatus(200); $body = json_decode($result->response()->getBody(), true); $this->assertEquals('success', $body['status']); } /** * Test index with keyword search */ public function testIndexWithKeywordSearch(): void { $result = $this->get($this->endpoint . '?TestSiteName=hemoglobin'); $result->assertStatus(200); $body = json_decode($result->response()->getBody(), true); $this->assertEquals('success', $body['status']); } /** * Test show endpoint returns single test */ public function testShowReturnsSingleTest(): void { // First get the list to find a valid ID $indexResult = $this->get($this->endpoint); $indexBody = json_decode($indexResult->response()->getBody(), true); if (isset($indexBody['data']) && is_array($indexBody['data']) && !empty($indexBody['data'])) { $firstItem = $indexBody['data'][0]; $testSiteID = $firstItem['TestSiteID'] ?? null; if ($testSiteID) { $showResult = $this->get($this->endpoint . '/' . $testSiteID); $showResult->assertStatus(200); $body = json_decode($showResult->response()->getBody(), true); $this->assertArrayHasKey('data', $body); $this->assertEquals('success', $body['status']); // Check that related details are loaded based on TestType if ($body['data'] !== null) { $typeCode = $body['data']['TypeCode'] ?? ''; if ($typeCode === 'CALC') { $this->assertArrayHasKey('testdefcal', $body['data']); } elseif ($typeCode === 'GROUP') { $this->assertArrayHasKey('testdefgrp', $body['data']); } elseif (in_array($typeCode, ['TEST', 'PARAM'])) { $this->assertArrayHasKey('testdeftech', $body['data']); } // All types should have testmap $this->assertArrayHasKey('testmap', $body['data']); } } } } /** * Test show with non-existent ID returns null data */ public function testShowWithInvalidIDReturnsNull(): void { $result = $this->get($this->endpoint . '/9999999'); $result->assertStatus(200); $body = json_decode($result->response()->getBody(), true); $this->assertArrayHasKey('data', $body); $this->assertNull($body['data']); } /** * Test create new TEST type test definition */ public function testCreateTestTypeTest(): void { $testData = $this->createTestData(); $result = $this->post($this->endpoint, ['body' => json_encode($testData)]); $status = $result->response()->getStatusCode(); // Expect 201 (created) or 400 (validation error) or 500 (server error) $this->assertTrue( in_array($status, [201, 400, 500]), "Expected 201, 400, or 500, got $status" ); if ($status === 201) { $body = json_decode($result->response()->getBody(), true); $this->assertEquals('created', $body['status']); $this->assertArrayHasKey('TestSiteId', $body['data']); } } /** * Test create new PARAM type test definition */ public function testCreateParamTypeTest(): void { $paramData = $this->createParamData(); $result = $this->post($this->endpoint, ['body' => json_encode($paramData)]); $status = $result->response()->getStatusCode(); $this->assertTrue( in_array($status, [201, 400, 500]), "Expected 201, 400, or 500, got $status" ); } /** * Test create new GROUP type test definition */ public function testCreateGroupTypeTest(): void { // First create some member tests $memberIds = $this->getExistingTestIds(); $groupData = $this->createGroupData($memberIds); $result = $this->post($this->endpoint, ['body' => json_encode($groupData)]); $status = $result->response()->getStatusCode(); $this->assertTrue( in_array($status, [201, 400, 500]), "Expected 201, 400, or 500, got $status" ); } /** * Test create new CALC type test definition */ public function testCreateCalcTypeTest(): void { $calcData = $this->createCalcData(); $result = $this->post($this->endpoint, ['body' => json_encode($calcData)]); $status = $result->response()->getStatusCode(); $this->assertTrue( in_array($status, [201, 400, 500]), "Expected 201, 400, or 500, got $status" ); } /** * Test update existing test */ public function testUpdateTest(): void { $indexResult = $this->get($this->endpoint); $indexBody = json_decode($indexResult->response()->getBody(), true); if (isset($indexBody['data']) && is_array($indexBody['data']) && !empty($indexBody['data'])) { $firstItem = $indexBody['data'][0]; $testSiteID = $firstItem['TestSiteID'] ?? null; if ($testSiteID) { $updateData = [ 'TestSiteName' => 'Updated Test Name ' . time(), 'Description' => 'Updated description' ]; $result = $this->put($this->endpoint . '/' . $testSiteID, ['body' => json_encode($updateData)]); $status = $result->response()->getStatusCode(); $this->assertTrue( in_array($status, [200, 404, 500]), "Expected 200, 404, or 500, got $status" ); if ($status === 200) { $body = json_decode($result->response()->getBody(), true); $this->assertEquals('success', $body['status']); } } } } /** * Test soft delete (disable) test */ public function testDeleteTest(): void { // Create a test first to delete $testData = $this->createTestData(); $testData['TestSiteCode'] = 'DEL' . substr(time(), -4); $createResult = $this->post($this->endpoint, ['body' => json_encode($testData)]); $createStatus = $createResult->response()->getStatusCode(); if ($createStatus === 201) { $createBody = json_decode($createResult->response()->getBody(), true); $testSiteID = $createBody['data']['TestSiteId'] ?? null; if ($testSiteID) { $deleteResult = $this->delete($this->endpoint . '/' . $testSiteID); $deleteStatus = $deleteResult->response()->getStatusCode(); $this->assertTrue( in_array($deleteStatus, [200, 404, 500]), "Expected 200, 404, or 500, got $deleteStatus" ); if ($deleteStatus === 200) { $deleteBody = json_decode($deleteResult->response()->getBody(), true); $this->assertEquals('success', $deleteBody['status']); $this->assertArrayHasKey('EndDate', $deleteBody['data']); } } } } /** * Test validation - missing required fields */ public function testCreateValidationRequiredFields(): void { $invalidData = [ 'TestSiteName' => 'Test without required fields' ]; $result = $this->post($this->endpoint, ['body' => json_encode($invalidData)]); $result->assertStatus(400); } /** * Test that TestSiteCode is max 6 characters */ public function testTestSiteCodeLength(): void { $invalidData = [ 'SiteID' => 1, 'TestSiteCode' => 'HB123456', // 8 characters - invalid 'TestSiteName' => 'Test with too long code', 'TestType' => $this::TEST_TYPE_TEST ]; $result = $this->post($this->endpoint, ['body' => json_encode($invalidData)]); $result->assertStatus(400); } /** * Test that TestSiteCode is at least 3 characters */ public function testTestSiteCodeMinLength(): void { $invalidData = [ 'SiteID' => 1, 'TestSiteCode' => 'HB', // 2 characters - invalid 'TestSiteName' => 'Test with too short code', 'TestType' => $this::TEST_TYPE_TEST ]; $result = $this->post($this->endpoint, ['body' => json_encode($invalidData)]); $result->assertStatus(400); } /** * Test that duplicate TestSiteCode is rejected */ public function testDuplicateTestSiteCode(): void { // First create a test $testData = $this->createTestData(); $testData['TestSiteCode'] = 'DUP' . substr(time(), -3); $this->post($this->endpoint, ['body' => json_encode($testData)]); // Try to create another test with the same code $duplicateData = $testData; $duplicateData['TestSiteName'] = 'Different Name'; $result = $this->post($this->endpoint, ['body' => json_encode($duplicateData)]); // Should fail with 400 or 500 $status = $result->response()->getStatusCode(); $this->assertTrue( in_array($status, [400, 500]), "Expected 400 or 500 for duplicate, got $status" ); } /** * Test filtering by multiple parameters */ public function testIndexWithMultipleFilters(): void { $result = $this->get($this->endpoint . '?SiteID=1&TestType=TEST&VisibleScr=1'); $result->assertStatus(200); $body = json_decode($result->response()->getBody(), true); $this->assertEquals('success', $body['status']); } /** * Helper method to get existing test IDs for group members */ private function getExistingTestIds(): array { $indexResult = $this->get($this->endpoint); $indexBody = json_decode($indexResult->response()->getBody(), true); $ids = []; if (isset($indexBody['data']) && is_array($indexBody['data'])) { foreach ($indexBody['data'] as $item) { if (isset($item['TestSiteID'])) { $ids[] = $item['TestSiteID']; } if (count($ids) >= 2) { break; } } } return $ids ?: [1, 2]; } }