feat: implement test mapping functionality with TestMapController and model

- Add TestMapController for managing test-to-analyzer mappings
- Create TestMapModel with database operations for test mappings
- Update TestsController to support test mapping operations
- Add testmap API routes to Routes.php
- Create migration updates for test definitions table
- Add OpenAPI specification for test mapping endpoints
- Include unit tests for TestDef models
- Update bundled API documentation
This commit is contained in:
mahdahar 2026-02-23 16:49:39 +07:00
parent 98008d3172
commit 707d548db0
9 changed files with 722 additions and 29 deletions

View File

@ -259,6 +259,22 @@ $routes->group('api', function ($routes) {
$routes->patch('/', 'TestsController::update');
});
// Test Mapping
$routes->group('test', function ($routes) {
$routes->group('testmap', function ($routes) {
$routes->get('/', 'Test\TestMapController::index');
$routes->get('(:num)', 'Test\TestMapController::show/$1');
$routes->post('/', 'Test\TestMapController::create');
$routes->patch('/', 'Test\TestMapController::update');
$routes->delete('/', 'Test\TestMapController::delete');
// Filter routes
$routes->get('by-testsite/(:num)', 'Test\TestMapController::showByTestSite/$1');
$routes->get('by-host/(:any)/(:any)', 'Test\TestMapController::showByHost/$1/$2');
$routes->get('by-client/(:any)/(:any)', 'Test\TestMapController::showByClient/$1/$2');
});
});
// Orders
$routes->group('ordertest', function ($routes) {
$routes->get('/', 'OrderTestController::index');

View File

@ -66,4 +66,62 @@ class TestMapController extends BaseController {
}
}
public function delete() {
$input = $this->request->getJSON(true);
$id = $input["TestMapID"] ?? null;
if (!$id) { return $this->failValidationErrors('TestMapID is required.'); }
try {
$row = $this->model->where('TestMapID', $id)->where('EndDate IS NULL')->first();
if (empty($row)) { return $this->respond([ 'status' => 'failed', 'message' => "Data not found or already deleted.", 'data' => null ], 404); }
$this->model->update($id, ['EndDate' => date('Y-m-d H:i:s')]);
return $this->respond([ 'status' => 'success', 'message' => "data deleted successfully", 'data' => $id ], 200);
} catch (\Exception $e) {
return $this->failServerError('Something went wrong: ' . $e->getMessage());
}
}
public function showByTestSite($testSiteID = null) {
if (!$testSiteID) { return $this->failValidationErrors('TestSiteID is required.'); }
$rows = $this->model->getMappingsByTestSite($testSiteID);
if (empty($rows)) { return $this->respond([ 'status' => 'success', 'message' => "no Data.", 'data' => [] ], 200); }
$rows = ValueSet::transformLabels($rows, [
'HostType' => 'entity_type',
'ClientType' => 'entity_type',
]);
return $this->respond([ 'status' => 'success', 'message'=> "Data fetched successfully", 'data' => $rows ], 200);
}
public function showByHost($hostType = null, $hostID = null) {
if (!$hostType || !$hostID) { return $this->failValidationErrors('HostType and HostID are required.'); }
$rows = $this->model->getMappingsByHost($hostType, $hostID);
if (empty($rows)) { return $this->respond([ 'status' => 'success', 'message' => "no Data.", 'data' => [] ], 200); }
$rows = ValueSet::transformLabels($rows, [
'HostType' => 'entity_type',
'ClientType' => 'entity_type',
]);
return $this->respond([ 'status' => 'success', 'message'=> "Data fetched successfully", 'data' => $rows ], 200);
}
public function showByClient($clientType = null, $clientID = null) {
if (!$clientType || !$clientID) { return $this->failValidationErrors('ClientType and ClientID are required.'); }
$rows = $this->model->getMappingsByClient($clientType, $clientID);
if (empty($rows)) { return $this->respond([ 'status' => 'success', 'message' => "no Data.", 'data' => [] ], 200); }
$rows = ValueSet::transformLabels($rows, [
'HostType' => 'entity_type',
'ClientType' => 'entity_type',
]);
return $this->respond([ 'status' => 'success', 'message'=> "Data fetched successfully", 'data' => $rows ], 200);
}
}

View File

@ -649,12 +649,10 @@ class TestsController extends BaseController
'TestSiteID' => $testSiteID,
'HostType' => $map['HostType'] ?? null,
'HostID' => $map['HostID'] ?? null,
'HostDataSource' => $map['HostDataSource'] ?? null,
'HostTestCode' => $map['HostTestCode'] ?? null,
'HostTestName' => $map['HostTestName'] ?? null,
'ClientType' => $map['ClientType'] ?? null,
'ClientID' => $map['ClientID'] ?? null,
'ClientDataSource' => $map['ClientDataSource'] ?? null,
'ConDefID' => $map['ConDefID'] ?? null,
'ClientTestCode' => $map['ClientTestCode'] ?? null,
'ClientTestName' => $map['ClientTestName'] ?? null

View File

@ -82,12 +82,10 @@ class CreateTestDefinitions extends Migration {
'TestSiteID' => ['type' => 'INT', 'unsigned' => true, 'null' => false],
'HostType' => ['type' => 'varchar', 'constraint'=> 20, 'null' => true],
'HostID' => ['type' => 'varchar', 'constraint'=> 50, 'null' => true],
'HostDataSource' => ['type' => 'varchar', 'constraint'=> 50, 'null' => true],
'HostTestCode' => ['type' => 'varchar', 'constraint'=> 10, 'null' => true],
'HostTestName' => ['type' => 'varchar', 'constraint'=> 100, 'null' => true],
'ClientType' => ['type' => 'varchar', 'constraint'=> 20, 'null' => true],
'ClientID' => ['type' => 'varchar', 'constraint'=> 50, 'null' => true],
'ClientDataSource' => ['type' => 'varchar', 'constraint'=> 50, 'null' => true],
'ConDefID' => ['type' => 'INT', 'null' => true],
'ClientTestCode' => ['type' => 'varchar', 'constraint'=> 10, 'null' => true],
'ClientTestName' => ['type' => 'varchar', 'constraint'=> 100, 'null' => true],

View File

@ -9,20 +9,18 @@ class TestMapModel extends BaseModel {
protected $primaryKey = 'TestMapID';
protected $allowedFields = [
'TestSiteID',
'HostType',
'HostID',
'HostDataSource',
'HostTestCode',
'HostType',
'HostID',
'HostTestCode',
'HostTestName',
'ClientType',
'ClientID',
'ClientDataSource',
'ClientType',
'ClientID',
'ConDefID',
'ClientTestCode',
'ClientTestName',
'CreateDate',
'ClientTestCode',
'ClientTestName',
'CreateDate',
'EndDate'
];
];
protected $useTimestamps = true;
protected $createdField = 'CreateDate';

View File

@ -2556,6 +2556,326 @@ paths:
responses:
'200':
description: Collection method details
/api/test/testmap:
get:
tags:
- Tests
summary: List all test mappings
security:
- bearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
default: 1
description: Page number for pagination
- name: perPage
in: query
schema:
type: integer
default: 20
description: Number of items per page
responses:
'200':
description: List of test mappings
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: array
items:
$ref: '#/components/schemas/TestMap'
post:
tags:
- Tests
summary: Create test mapping
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
TestSiteID:
type: integer
description: Test Site ID (required)
HostType:
type: string
description: Host type code
HostID:
type: string
description: Host identifier
HostTestCode:
type: string
description: Test code in host system
HostTestName:
type: string
description: Test name in host system
ClientType:
type: string
description: Client type code
ClientID:
type: string
description: Client identifier
ConDefID:
type: integer
description: Connection definition ID
ClientTestCode:
type: string
description: Test code in client system
ClientTestName:
type: string
description: Test name in client system
required:
- TestSiteID
responses:
'201':
description: Test mapping created
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: integer
description: Created TestMapID
patch:
tags:
- Tests
summary: Update test mapping
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
TestMapID:
type: integer
description: Test Map ID (required)
TestSiteID:
type: integer
HostType:
type: string
HostID:
type: string
HostTestCode:
type: string
HostTestName:
type: string
ClientType:
type: string
ClientID:
type: string
ConDefID:
type: integer
ClientTestCode:
type: string
ClientTestName:
type: string
required:
- TestMapID
responses:
'200':
description: Test mapping updated
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: integer
description: Updated TestMapID
delete:
tags:
- Tests
summary: Soft delete test mapping
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
TestMapID:
type: integer
description: Test Map ID to delete (required)
required:
- TestMapID
responses:
'200':
description: Test mapping deleted successfully
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: integer
description: Deleted TestMapID
'404':
description: Test mapping not found or already deleted
/api/test/testmap/{id}:
get:
tags:
- Tests
summary: Get test mapping by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
description: Test Map ID
responses:
'200':
description: Test mapping details
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
$ref: '#/components/schemas/TestMap'
'404':
description: Test mapping not found
/api/test/testmap/by-testsite/{testSiteID}:
get:
tags:
- Tests
summary: Get test mappings by test site
security:
- bearerAuth: []
parameters:
- name: testSiteID
in: path
required: true
schema:
type: integer
description: Test Site ID
responses:
'200':
description: List of test mappings for the test site
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: array
items:
$ref: '#/components/schemas/TestMap'
/api/test/testmap/by-host/{hostType}/{hostID}:
get:
tags:
- Tests
summary: Get test mappings by host
security:
- bearerAuth: []
parameters:
- name: hostType
in: path
required: true
schema:
type: string
description: Host type code
- name: hostID
in: path
required: true
schema:
type: string
description: Host identifier
responses:
'200':
description: List of test mappings for the host
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: array
items:
$ref: '#/components/schemas/TestMap'
/api/test/testmap/by-client/{clientType}/{clientID}:
get:
tags:
- Tests
summary: Get test mappings by client
security:
- bearerAuth: []
parameters:
- name: clientType
in: path
required: true
schema:
type: string
description: Client type code
- name: clientID
in: path
required: true
schema:
type: string
description: Client identifier
responses:
'200':
description: List of test mappings for the client
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: array
items:
$ref: '#/components/schemas/TestMap'
/api/tests:
get:
tags:
@ -4567,9 +4887,6 @@ components:
HostID:
type: string
description: Host identifier
HostDataSource:
type: string
description: Host data source
HostTestCode:
type: string
description: Test code in host system
@ -4582,9 +4899,6 @@ components:
ClientID:
type: string
description: Client identifier
ClientDataSource:
type: string
description: Client data source
ConDefID:
type: integer
description: Connection definition ID

View File

@ -434,9 +434,6 @@ TestMap:
HostID:
type: string
description: Host identifier
HostDataSource:
type: string
description: Host data source
HostTestCode:
type: string
description: Test code in host system
@ -449,9 +446,6 @@ TestMap:
ClientID:
type: string
description: Client identifier
ClientDataSource:
type: string
description: Client data source
ConDefID:
type: integer
description: Connection definition ID

319
public/paths/testmap.yaml Normal file
View File

@ -0,0 +1,319 @@
/api/test/testmap:
get:
tags: [Tests]
summary: List all test mappings
security:
- bearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
default: 1
description: Page number for pagination
- name: perPage
in: query
schema:
type: integer
default: 20
description: Number of items per page
responses:
'200':
description: List of test mappings
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: array
items:
$ref: '../components/schemas/tests.yaml#/TestMap'
post:
tags: [Tests]
summary: Create test mapping
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
TestSiteID:
type: integer
description: Test Site ID (required)
HostType:
type: string
description: Host type code
HostID:
type: string
description: Host identifier
HostTestCode:
type: string
description: Test code in host system
HostTestName:
type: string
description: Test name in host system
ClientType:
type: string
description: Client type code
ClientID:
type: string
description: Client identifier
ConDefID:
type: integer
description: Connection definition ID
ClientTestCode:
type: string
description: Test code in client system
ClientTestName:
type: string
description: Test name in client system
required:
- TestSiteID
responses:
'201':
description: Test mapping created
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: integer
description: Created TestMapID
patch:
tags: [Tests]
summary: Update test mapping
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
TestMapID:
type: integer
description: Test Map ID (required)
TestSiteID:
type: integer
HostType:
type: string
HostID:
type: string
HostTestCode:
type: string
HostTestName:
type: string
ClientType:
type: string
ClientID:
type: string
ConDefID:
type: integer
ClientTestCode:
type: string
ClientTestName:
type: string
required:
- TestMapID
responses:
'200':
description: Test mapping updated
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: integer
description: Updated TestMapID
delete:
tags: [Tests]
summary: Soft delete test mapping
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
TestMapID:
type: integer
description: Test Map ID to delete (required)
required:
- TestMapID
responses:
'200':
description: Test mapping deleted successfully
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: integer
description: Deleted TestMapID
'404':
description: Test mapping not found or already deleted
/api/test/testmap/{id}:
get:
tags: [Tests]
summary: Get test mapping by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
description: Test Map ID
responses:
'200':
description: Test mapping details
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
$ref: '../components/schemas/tests.yaml#/TestMap'
'404':
description: Test mapping not found
/api/test/testmap/by-testsite/{testSiteID}:
get:
tags: [Tests]
summary: Get test mappings by test site
security:
- bearerAuth: []
parameters:
- name: testSiteID
in: path
required: true
schema:
type: integer
description: Test Site ID
responses:
'200':
description: List of test mappings for the test site
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: array
items:
$ref: '../components/schemas/tests.yaml#/TestMap'
/api/test/testmap/by-host/{hostType}/{hostID}:
get:
tags: [Tests]
summary: Get test mappings by host
security:
- bearerAuth: []
parameters:
- name: hostType
in: path
required: true
schema:
type: string
description: Host type code
- name: hostID
in: path
required: true
schema:
type: string
description: Host identifier
responses:
'200':
description: List of test mappings for the host
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: array
items:
$ref: '../components/schemas/tests.yaml#/TestMap'
/api/test/testmap/by-client/{clientType}/{clientID}:
get:
tags: [Tests]
summary: Get test mappings by client
security:
- bearerAuth: []
parameters:
- name: clientType
in: path
required: true
schema:
type: string
description: Client type code
- name: clientID
in: path
required: true
schema:
type: string
description: Client identifier
responses:
'200':
description: List of test mappings for the client
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: array
items:
$ref: '../components/schemas/tests.yaml#/TestMap'

View File

@ -167,12 +167,10 @@ class TestDefModelsTest extends CIUnitTestCase
$this->assertContains('TestSiteID', $allowedFields);
$this->assertContains('HostType', $allowedFields);
$this->assertContains('HostID', $allowedFields);
$this->assertContains('HostDataSource', $allowedFields);
$this->assertContains('HostTestCode', $allowedFields);
$this->assertContains('HostTestName', $allowedFields);
$this->assertContains('ClientType', $allowedFields);
$this->assertContains('ClientID', $allowedFields);
$this->assertContains('ClientDataSource', $allowedFields);
$this->assertContains('ConDefID', $allowedFields);
$this->assertContains('ClientTestCode', $allowedFields);
$this->assertContains('ClientTestName', $allowedFields);