;; lib/mod/tests/decide.sx — Phase 1: report representation + simple policy. (define mod-dec-count 0) (define mod-dec-pass 0) (define mod-dec-fail 0) (define mod-dec-failures (list)) (define mod-dec-test! (fn (name got expected) (begin (set! mod-dec-count (+ mod-dec-count 1)) (if (= got expected) (set! mod-dec-pass (+ mod-dec-pass 1)) (begin (set! mod-dec-fail (+ mod-dec-fail 1)) (append! mod-dec-failures (str name "\n expected: " expected "\n got: " got))))))) ;; decide a single report (count over a 1-element registry) (define mod-dec-one (fn (reason) (let ((r (mod/mk-report "r1" "alice" "bob" reason))) (mod/decide-report r (list r) mod/default-rules)))) (define mod-dec-action (fn (reason) (get (mod-dec-one reason) :action))) ;; ── spam keyword → :hide ── (mod-dec-test! "spam keyword 'spam' → hide" (mod-dec-action "this is spam") "hide") (mod-dec-test! "spam keyword 'buy now' → hide" (mod-dec-action "buy now while stocks last") "hide") (mod-dec-test! "spam keyword case-insensitive 'CLICK HERE' → hide" (mod-dec-action "CLICK HERE now") "hide") (mod-dec-test! "spam keyword 'free money' → hide" (mod-dec-action "win free money fast") "hide") ;; ── abuse keyword → :remove ── (mod-dec-test! "abuse keyword 'harassment' → remove" (mod-dec-action "ongoing harassment of users") "remove") (mod-dec-test! "abuse keyword 'threat' → remove" (mod-dec-action "this is a threat") "remove") (mod-dec-test! "abuse keyword 'slur' → remove" (mod-dec-action "contains a slur") "remove") ;; ── no rule → :keep ── (mod-dec-test! "neutral reason → keep" (mod-dec-action "I disagree with this post") "keep") (mod-dec-test! "empty reason → keep" (mod-dec-action "") "keep") ;; ── decision carries the matching rule (proof, not bare keyword) ── (mod-dec-test! "spam decision rule name" (get (mod-dec-one "this is spam") :rule) "spam-hide") (mod-dec-test! "keep decision rule name" (get (mod-dec-one "fine post") :rule) "default-keep") (mod-dec-test! "abuse decision rule name" (get (mod-dec-one "harassment here") :rule) "abuse-remove") (mod-dec-test! "spam proof :rule" (get (get (mod-dec-one "spam!") :proof) :rule) "spam-hide") (mod-dec-test! "spam proof :evidence" (get (get (mod-dec-one "spam!") :proof) :evidence) (list "spam")) (mod-dec-test! "spam proof :count" (get (get (mod-dec-one "spam!") :proof) :count) 1) ;; ── classification (evidence derivation) ── (mod-dec-test! "classify spam" (mod/classify-keywords (mod/mk-report "r1" "a" "b" "spam!")) (list "spam")) (mod-dec-test! "classify abuse" (mod/classify-keywords (mod/mk-report "r1" "a" "b" "abuse")) (list "abuse")) (mod-dec-test! "classify neutral → empty" (mod/classify-keywords (mod/mk-report "r1" "a" "b" "hello")) (list)) (mod-dec-test! "classify both spam+abuse" (mod/classify-keywords (mod/mk-report "r1" "a" "b" "spam and abuse")) (list "spam" "abuse")) ;; ── report-count + repeated → :escalate ── (define mod-dec-three (list (mod/mk-report "r1" "a" "bob" "x") (mod/mk-report "r2" "c" "bob" "y") (mod/mk-report "r3" "d" "bob" "z"))) (mod-dec-test! "report-count counts subject" (mod/report-count "bob" mod-dec-three) 3) (mod-dec-test! "3 reports about subject → escalate" (get (mod/decide-report (first mod-dec-three) mod-dec-three mod/default-rules) :action) "escalate") (mod-dec-test! "escalate rule name" (get (mod/decide-report (first mod-dec-three) mod-dec-three mod/default-rules) :rule) "repeated-escalate") (define mod-dec-two (list (mod/mk-report "r1" "a" "carol" "x") (mod/mk-report "r2" "c" "carol" "y"))) (mod-dec-test! "2 reports about subject → keep (below threshold)" (get (mod/decide-report (first mod-dec-two) mod-dec-two mod/default-rules) :action) "keep") ;; ── precedence: spam beats repeated ── (define mod-dec-spam-among-many (list (mod/mk-report "r1" "a" "dave" "buy now spam") (mod/mk-report "r2" "c" "dave" "y") (mod/mk-report "r3" "d" "dave" "z"))) (mod-dec-test! "spam wins over repeated (precedence)" (get (mod/decide-report (first mod-dec-spam-among-many) mod-dec-spam-among-many mod/default-rules) :action) "hide") ;; ── accessors ── (mod-dec-test! "report-about accessor" (mod/report-about (mod/mk-report "r1" "a" "bob" "x")) "bob") (mod-dec-test! "report-by accessor" (mod/report-by (mod/mk-report "r1" "alice" "bob" "x")) "alice") ;; ── api registry ── (mod/reset!) (define mod-dec-r1 (mod/report "alice" "bob" "this is spam")) (define mod-dec-r2 (mod/report "carol" "eve" "fine post")) (mod-dec-test! "mod/report assigns sequential id r1" (mod/report-id mod-dec-r1) "r1") (mod-dec-test! "mod/report assigns sequential id r2" (mod/report-id mod-dec-r2) "r2") (mod-dec-test! "mod/decide via registry → hide" (get (mod/decide "r1") :action) "hide") (mod-dec-test! "mod/decide via registry → keep" (get (mod/decide "r2") :action) "keep") (mod-dec-test! "mod/decide unknown id → nil" (mod/decide "r99") nil) (define mod-decide-tests-run! (fn () {:failures mod-dec-failures :total mod-dec-count :passed mod-dec-pass :failed mod-dec-fail}))