Skip to content

Commit 6bf4d88

Browse files
authored
Add tests for Zulip's URL encoding (#723)
1 parent 76a9a45 commit 6bf4d88

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

src/zulip.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::handlers::Context;
55
use anyhow::Context as _;
66
use std::convert::TryInto;
77
use std::env;
8-
use std::io::Write as _;
8+
use std::fmt::Write as _;
99

1010
#[derive(Debug, serde::Deserialize)]
1111
pub struct Request {
@@ -344,25 +344,48 @@ impl Recipient<'_> {
344344
const ALWAYS_SAFE: &str =
345345
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-~";
346346

347-
let mut encoded_topic = Vec::new();
347+
let mut encoded_topic = String::new();
348348
for ch in topic.bytes() {
349349
if !(ALWAYS_SAFE.contains(ch as char)) {
350-
write!(encoded_topic, "%{:02X}", ch).unwrap();
350+
write!(encoded_topic, ".{:02X}", ch).unwrap();
351351
} else {
352-
encoded_topic.push(ch);
352+
encoded_topic.push(ch as char);
353353
}
354354
}
355-
356-
let mut encoded_topic = String::from_utf8(encoded_topic).unwrap();
357-
encoded_topic = encoded_topic.replace("%", ".");
358-
359355
format!("stream/{}-xxx/topic/{}", id, encoded_topic)
360356
}
361357
Recipient::Private { id, .. } => format!("pm-with/{}-xxx", id),
362358
}
363359
}
364360
}
365361

362+
#[cfg(test)]
363+
fn check_encode(topic: &str, expected: &str) {
364+
const PREFIX: &str = "stream/0-xxx/topic/";
365+
let computed = Recipient::Stream { id: 0, topic }.narrow();
366+
assert_eq!(&computed[..PREFIX.len()], PREFIX);
367+
assert_eq!(&computed[PREFIX.len()..], expected);
368+
}
369+
370+
#[test]
371+
fn test_encode() {
372+
check_encode("some text with spaces", "some.20text.20with.20spaces");
373+
check_encode(
374+
" !\"#$%&'()*+,-./",
375+
".20.21.22.23.24.25.26.27.28.29.2A.2B.2C-.2E.2F",
376+
);
377+
check_encode("0123456789:;<=>?", "0123456789.3A.3B.3C.3D.3E.3F");
378+
check_encode(
379+
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_",
380+
".40ABCDEFGHIJKLMNOPQRSTUVWXYZ.5B.5C.5D.5E_",
381+
);
382+
check_encode(
383+
"`abcdefghijklmnopqrstuvwxyz{|}~",
384+
".60abcdefghijklmnopqrstuvwxyz.7B.7C.7D~.7F",
385+
);
386+
check_encode("áé…", ".C3.A1.C3.A9.E2.80.A6");
387+
}
388+
366389
#[derive(serde::Serialize)]
367390
pub struct MessageApiRequest<'a> {
368391
pub recipient: Recipient<'a>,

0 commit comments

Comments
 (0)