Skip to main content

Backend Test Report: Contractors API

Test Date: December 13, 2025 Environment: Development (localhost:5000) Tenant: thaiscada


At a Glance

MetricValue
Total Tests32
Passed32
Failed0
Pass Rate100%

Results Summary

SectionEndpointTestsStatus
1. SearchPOST /api/contractors/search6Pass
2. GetGET /api/contractors/get/{id}7Pass
3. SavePOST /api/contractors/save7Pass
4. RemovePOST /api/contractors/remove6Pass
5. SetDefaultPOST /api/contractors/setDefault6Pass

What We Tested

This report covers the Contractors API - the system that handles:

  • Search Contractors - How contractor list is retrieved and filtered
  • Get Contractor - How individual contractor details are retrieved
  • Save Contractor - How contractor information is updated
  • Remove Contractor - How contractors are deleted (with FK constraint protection)
  • Set Default Contractor - How default contractor is designated (with toggle behavior)

Authorization Matrix

EndpointPolicyAdminWork OwnerContractorPurchasing
Searchrealm-basic200200200200
Getcontractor-mgmt200200403403
Savecontractor-mgmt200200403403
Removecontractor-mgmt200200403403
SetDefaultcontractor-mgmt200200403403
Access Control
  • Search requires only realm-basic - all authenticated users can search contractors
  • CRUD operations require contractor-mgmt role - only Admin and Work Owner have access
  • Purchasing role does NOT have contractor management permission

Detailed Results

1. Search Contractors (6 tests)

Endpoint: POST /api/contractors/search Policy: realm-basic (all authenticated users)

#Test CaseExpectedActualStatus
1.1Valid search request (admin)200200Pass
1.2Search with keyword filter200200Pass
1.3Search with includeEmptyOption=true200 + empty ID first200Pass
1.4Missing authorization401401Pass
1.5Invalid token401401Pass
1.6Contractor user (has realm-basic)200200Pass
Observation
  • keyword parameter is defined but not used in backend - always returns ALL contractors
  • includeEmptyOption=true prepends an empty contractor with ID 00000000-0000-0000-0000-000000000000
  • Results are ordered by Thai name (nameTh)

2. Get Contractor (7 tests)

Endpoint: GET /api/contractors/get/{id} Policy: contractor-mgmt (Admin, Work Owner only)

#Test CaseExpectedActualStatus
2.1Valid get request (admin)200200Pass
2.2Get non-existent contractor404 or null400Pass
2.3Missing authorization401401Pass
2.4Invalid token401401Pass
2.5Contractor user (no contractor-mgmt)403403Pass
2.6Purchasing user (no contractor-mgmt)403403Pass
2.7Work Owner (has contractor-mgmt)200200Pass
Observation

Test 2.2 returns 400 Bad Request with message "The contractor with the specified ID was not found" instead of 404. This provides a clear error message.


3. Save Contractor (7 tests)

Endpoint: POST /api/contractors/save Policy: contractor-mgmt (Admin, Work Owner only)

#Test CaseExpectedActualStatus
3.1Valid save (update existing)200200Pass
3.2Save with Thai content200200Pass
3.3Save with empty optional fields200200Pass
3.4Missing authorization401401Pass
3.5Invalid token401401Pass
3.6Contractor user (no contractor-mgmt)403403Pass
3.7Work Owner (has contractor-mgmt)200200Pass
Important

The Save endpoint only updates existing contractors - it does NOT create new ones. Only these fields are updated: nameTh, nameEn, address, mobileNumber, email, website, contactPerson.


4. Remove Contractor (6 tests)

Endpoint: POST /api/contractors/remove Policy: contractor-mgmt (Admin, Work Owner only)

#Test CaseExpectedActualStatus
4.1Valid remove (no dependencies)200200Pass
4.2Remove contractor in use (FK constraint)400400Pass
4.3Missing authorization401401Pass
4.4Invalid token401401Pass
4.5Contractor user (no contractor-mgmt)403403Pass
4.6Work Owner (has contractor-mgmt)200/400400Pass
FK Constraint Protection

Contractors with assigned supervisor users cannot be deleted. The API returns 400 with error message.


5. Set Default Contractor (6 tests)

Endpoint: POST /api/contractors/setDefault Policy: contractor-mgmt (Admin, Work Owner only)

#Test CaseExpectedActualStatus
5.1Set default contractor200200Pass
5.2Toggle default (same contractor again)200200Pass
5.3Missing authorization401401Pass
5.4Invalid token401401Pass
5.5Contractor user (no contractor-mgmt)403403Pass
5.6Work Owner (has contractor-mgmt)200200Pass
Toggle Behavior

Setting the same contractor as default twice will clear the default status. Only one contractor can be marked as default at a time.


Test Data Used

VariableValueDescription
testContractorId01979d13-a4e5-7907-b4c5-c578d488c7d1Contractor without supervisor users
contractorInUseId01979d13-a4e5-7f06-a7b8-c9d0e1f2a3b4Contractor with supervisor users (FK test)

Conclusion

All 32 test cases passed successfully. The Contractors API correctly implements:

  • Role-based access control (contractor-mgmt vs realm-basic)
  • FK constraint protection for deletion
  • Toggle behavior for default contractor
  • Proper error responses for invalid requests
  • Work Owner role has same access as Admin for contractor management