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

206 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"
}
};
}
function run() {
describe("NativeJsonSerializer", function() {
beforeEach(function() {
variables.serializer = new core.nativeJsonSerializer();
});
describe("inheritance", function() {
it("should extend baseSerializer", function() {
expect(new tests.helpers.MetadataHelper().extendsClass(serializer, "baseSerializer")).toBeTrue();
});
it("should have all baseSerializer methods", function() {
expect(serializer).toHaveKey("setData");
expect(serializer).toHaveKey("getData");
expect(serializer).toHaveKey("withStatus");
expect(serializer).toHaveKey("withHeaders");
expect(serializer).toHaveKey("noData");
expect(serializer).toHaveKey("noContent");
});
});
describe("getAsJson()", function() {
it("should serialize simple string to JSON", function() {
serializer.setData("Hello World");
var result = serializer.getAsJson();
expect(result).toBe('"Hello World"');
});
it("should serialize struct to JSON", function() {
serializer.setData({ name: "Test", value: 123 });
var result = serializer.getAsJson();
var parsed = deserializeJSON(result);
expect(parsed.name).toBe("Test");
expect(parsed.value).toBe(123);
});
it("should serialize array to JSON", function() {
serializer.setData([1, 2, 3]);
var result = serializer.getAsJson();
var parsed = deserializeJSON(result);
expect(parsed).toBeArray();
expect(arrayLen(parsed)).toBe(3);
});
it("should serialize nested structures to JSON", function() {
serializer.setData({
user: {
name: "John",
roles: ["admin", "user"]
},
active: true
});
var result = serializer.getAsJson();
var parsed = deserializeJSON(result);
expect(parsed.user.name).toBe("John");
expect(parsed.user.roles).toBeArray();
expect(parsed.active).toBeTrue();
});
it("should serialize boolean values correctly", function() {
serializer.setData({ active: true, deleted: false });
var result = serializer.getAsJson();
var parsed = deserializeJSON(result);
expect(parsed.active).toBeTrue();
expect(parsed.deleted).toBeFalse();
});
it("should serialize null values", function() {
serializer.setData({ value: javacast("null", "") });
var result = serializer.getAsJson();
expect(result).toInclude("null");
});
it("should handle empty struct", function() {
serializer.setData({});
var result = serializer.getAsJson();
expect(result).toBe("{}");
});
it("should handle empty array", function() {
serializer.setData([]);
var result = serializer.getAsJson();
expect(result).toBe("[]");
});
it("should handle numeric values", function() {
serializer.setData({
integer: 42,
decimal: 3.14,
negative: -100
});
var result = serializer.getAsJson();
var parsed = deserializeJSON(result);
expect(parsed.integer).toBe(42);
expect(parsed.decimal).toBe(3.14);
expect(parsed.negative).toBe(-100);
});
});
describe("taffy:mime metadata", function() {
it("should have taffy:mime metadata for application/json", function() {
var metadata = getMetadata(serializer);
var getAsJsonFunc = "";
for (var func in metadata.functions) {
if (func.name == "getAsJson") {
getAsJsonFunc = func;
break;
}
}
expect(getAsJsonFunc).notToBeEmpty();
var hasMime = structKeyExists(getAsJsonFunc, "taffy:mime")
|| structKeyExists(getAsJsonFunc, "taffy_mime");
expect(hasMime).toBeTrue();
});
it("should be marked as default serializer", function() {
var metadata = getMetadata(serializer);
var getAsJsonFunc = "";
for (var func in metadata.functions) {
if (func.name == "getAsJson") {
getAsJsonFunc = func;
break;
}
}
var hasDefault = structKeyExists(getAsJsonFunc, "taffy:default")
|| structKeyExists(getAsJsonFunc, "taffy_default");
expect(hasDefault).toBeTrue();
});
});
describe("encode.string helper", function() {
it("should force numeric strings to serialize as strings", function() {
// The forceString function adds chr(2) which is then stripped by getAsJson
// This ensures numeric-looking strings serialize as strings, not numbers
var resource = new core.resource();
var forcedString = resource.forceString("12345");
// The chr(2) prefix forces CF to treat this as a string during serialization
expect(left(forcedString, 1)).toBe(chr(2));
// When serialized via nativeJsonSerializer, the chr(2) is stripped
serializer.setData({ value: forcedString });
var result = serializer.getAsJson();
// The value should be serialized as a string (with quotes), not a number
expect(result).toInclude('"');
});
});
describe("combined operations", function() {
it("should work with setData and status code", function() {
serializer.setData({ error: "Not found" }).withStatus(404);
var result = serializer.getAsJson();
var parsed = deserializeJSON(result);
expect(parsed.error).toBe("Not found");
expect(serializer.getStatus()).toBe(404);
});
it("should work with setData, status, and headers", function() {
serializer
.setData({ created: true })
.withStatus(201)
.withHeaders({ "Location": "/items/123" });
var result = serializer.getAsJson();
var parsed = deserializeJSON(result);
expect(parsed.created).toBeTrue();
expect(serializer.getStatus()).toBe(201);
expect(serializer.getHeaders()["Location"]).toBe("/items/123");
});
});
});
}
}