mirror of
https://github.com/block/buzz.git
synced 2026-10-31 14:31:02 +00:00
148 lines
3.7 KiB
JavaScript
148 lines
3.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
|
|
import {
|
|
buildConditionExpression,
|
|
conditionFieldsForTrigger,
|
|
conditionOperatorsForField,
|
|
normalizeWebhookField,
|
|
parseConditionExpression,
|
|
} from "./workflowConditionExpression.ts";
|
|
|
|
test("builds the supported string conditions", () => {
|
|
assert.equal(
|
|
buildConditionExpression({
|
|
field: "trigger_text",
|
|
operator: "contains",
|
|
value: "deploy",
|
|
}),
|
|
'str_contains(trigger_text, "deploy")',
|
|
);
|
|
assert.equal(
|
|
buildConditionExpression({
|
|
field: "trigger_text",
|
|
operator: "not_contains",
|
|
value: "draft",
|
|
}),
|
|
'!str_contains(trigger_text, "draft")',
|
|
);
|
|
assert.equal(
|
|
buildConditionExpression({
|
|
field: "trigger_author",
|
|
operator: "equals",
|
|
value: "abc123",
|
|
}),
|
|
'trigger_author == "abc123"',
|
|
);
|
|
});
|
|
|
|
test("escapes values before placing them in an expression", () => {
|
|
assert.equal(
|
|
buildConditionExpression({
|
|
field: "trigger_text",
|
|
operator: "equals",
|
|
value: 'say "hello"\\world',
|
|
}),
|
|
'trigger_text == "say \\"hello\\"\\\\world"',
|
|
);
|
|
});
|
|
|
|
test("builds empty checks without requiring comparison text", () => {
|
|
assert.equal(
|
|
buildConditionExpression({
|
|
field: "trigger_emoji",
|
|
operator: "is_not_empty",
|
|
value: "",
|
|
}),
|
|
"str_len(trigger_emoji) > 0",
|
|
);
|
|
});
|
|
|
|
test("normalizes safe webhook fields and rejects reserved or invalid names", () => {
|
|
assert.equal(normalizeWebhookField("environment"), "trigger_environment");
|
|
assert.equal(normalizeWebhookField("deploy_id"), "trigger_deploy_id");
|
|
assert.equal(normalizeWebhookField("trigger_text"), null);
|
|
assert.equal(normalizeWebhookField("bad-name"), null);
|
|
});
|
|
|
|
test("shows trigger-relevant fields", () => {
|
|
assert.deepEqual(
|
|
conditionFieldsForTrigger("reaction_added").map((field) => field.value),
|
|
["trigger_emoji", "trigger_author", "trigger_message_id"],
|
|
);
|
|
assert.equal(conditionFieldsForTrigger("webhook")[0].value, "webhook_field");
|
|
for (const triggerType of ["message_posted", "diff_posted"]) {
|
|
assert.equal(
|
|
conditionFieldsForTrigger(triggerType).some(
|
|
(field) => field.value === "trigger_message_id",
|
|
),
|
|
false,
|
|
);
|
|
}
|
|
for (const triggerType of [
|
|
"message_posted",
|
|
"diff_posted",
|
|
"reaction_added",
|
|
"webhook",
|
|
"schedule",
|
|
]) {
|
|
assert.equal(
|
|
conditionFieldsForTrigger(triggerType).some(
|
|
(field) => field.value === "trigger_channel_id",
|
|
),
|
|
false,
|
|
);
|
|
}
|
|
});
|
|
|
|
test("limits opaque identifiers to equality operators", () => {
|
|
for (const field of [
|
|
"trigger_author",
|
|
"trigger_emoji",
|
|
"trigger_channel_id",
|
|
"trigger_message_id",
|
|
"future_resource_id",
|
|
]) {
|
|
assert.deepEqual(conditionOperatorsForField(field), [
|
|
"equals",
|
|
"not_equals",
|
|
]);
|
|
}
|
|
assert.equal(conditionOperatorsForField("trigger_text").length, 8);
|
|
});
|
|
|
|
test("parses generated conditions back into editor fields", () => {
|
|
assert.deepEqual(
|
|
parseConditionExpression(
|
|
'str_contains(trigger_text, "deploy \\"buzz\\"")',
|
|
"message_posted",
|
|
),
|
|
{
|
|
field: "trigger_text",
|
|
operator: "contains",
|
|
value: 'deploy "buzz"',
|
|
webhookField: "",
|
|
},
|
|
);
|
|
assert.deepEqual(
|
|
parseConditionExpression('trigger_environment == "prod"', "webhook"),
|
|
{
|
|
field: "webhook_field",
|
|
operator: "equals",
|
|
value: "prod",
|
|
webhookField: "environment",
|
|
},
|
|
);
|
|
});
|
|
|
|
test("keeps unsupported expressions in custom mode", () => {
|
|
assert.equal(
|
|
parseConditionExpression("trigger_timestamp > 0", "message_posted"),
|
|
null,
|
|
);
|
|
assert.equal(
|
|
parseConditionExpression('trigger_emoji == "👍"', "message_posted"),
|
|
null,
|
|
);
|
|
});
|