karma-web: static HTML karma board served at karma.devtronic.pro
All checks were successful
ci / check (push) Successful in 43s
All checks were successful
ci / check (push) Successful in 43s
This commit is contained in:
parent
e801b04d6e
commit
9a3393153a
6 changed files with 339 additions and 1 deletions
60
tests/karma_web.rs
Normal file
60
tests/karma_web.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
use rustbot::karma_web::{parse_board, render};
|
||||
|
||||
#[test]
|
||||
fn parses_flat_number_format() {
|
||||
let b = parse_board("libera", r#"{"romaka":2}"#);
|
||||
assert_eq!(b.rows.len(), 1);
|
||||
assert_eq!(b.rows[0].thing, "romaka");
|
||||
assert_eq!(b.rows[0].count, 2);
|
||||
assert!(b.rows[0].reason.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_object_format_with_reason_and_by() {
|
||||
let b = parse_board("t", r#"{"rust":{"n":5,"why":"clean PR","by":"alice"}}"#);
|
||||
assert_eq!(b.rows[0].count, 5);
|
||||
assert_eq!(b.rows[0].reason.as_deref(), Some("clean PR"));
|
||||
assert_eq!(b.rows[0].by.as_deref(), Some("alice"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sorts_descending_by_count() {
|
||||
let b = parse_board("t", r#"{"a":1,"b":9,"c":-3}"#);
|
||||
let order: Vec<&str> = b.rows.iter().map(|r| r.thing.as_str()).collect();
|
||||
assert_eq!(order, vec!["b", "a", "c"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn renders_scores_and_reason() {
|
||||
let b = parse_board(
|
||||
"libera",
|
||||
r#"{"rust":{"n":5,"why":"clean PR","by":"alice"}}"#,
|
||||
);
|
||||
let html = render(&[b], 0);
|
||||
assert!(html.contains("libera"), "{html}");
|
||||
assert!(html.contains(">rust<"), "{html}");
|
||||
assert!(html.contains(">+5<"), "{html}");
|
||||
assert!(html.contains("clean PR"), "{html}");
|
||||
assert!(html.contains("alice"), "{html}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escapes_untrusted_irc_input() {
|
||||
let b = parse_board(
|
||||
"t",
|
||||
r#"{"<script>":{"n":1,"why":"\"><img src=x>","by":"a&b"}}"#,
|
||||
);
|
||||
let html = render(&[b], 0);
|
||||
// the page legitimately has its own <script> block; what matters is that the
|
||||
// untrusted nick/reason are escaped and never emit a live tag of their own.
|
||||
assert!(!html.contains("<img"), "raw img tag leaked: {html}");
|
||||
assert!(html.contains("<script>"), "{html}");
|
||||
assert!(html.contains("a&b"), "{html}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_shows_instructions() {
|
||||
let html = render(&[], 0);
|
||||
assert!(html.contains("no karma yet"), "{html}");
|
||||
assert!(html.contains("nick++"), "{html}");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue