|
|
|
@@ -315,6 +315,207 @@ describe("ucas render command", () => {
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("Schema Hash Validation in put command", () => {
|
|
|
|
|
test("put with non-existent literal hash should fail", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify({ test: "data" }));
|
|
|
|
|
|
|
|
|
|
const { stderr, exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
"AAAAAAAAAAAAA",
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).not.toBe(0);
|
|
|
|
|
expect(stderr).toContain("Schema not found: AAAAAAAAAAAAA");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("put with different non-existent literal hash should fail", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify({ test: "data" }));
|
|
|
|
|
|
|
|
|
|
const { stderr, exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
"ZZZZZZZZZZZZZ",
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).not.toBe(0);
|
|
|
|
|
expect(stderr).toContain("Schema not found: ZZZZZZZZZZZZZ");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("put with malformed hash should fail", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify({ test: "data" }));
|
|
|
|
|
|
|
|
|
|
const { stderr, exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
"INVALID_HASH",
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).not.toBe(0);
|
|
|
|
|
expect(stderr.length).toBeGreaterThan(0);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("put with non-existent @alias should fail with clear message", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify({ test: "data" }));
|
|
|
|
|
|
|
|
|
|
const { stderr, exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
"@nonexistent",
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).not.toBe(0);
|
|
|
|
|
expect(stderr).toContain("Schema not found");
|
|
|
|
|
expect(stderr).toContain("@nonexistent");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("put with valid @string alias should succeed (regression)", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify("hello"));
|
|
|
|
|
|
|
|
|
|
const { stdout, stderr, exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
"@string",
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).toBe(0);
|
|
|
|
|
expect(stderr).toBe("");
|
|
|
|
|
expect(stdout).toMatch(/^[0-9A-HJKMNP-TV-Z]{13}$/);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("put with valid @number alias should succeed (regression)", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, "42");
|
|
|
|
|
|
|
|
|
|
const { stdout, stderr, exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
"@number",
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).toBe(0);
|
|
|
|
|
expect(stderr).toBe("");
|
|
|
|
|
expect(stdout).toMatch(/^[0-9A-HJKMNP-TV-Z]{13}$/);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("put with valid @object alias should succeed (regression)", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify({ key: "value" }));
|
|
|
|
|
|
|
|
|
|
const { stdout, stderr, exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
"@object",
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).toBe(0);
|
|
|
|
|
expect(stderr).toBe("");
|
|
|
|
|
expect(stdout).toMatch(/^[0-9A-HJKMNP-TV-Z]{13}$/);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("put with explicit valid schema hash should succeed (regression)", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
// First, create a custom schema
|
|
|
|
|
const schemaFile = join(testDir, "schema.json");
|
|
|
|
|
writeFileSync(
|
|
|
|
|
schemaFile,
|
|
|
|
|
JSON.stringify({
|
|
|
|
|
type: "object",
|
|
|
|
|
properties: { name: { type: "string" } },
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
const { stdout: schemaHash } = await runCliAlias(
|
|
|
|
|
"schema",
|
|
|
|
|
"put",
|
|
|
|
|
schemaFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Now create a node with that schema
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify({ name: "test" }));
|
|
|
|
|
|
|
|
|
|
const { stdout, stderr, exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
schemaHash.trim(),
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).toBe(0);
|
|
|
|
|
expect(stderr).toBe("");
|
|
|
|
|
expect(stdout).toMatch(/^[0-9A-HJKMNP-TV-Z]{13}$/);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("all bootstrap schema aliases should work (regression)", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const aliases = ["@string", "@number", "@object", "@array", "@bool"];
|
|
|
|
|
const payloads = [
|
|
|
|
|
JSON.stringify("test"),
|
|
|
|
|
"123",
|
|
|
|
|
JSON.stringify({}),
|
|
|
|
|
JSON.stringify([]),
|
|
|
|
|
"true",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < aliases.length; i++) {
|
|
|
|
|
const payloadFile = join(testDir, `payload-${i}.json`);
|
|
|
|
|
writeFileSync(payloadFile, payloads[i] ?? "");
|
|
|
|
|
|
|
|
|
|
const { exitCode } = await runCliAlias(
|
|
|
|
|
"put",
|
|
|
|
|
aliases[i] ?? "",
|
|
|
|
|
payloadFile,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(exitCode).toBe(0);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("error message should preserve original input (hash)", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify({ test: "data" }));
|
|
|
|
|
|
|
|
|
|
const { stderr } = await runCliAlias("put", "AAAAAAAAAAAAA", payloadFile);
|
|
|
|
|
|
|
|
|
|
// Error should show the original hash, not a resolved version
|
|
|
|
|
expect(stderr).toContain("AAAAAAAAAAAAA");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("error message should preserve original input (alias)", async () => {
|
|
|
|
|
await runCliAlias("init");
|
|
|
|
|
|
|
|
|
|
const payloadFile = join(testDir, "payload.json");
|
|
|
|
|
writeFileSync(payloadFile, JSON.stringify({ test: "data" }));
|
|
|
|
|
|
|
|
|
|
const { stderr } = await runCliAlias("put", "@invalid", payloadFile);
|
|
|
|
|
|
|
|
|
|
// Error should show the original alias, not a resolved hash
|
|
|
|
|
expect(stderr).toContain("@invalid");
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("Suite 6: CLI Integration with Templates", () => {
|
|
|
|
|
test("6.1 CLI with Template (Default Parameters)", async () => {
|
|
|
|
|
const tmpStore = mkdtempSync(join(tmpdir(), "json-cas-test-"));
|
|
|
|
|