milestone 21: abp list exceptions and a regex rule kind

This commit is contained in:
2026-08-13 19:14:47 +02:00
parent b340521716
commit 2ab7c1f1de
51 changed files with 4016 additions and 465 deletions
+44 -2
View File
@@ -39,7 +39,7 @@ const Created = union(enum) { id: i64, fail: Failure };
/// not understood.
fn toInput(body: Body) union(enum) { input: rules_repo.RuleInput, fail: Failure } {
const kind = model.RuleKind.fromDb(body.kind) orelse
return .{ .fail = .{ .invalid = "kind must be 'exact' or 'wildcard'" } };
return .{ .fail = .{ .invalid = "kind must be 'exact', 'wildcard' or 'regex'" } };
const action = model.RuleAction.fromDb(body.action) orelse
return .{ .fail = .{ .invalid = "action must be 'allow' or 'block'" } };
return .{ .input = .{
@@ -308,7 +308,7 @@ test "an unknown kind or action is a 400 before anything is written" {
try testing.expect(toInput(.{
.group_id = 1,
.pattern = "ads.example",
.kind = "regex",
.kind = "glob",
.action = "block",
}).fail == .invalid);
@@ -327,4 +327,46 @@ test "an unknown kind or action is a 400 before anything is written" {
});
try testing.expectEqual(model.RuleKind.wildcard, good.input.kind);
try testing.expectEqual(model.RuleAction.allow, good.input.action);
const third = toInput(.{
.group_id = 1,
.pattern = "^ad[0-9]+-",
.kind = "regex",
.action = "block",
});
try testing.expectEqual(model.RuleKind.regex, third.input.kind);
}
test "a regex rule is stored, and a pattern the engine refuses is a 400 that names it" {
var bench: mutations.Bench = undefined;
try bench.init(testing.allocator);
defer bench.deinit(testing.allocator);
const created = try applyCreate(&bench.state, bench.io(), bench.arena(), .{
.group_id = 1,
.pattern = "^ad[0-9]+-",
.kind = .regex,
.action = .block,
});
const row = (try rules_repo.getRule(&bench.database, bench.arena(), created.id)).?;
try testing.expectEqual(model.RuleKind.regex, row.kind);
// Stored verbatim: a regex is not a name, so nothing lowercases or
// dot-strips it on the way to the table.
try testing.expectEqualStrings("^ad[0-9]+-", row.pattern);
const unclosed = try applyCreate(&bench.state, bench.io(), bench.arena(), .{
.group_id = 1,
.pattern = "(",
.kind = .regex,
.action = .block,
});
try testing.expectEqualStrings(
"rules[0].pattern: '(' is not a valid regex pattern",
unclosed.fail.invalid,
);
// The refused pattern reached no table, and the good one is still the only
// row: a 400 costs no write and no reload.
try testing.expectEqual(@as(i64, 1), try bench.queryInt("SELECT count(*) FROM rules"));
try testing.expectEqual(@as(usize, 1), bench.reloads);
}