Files
svc-api-x/v1/taffy/tests/specs/unit/ResourceSpec.cfc

208 lines
6.0 KiB
Plaintext

component extends="testbox.system.BaseSpec" {
function beforeAll() {
// Initialize application scope with minimal settings
application._taffy = {
settings: {
serializer: "core.nativeJsonSerializer",
noDataSends204NoContent: false
},
factory: new core.factory(),
compat: {
queryToArray: "missing",
queryToStruct: "missing"
}
};
// Create sample data fixture
variables.sampleData = new tests.fixtures.SampleData();
}
function run() {
describe("Resource", function() {
beforeEach(function() {
variables.resource = new core.resource();
});
describe("rep() / representationOf()", function() {
it("should return a serializer instance with data", function() {
var result = resource.rep({ message: "test" });
expect(new tests.helpers.MetadataHelper().extendsClass(result, "baseSerializer")).toBeTrue();
expect(result.getData().message).toBe("test");
});
it("rep() should be alias for representationOf()", function() {
var data = { id: 123 };
var rep1 = resource.rep(data);
// Both should return serializer instances with same data
expect(rep1.getData().id).toBe(123);
});
it("should work with simple string data", function() {
var result = resource.rep("Hello World");
expect(result.getData()).toBe("Hello World");
});
it("should work with array data", function() {
var result = resource.rep([1, 2, 3]);
expect(result.getData()).toBeArray();
expect(arrayLen(result.getData())).toBe(3);
});
it("should work with nested struct data", function() {
var data = {
user: { name: "John", age: 30 },
roles: ["admin", "user"]
};
var result = resource.rep(data);
expect(result.getData().user.name).toBe("John");
expect(result.getData().roles).toBeArray();
});
});
describe("encode.string()", function() {
it("should add control character prefix to force string serialization", function() {
// forceString is public (no access modifier), encode.string is just a reference to it
var result = resource.forceString("12345");
expect(left(result, 1)).toBe(chr(2));
});
it("should preserve the original value after prefix", function() {
var result = resource.forceString("12345");
expect(right(result, 5)).toBe("12345");
});
it("should work with numeric-looking strings", function() {
var result = resource.forceString("00123");
expect(len(result)).toBe(6); // chr(2) + "00123"
});
});
describe("qToArray() - internal query to array conversion", function() {
beforeEach(function() {
makePublic(resource, "qToArray");
});
it("should convert query to array of structs", function() {
var q = sampleData.getSampleQuery();
var result = resource.qToArray(q);
expect(result).toBeArray();
expect(arrayLen(result)).toBe(3);
});
it("should preserve column values in structs", function() {
var q = sampleData.getSampleQuery();
var result = resource.qToArray(q);
// Find the row with id=1
var found = false;
for (var row in result) {
if (row.id == 1) {
expect(row.name).toBe("John Doe");
expect(row.email).toBe("john@example.com");
found = true;
break;
}
}
expect(found).toBeTrue();
});
it("should handle empty query", function() {
var q = queryNew("id,name", "integer,varchar");
var result = resource.qToArray(q);
expect(result).toBeArray();
expect(arrayLen(result)).toBe(0);
});
it("should support callback function for row transformation", function() {
var q = sampleData.getSingleRowQuery();
var result = resource.qToArray(q, function(row) {
row.transformed = true;
return row;
});
expect(result[1].transformed).toBeTrue();
});
});
describe("qToStruct() - internal query to struct conversion", function() {
beforeEach(function() {
makePublic(resource, "qToStruct");
});
it("should convert single-row query to struct", function() {
var q = sampleData.getSingleRowQuery();
var result = resource.qToStruct(q);
expect(result).toBeStruct();
expect(result.id).toBe(1);
expect(result.name).toBe("Test User");
});
it("should throw error for multi-row query", function() {
var q = sampleData.getSampleQuery(); // Has 3 rows
expect(function() {
resource.qToStruct(q);
}).toThrow();
});
it("should handle query with all column types", function() {
var q = sampleData.getSingleRowQuery();
var result = resource.qToStruct(q);
expect(structKeyExists(result, "id")).toBeTrue();
expect(structKeyExists(result, "name")).toBeTrue();
expect(structKeyExists(result, "email")).toBeTrue();
});
it("should support callback function for value transformation", function() {
var q = sampleData.getSingleRowQuery();
var result = resource.qToStruct(q, function(colName, value) {
if (colName == "name") {
return uCase(value);
}
return value;
});
expect(result.name).toBe("TEST USER");
});
});
describe("method chaining with rep()", function() {
it("should support chaining with withStatus()", function() {
var result = resource.rep({ created: true }).withStatus(201);
expect(result.getStatus()).toBe(201);
expect(result.getData().created).toBeTrue();
});
it("should support chaining with withHeaders()", function() {
var result = resource.rep({ data: "test" })
.withHeaders({ "X-Custom": "value" });
expect(result.getHeaders()["X-Custom"]).toBe("value");
});
it("should support full fluent chain", function() {
var result = resource.rep({ id: 123 })
.withStatus(201, "Created")
.withHeaders({ "Location": "/items/123" });
expect(result.getData().id).toBe(123);
expect(result.getStatus()).toBe(201);
expect(result.getStatusText()).toBe("Created");
expect(result.getHeaders()["Location"]).toBe("/items/123");
});
});
});
}
}