Merge pull request #278 from ArnasDon/fix/keyword-match-default-match-type

fix(automations): persist default match_type for Keyword Match triggers
This commit is contained in:
Arnas Donauskas 2026-06-22 10:27:27 +03:00 committed by GitHub
commit c56ef7d5af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 1 deletions

View File

@ -723,6 +723,18 @@ function KeywordMatchConfig({
// when the trigger type changes, so the seed stays in sync.
const [draft, setDraft] = useState(keywords.join(", "))
// Persist the default the <select> displays. The dropdown falls back to
// "contains" for display, but leaving it untouched would otherwise omit
// match_type from the saved config — and activation validation then
// rejected it (trigger.match_type). Seed once on mount; the component
// remounts when the trigger type changes, matching the keywords draft.
useEffect(() => {
if (config?.match_type == null) {
onChange({ ...config, match_type: "contains" })
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
function commit() {
const parsed = draft
.split(",")

View File

@ -212,6 +212,12 @@ describe("validateTriggerForActivation", () => {
expect(issues.map((i) => i.path)).toContain("trigger.match_type");
});
it("accepts keyword_match with a missing match_type (defaults to contains)", () => {
expect(
validateTriggerForActivation("keyword_match", { keywords: ["hi"] }),
).toEqual([]);
});
it("requires schedule on time_based triggers", () => {
expect(validateTriggerForActivation("time_based", {})).toEqual([
{ path: "trigger.schedule", message: "schedule is required" },

View File

@ -154,7 +154,13 @@ export function validateTriggerForActivation(
} else if (k.some((v) => typeof v !== 'string' || v.trim() === '')) {
issues.push({ path: 'trigger.keywords', message: 'keywords cannot be empty strings' })
}
if (cfg.match_type !== 'exact' && cfg.match_type !== 'contains') {
// A missing match_type defaults to "contains" at runtime (see
// automations/engine.ts and flows/engine.ts, which both read
// `match_type ?? "contains"`), so only an explicit, unrecognised
// value is invalid here. This keeps activation validation in step
// with the engine and with the builder's "Contains" default — an
// automation that shows the default in the UI must not be rejected.
if (cfg.match_type != null && cfg.match_type !== 'exact' && cfg.match_type !== 'contains') {
issues.push({
path: 'trigger.match_type',
message: 'match type must be "exact" or "contains"',