mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-01 04:21:58 +00:00
fix(delete): run delete hooks and queries in one transaction
- resolvespec/restheadspec: single and batch delete use one transaction - add sqlmock tests for delete transaction behaviour - testmodels: serial integer ids; update tests accordingly - add compose testserver, smoke script, podman-first Makefile targets
This commit is contained in:
+54
-42
@@ -168,15 +168,14 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
|
||||
// Generate unique IDs for this test run
|
||||
timestamp := time.Now().Unix()
|
||||
deptID := fmt.Sprintf("dept_rs_%d", timestamp)
|
||||
empID := fmt.Sprintf("emp_rs_%d", timestamp)
|
||||
// IDs are assigned by the database (serial) and captured on create
|
||||
var deptID, empID int64
|
||||
|
||||
// Test CREATE operation
|
||||
t.Run("Create_Department", func(t *testing.T) {
|
||||
payload := map[string]interface{}{
|
||||
"operation": "create",
|
||||
"data": map[string]interface{}{
|
||||
"id": deptID,
|
||||
"name": "Engineering Department",
|
||||
"code": fmt.Sprintf("ENG_%d", timestamp),
|
||||
"description": "Software Engineering",
|
||||
@@ -188,15 +187,15 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
deptID = createdID(result)
|
||||
assert.True(t, result["success"].(bool), "Create department should succeed")
|
||||
logger.Info("Department created successfully: %s", deptID)
|
||||
logger.Info("Department created successfully: %d", deptID)
|
||||
})
|
||||
|
||||
t.Run("Create_Employee", func(t *testing.T) {
|
||||
payload := map[string]interface{}{
|
||||
"operation": "create",
|
||||
"data": map[string]interface{}{
|
||||
"id": empID,
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"email": fmt.Sprintf("john.doe.rs.%d@example.com", timestamp),
|
||||
@@ -212,8 +211,9 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
empID = createdID(result)
|
||||
assert.True(t, result["success"].(bool), "Create employee should succeed")
|
||||
logger.Info("Employee created successfully: %s", empID)
|
||||
logger.Info("Employee created successfully: %d", empID)
|
||||
})
|
||||
|
||||
// Test READ operation
|
||||
@@ -222,7 +222,7 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
"operation": "read",
|
||||
}
|
||||
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/departments/%s", deptID), payload)
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/departments/%d", deptID), payload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
@@ -230,9 +230,9 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
assert.True(t, result["success"].(bool), "Read department should succeed")
|
||||
|
||||
data := result["data"].(map[string]interface{})
|
||||
assert.Equal(t, deptID, data["id"])
|
||||
assert.EqualValues(t, deptID, data["id"])
|
||||
assert.Equal(t, "Engineering Department", data["name"])
|
||||
logger.Info("Department read successfully: %s", deptID)
|
||||
logger.Info("Department read successfully: %d", deptID)
|
||||
})
|
||||
|
||||
t.Run("Read_Employees_With_Filters", func(t *testing.T) {
|
||||
@@ -270,17 +270,17 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
},
|
||||
}
|
||||
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/departments/%s", deptID), payload)
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/departments/%d", deptID), payload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
assert.True(t, result["success"].(bool), "Update department should succeed")
|
||||
logger.Info("Department updated successfully: %s", deptID)
|
||||
logger.Info("Department updated successfully: %d", deptID)
|
||||
|
||||
// Verify update
|
||||
readPayload := map[string]interface{}{"operation": "read"}
|
||||
resp = makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/departments/%s", deptID), readPayload)
|
||||
resp = makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/departments/%d", deptID), readPayload)
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
data := result["data"].(map[string]interface{})
|
||||
assert.Equal(t, "Updated Software Engineering Department", data["description"])
|
||||
@@ -294,13 +294,13 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
},
|
||||
}
|
||||
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/employees/%s", empID), payload)
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/employees/%d", empID), payload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
assert.True(t, result["success"].(bool), "Update employee should succeed")
|
||||
logger.Info("Employee updated successfully: %s", empID)
|
||||
logger.Info("Employee updated successfully: %d", empID)
|
||||
})
|
||||
|
||||
// Test DELETE operation
|
||||
@@ -309,17 +309,17 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
"operation": "delete",
|
||||
}
|
||||
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/employees/%s", empID), payload)
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/employees/%d", empID), payload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
assert.True(t, result["success"].(bool), "Delete employee should succeed")
|
||||
logger.Info("Employee deleted successfully: %s", empID)
|
||||
logger.Info("Employee deleted successfully: %d", empID)
|
||||
|
||||
// Verify deletion - after delete, reading should return empty/zero-value record or error
|
||||
readPayload := map[string]interface{}{"operation": "read"}
|
||||
resp = makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/employees/%s", empID), readPayload)
|
||||
resp = makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/employees/%d", empID), readPayload)
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
// After deletion, the record should either not exist or have empty/zero ID
|
||||
if result["success"] != nil && result["success"].(bool) {
|
||||
@@ -337,13 +337,13 @@ func testResolveSpecCRUD(t *testing.T, serverURL string) {
|
||||
"operation": "delete",
|
||||
}
|
||||
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/departments/%s", deptID), payload)
|
||||
resp := makeResolveSpecRequest(t, serverURL, fmt.Sprintf("/resolvespec/departments/%d", deptID), payload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
assert.True(t, result["success"].(bool), "Delete department should succeed")
|
||||
logger.Info("Department deleted successfully: %s", deptID)
|
||||
logger.Info("Department deleted successfully: %d", deptID)
|
||||
})
|
||||
|
||||
logger.Info("ResolveSpec API CRUD tests completed")
|
||||
@@ -355,13 +355,12 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
|
||||
// Generate unique IDs for this test run
|
||||
timestamp := time.Now().Unix()
|
||||
deptID := fmt.Sprintf("dept_rhs_%d", timestamp)
|
||||
empID := fmt.Sprintf("emp_rhs_%d", timestamp)
|
||||
// IDs are assigned by the database (serial) and captured on create
|
||||
var deptID, empID int64
|
||||
|
||||
// Test CREATE operation (POST)
|
||||
t.Run("Create_Department", func(t *testing.T) {
|
||||
data := map[string]interface{}{
|
||||
"id": deptID,
|
||||
"name": "Marketing Department",
|
||||
"code": fmt.Sprintf("MKT_%d", timestamp),
|
||||
"description": "Marketing and Communications",
|
||||
@@ -372,20 +371,20 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
deptID = createdID(result)
|
||||
// Check if response has "success" field (wrapped format) or direct data (unwrapped format)
|
||||
if success, ok := result["success"]; ok && success != nil {
|
||||
assert.True(t, success.(bool), "Create department should succeed")
|
||||
} else {
|
||||
// Unwrapped format - verify we got the created data back
|
||||
assert.NotEmpty(t, result, "Create department should return data")
|
||||
assert.Equal(t, deptID, result["id"], "Created department should have correct ID")
|
||||
assert.EqualValues(t, deptID, result["id"], "Created department should have correct ID")
|
||||
}
|
||||
logger.Info("Department created successfully: %s", deptID)
|
||||
logger.Info("Department created successfully: %d", deptID)
|
||||
})
|
||||
|
||||
t.Run("Create_Employee", func(t *testing.T) {
|
||||
data := map[string]interface{}{
|
||||
"id": empID,
|
||||
"first_name": "Jane",
|
||||
"last_name": "Smith",
|
||||
"email": fmt.Sprintf("jane.smith.rhs.%d@example.com", timestamp),
|
||||
@@ -400,20 +399,21 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
empID = createdID(result)
|
||||
// Check if response has "success" field (wrapped format) or direct data (unwrapped format)
|
||||
if success, ok := result["success"]; ok && success != nil {
|
||||
assert.True(t, success.(bool), "Create employee should succeed")
|
||||
} else {
|
||||
// Unwrapped format - verify we got the created data back
|
||||
assert.NotEmpty(t, result, "Create employee should return data")
|
||||
assert.Equal(t, empID, result["id"], "Created employee should have correct ID")
|
||||
assert.EqualValues(t, empID, result["id"], "Created employee should have correct ID")
|
||||
}
|
||||
logger.Info("Employee created successfully: %s", empID)
|
||||
logger.Info("Employee created successfully: %d", empID)
|
||||
})
|
||||
|
||||
// Test READ operation (GET)
|
||||
t.Run("Read_Department", func(t *testing.T) {
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/departments/%s", deptID), "GET", nil, nil)
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/departments/%d", deptID), "GET", nil, nil)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
// RestHeadSpec may return data directly as array/object or wrapped in response object
|
||||
@@ -424,7 +424,7 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
var dataArray []interface{}
|
||||
if err := json.Unmarshal(body, &dataArray); err == nil {
|
||||
assert.GreaterOrEqual(t, len(dataArray), 1, "Should find department")
|
||||
logger.Info("Department read successfully (simple format - array): %s", deptID)
|
||||
logger.Info("Department read successfully (simple format - array): %d", deptID)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
if _, hasSuccess := singleObj["success"]; !hasSuccess {
|
||||
// This is a direct data object (simple format, single record)
|
||||
assert.NotEmpty(t, singleObj, "Should find department")
|
||||
logger.Info("Department read successfully (simple format - single object): %s", deptID)
|
||||
logger.Info("Department read successfully (simple format - single object): %d", deptID)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -444,13 +444,13 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
// Check if data is an array
|
||||
if data, ok := singleObj["data"].([]interface{}); ok {
|
||||
assert.GreaterOrEqual(t, len(data), 1, "Should find department")
|
||||
logger.Info("Department read successfully (detail format - array): %s", deptID)
|
||||
logger.Info("Department read successfully (detail format - array): %d", deptID)
|
||||
return
|
||||
}
|
||||
// Check if data is a single object (SingleRecordAsObject feature in detail format)
|
||||
if data, ok := singleObj["data"].(map[string]interface{}); ok {
|
||||
assert.NotEmpty(t, data, "Should find department")
|
||||
logger.Info("Department read successfully (detail format - single object): %s", deptID)
|
||||
logger.Info("Department read successfully (detail format - single object): %d", deptID)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -549,7 +549,7 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
"description": "Updated Marketing and Sales Department",
|
||||
}
|
||||
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/departments/%s", deptID), "PUT", data, nil)
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/departments/%d", deptID), "PUT", data, nil)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
@@ -561,11 +561,11 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
// Unwrapped format - verify we got the updated data back
|
||||
assert.NotEmpty(t, result, "Update department should return data")
|
||||
}
|
||||
logger.Info("Department updated successfully: %s", deptID)
|
||||
logger.Info("Department updated successfully: %d", deptID)
|
||||
|
||||
// Verify update by reading the department again
|
||||
// For simplicity, just verify the update succeeded, skip verification read
|
||||
logger.Info("Department update verified: %s", deptID)
|
||||
logger.Info("Department update verified: %d", deptID)
|
||||
})
|
||||
|
||||
t.Run("Update_Employee_With_PATCH", func(t *testing.T) {
|
||||
@@ -573,7 +573,7 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
"title": "Senior Marketing Manager",
|
||||
}
|
||||
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/employees/%s", empID), "PATCH", data, nil)
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/employees/%d", empID), "PATCH", data, nil)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
@@ -585,12 +585,12 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
// Unwrapped format - verify we got the updated data back
|
||||
assert.NotEmpty(t, result, "Update employee should return data")
|
||||
}
|
||||
logger.Info("Employee updated successfully: %s", empID)
|
||||
logger.Info("Employee updated successfully: %d", empID)
|
||||
})
|
||||
|
||||
// Test DELETE operation (DELETE)
|
||||
t.Run("Delete_Employee", func(t *testing.T) {
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/employees/%s", empID), "DELETE", nil, nil)
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/employees/%d", empID), "DELETE", nil, nil)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
@@ -602,14 +602,14 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
// Unwrapped format - verify we got a response (typically {"deleted": count})
|
||||
assert.NotEmpty(t, result, "Delete employee should return data")
|
||||
}
|
||||
logger.Info("Employee deleted successfully: %s", empID)
|
||||
logger.Info("Employee deleted successfully: %d", empID)
|
||||
|
||||
// Verify deletion - just log that delete succeeded
|
||||
logger.Info("Employee deletion verified: %s", empID)
|
||||
logger.Info("Employee deletion verified: %d", empID)
|
||||
})
|
||||
|
||||
t.Run("Delete_Department", func(t *testing.T) {
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/departments/%s", deptID), "DELETE", nil, nil)
|
||||
resp := makeRestHeadSpecRequest(t, serverURL, fmt.Sprintf("/restheadspec/departments/%d", deptID), "DELETE", nil, nil)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
@@ -621,7 +621,7 @@ func testRestHeadSpecCRUD(t *testing.T, serverURL string) {
|
||||
// Unwrapped format - verify we got a response (typically {"deleted": count})
|
||||
assert.NotEmpty(t, result, "Delete department should return data")
|
||||
}
|
||||
logger.Info("Department deleted successfully: %s", deptID)
|
||||
logger.Info("Department deleted successfully: %d", deptID)
|
||||
})
|
||||
|
||||
logger.Info("RestHeadSpec API CRUD tests completed")
|
||||
@@ -687,3 +687,15 @@ func makeRestHeadSpecRequest(t *testing.T, serverURL, path, method string, data
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// createdID extracts the database-assigned id from a create response, in either the
|
||||
// wrapped ({"data": {...}}) or unwrapped format.
|
||||
func createdID(result map[string]interface{}) int64 {
|
||||
if data, ok := result["data"].(map[string]interface{}); ok {
|
||||
result = data
|
||||
}
|
||||
if id, ok := result["id"].(float64); ok {
|
||||
return int64(id)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
+48
-23
@@ -2,6 +2,7 @@ package test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -9,6 +10,32 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Database-assigned (serial) ids, captured on create; later tests build on earlier ones.
|
||||
var deptID, emp1ID, emp2ID, mgrID, projID, task1ID int64
|
||||
|
||||
// createdIDs returns the ids of the records in a create response (single object or array).
|
||||
func createdIDs(resp *http.Response) []int64 {
|
||||
var result struct {
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
_ = json.NewDecoder(resp.Body).Decode(&result)
|
||||
items, ok := result.Data.([]interface{})
|
||||
if !ok {
|
||||
items = []interface{}{result.Data}
|
||||
}
|
||||
ids := make([]int64, 0, len(items))
|
||||
for _, item := range items {
|
||||
if m, ok := item.(map[string]interface{}); ok {
|
||||
if id, ok := m["id"].(float64); ok {
|
||||
ids = append(ids, int64(id))
|
||||
continue
|
||||
}
|
||||
}
|
||||
ids = append(ids, 0)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// TestMain sets up the test environment
|
||||
func TestMain(m *testing.M) {
|
||||
TestSetup(m)
|
||||
@@ -19,7 +46,6 @@ func TestDepartmentEmployees(t *testing.T) {
|
||||
deptPayload := map[string]interface{}{
|
||||
"operation": "create",
|
||||
"data": map[string]interface{}{
|
||||
"id": "dept1",
|
||||
"name": "Engineering",
|
||||
"code": "ENG",
|
||||
"description": "Engineering Department",
|
||||
@@ -28,25 +54,24 @@ func TestDepartmentEmployees(t *testing.T) {
|
||||
|
||||
resp := makeRequest(t, "/departments", deptPayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
deptID = createdIDs(resp)[0]
|
||||
|
||||
// Create employees in department
|
||||
empPayload := map[string]interface{}{
|
||||
"operation": "create",
|
||||
"data": []map[string]interface{}{
|
||||
{
|
||||
"id": "emp1",
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"email": "john@example.com",
|
||||
"department_id": "dept1",
|
||||
"department_id": deptID,
|
||||
"title": "Senior Engineer",
|
||||
},
|
||||
{
|
||||
"id": "emp2",
|
||||
"first_name": "Jane",
|
||||
"last_name": "Smith",
|
||||
"email": "jane@example.com",
|
||||
"department_id": "dept1",
|
||||
"department_id": deptID,
|
||||
"title": "Engineer",
|
||||
},
|
||||
},
|
||||
@@ -54,6 +79,8 @@ func TestDepartmentEmployees(t *testing.T) {
|
||||
|
||||
resp = makeRequest(t, "/employees", empPayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
emps := createdIDs(resp)
|
||||
emp1ID, emp2ID = emps[0], emps[1]
|
||||
|
||||
// Read department with employees
|
||||
readPayload := map[string]interface{}{
|
||||
@@ -68,7 +95,7 @@ func TestDepartmentEmployees(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
resp = makeRequest(t, "/departments/dept1", readPayload)
|
||||
resp = makeRequest(t, fmt.Sprintf("/departments/%d", deptID), readPayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
@@ -83,29 +110,29 @@ func TestEmployeeHierarchy(t *testing.T) {
|
||||
mgrPayload := map[string]interface{}{
|
||||
"operation": "create",
|
||||
"data": map[string]interface{}{
|
||||
"id": "mgr1",
|
||||
"first_name": "Alice",
|
||||
"last_name": "Manager",
|
||||
"email": "alice@example.com",
|
||||
"title": "Engineering Manager",
|
||||
"department_id": "dept1",
|
||||
"department_id": deptID,
|
||||
},
|
||||
}
|
||||
|
||||
resp := makeRequest(t, "/employees", mgrPayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
mgrID = createdIDs(resp)[0]
|
||||
|
||||
// Update employees to set manager
|
||||
updatePayload := map[string]interface{}{
|
||||
"operation": "update",
|
||||
"data": map[string]interface{}{
|
||||
"manager_id": "mgr1",
|
||||
"manager_id": mgrID,
|
||||
},
|
||||
}
|
||||
|
||||
resp = makeRequest(t, "/employees/emp1", updatePayload)
|
||||
resp = makeRequest(t, fmt.Sprintf("/employees/%d", emp1ID), updatePayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
resp = makeRequest(t, "/employees/emp2", updatePayload)
|
||||
resp = makeRequest(t, fmt.Sprintf("/employees/%d", emp2ID), updatePayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
// Read manager with reports
|
||||
@@ -121,7 +148,7 @@ func TestEmployeeHierarchy(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
resp = makeRequest(t, "/employees/mgr1", readPayload)
|
||||
resp = makeRequest(t, fmt.Sprintf("/employees/%d", mgrID), readPayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
@@ -136,7 +163,6 @@ func TestProjectStructure(t *testing.T) {
|
||||
projectPayload := map[string]interface{}{
|
||||
"operation": "create",
|
||||
"data": map[string]interface{}{
|
||||
"id": "proj1",
|
||||
"name": "New Website",
|
||||
"code": "WEB",
|
||||
"description": "Company website redesign",
|
||||
@@ -149,15 +175,15 @@ func TestProjectStructure(t *testing.T) {
|
||||
|
||||
resp := makeRequest(t, "/projects", projectPayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
projID = createdIDs(resp)[0]
|
||||
|
||||
// Create project tasks
|
||||
taskPayload := map[string]interface{}{
|
||||
"operation": "create",
|
||||
"data": []map[string]interface{}{
|
||||
{
|
||||
"id": "task1",
|
||||
"project_id": "proj1",
|
||||
"assignee_id": "emp1",
|
||||
"project_id": projID,
|
||||
"assignee_id": emp1ID,
|
||||
"title": "Design Homepage",
|
||||
"description": "Create homepage design",
|
||||
"status": "in_progress",
|
||||
@@ -165,9 +191,8 @@ func TestProjectStructure(t *testing.T) {
|
||||
"due_date": time.Now().AddDate(0, 1, 0).Format(time.RFC3339),
|
||||
},
|
||||
{
|
||||
"id": "task2",
|
||||
"project_id": "proj1",
|
||||
"assignee_id": "emp2",
|
||||
"project_id": projID,
|
||||
"assignee_id": emp2ID,
|
||||
"title": "Implement Backend",
|
||||
"description": "Implement backend APIs",
|
||||
"status": "planned",
|
||||
@@ -179,14 +204,14 @@ func TestProjectStructure(t *testing.T) {
|
||||
|
||||
resp = makeRequest(t, "/project_tasks", taskPayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
task1ID = createdIDs(resp)[0]
|
||||
|
||||
// Create task comments
|
||||
commentPayload := map[string]interface{}{
|
||||
"operation": "create",
|
||||
"data": map[string]interface{}{
|
||||
"id": "comment1",
|
||||
"task_id": "task1",
|
||||
"author_id": "mgr1",
|
||||
"task_id": task1ID,
|
||||
"author_id": mgrID,
|
||||
"content": "Looking good! Please add more animations.",
|
||||
},
|
||||
}
|
||||
@@ -223,7 +248,7 @@ func TestProjectStructure(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
resp = makeRequest(t, "/projects/proj1", readPayload)
|
||||
resp = makeRequest(t, fmt.Sprintf("/projects/%d", projID), readPayload)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
var result map[string]interface{}
|
||||
|
||||
Reference in New Issue
Block a user