use cookie_rs::error::*;
use cookie_rs::prelude::*;
#[test]
fn simple_cookie() {
let expected = Cookie::new("name", "value");
let input = "name=value";
assert_eq!(Cookie::parse(input), Ok(expected))
}
#[test]
fn empty_name() {
let expected = Err(ParseError::EmptyName);
let input = "=value";
assert_eq!(Cookie::parse(input), expected)
}
#[test]
fn empty_value() {
let expected = Cookie::new("key", "");
let input = "key=";
assert_eq!(Cookie::parse(input), Ok(expected))
}
#[test]
fn empty_input() {
let expected = Err(ParseError::MissingPair(MissingPair::NameValue));
let input = "";
assert_eq!(Cookie::parse(input), expected)
}
#[test]
fn cookie_with_domain() {
let expected = Cookie::builder("name", "value")
.domain("example.com")
.build();
let input = "name=value; Domain=example.com";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_path() {
let expected = Cookie::builder("name", "value")
.path("/path/to/resource")
.build();
let input = "name=value; Path=/path/to/resource";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_secure() {
let expected = Cookie::builder("name", "value").secure(true).build();
let input = "name=value; Secure";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_httponly() {
let expected = Cookie::builder("name", "value").http_only(true).build();
let input = "name=value; HttpOnly";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_max_age() {
let expected = Cookie::builder("name", "value")
.max_age(std::time::Duration::from_secs(3600))
.build();
let input = "name=value; Max-Age=3600";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_samesite_strict() {
let expected = Cookie::builder("name", "value")
.same_site(SameSite::Strict)
.build();
let input = "name=value; SameSite=Strict";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_samesite_lax() {
let expected = Cookie::builder("name", "value")
.same_site(SameSite::Lax)
.build();
let input = "name=value; SameSite=Lax";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_unknown_attribute_strict() {
let expected = Err(ParseError::UnknownAttribute("UnknownAttr".to_string()));
let input = "name=value; UnknownAttr";
assert_eq!(Cookie::parse_strict(input), expected);
}
#[test]
fn cookie_with_unknown_attribute_non_strict() {
let expected = Cookie::builder("name", "value").build();
let input = "name=value; UnknownAttr";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_multiple_attributes() {
let expected = Cookie::builder("name", "value")
.domain("example.com")
.path("/path")
.secure(true)
.http_only(true)
.same_site(SameSite::None)
.build();
let input = "name=value; Domain=example.com; Path=/path; Secure; HttpOnly; SameSite=None";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn malformed_cookie_missing_equals() {
let expected = Err(ParseError::MissingPair(MissingPair::NameValue));
let input = "namevalue";
assert_eq!(Cookie::parse(input), expected);
}
#[test]
fn cookie_with_expires() {
let expected = Cookie::builder("name", "value")
.expires("Wed, 21 Oct 2025 07:28:00 GMT")
.build();
let input = "name=value; Expires=Wed, 21 Oct 2025 07:28:00 GMT";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_partitioned() {
let expected = Cookie::builder("name", "value").partitioned(true).build();
let input = "name=value; Partitioned";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_empty_attribute_value() {
let expected = Cookie::builder("name", "value").path("").build();
let input = "name=value; Path=";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_case_insensitive_attributes() {
let expected = Cookie::builder("name", "value")
.secure(true)
.http_only(true)
.same_site(SameSite::Lax)
.build();
let input = "name=value; secure; httponly; samesite=Lax";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_unexpected_whitespace() {
let expected = Cookie::builder("name", "value")
.domain("example.com")
.path("/")
.secure(true)
.http_only(true)
.build();
let input = " name = value ; Domain = example.com ; Path = / ; Secure ; HttpOnly ";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_empty_pair() {
let expected = Err(ParseError::MissingPair(MissingPair::NameValue));
let input = ";";
assert_eq!(Cookie::parse(input), expected);
}
#[test]
fn cookie_with_duplicate_attributes() {
let expected = Cookie::builder("name", "value").path("/second").build();
let input = "name=value; Path=/first; Path=/second";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_invalid_max_age() {
let expected = Err(ParseError::ParseMaxAgeError(
"invalid".parse::<i64>().unwrap_err(),
));
let input = "name=value; Max-Age=invalid";
assert_eq!(Cookie::parse(input), expected);
}
#[test]
fn cookie_with_negative_max_age() {
let expected = Cookie::builder("name", "value")
.max_age(std::time::Duration::ZERO)
.build();
let input = "name=value; Max-Age=-1";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_zero_max_age() {
let expected = Cookie::builder("name", "value")
.max_age(std::time::Duration::ZERO)
.build();
let input = "name=value; Max-Age=0";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_large_negative_max_age() {
let expected = Cookie::builder("name", "value")
.max_age(std::time::Duration::ZERO)
.build();
let input = "name=value; Max-Age=-99999";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_invalid_samesite_value() {
let expected = Err(ParseError::ParseSameSiteError(
ParseSameSiteError::UnknownValue("InvalidValue".to_string()),
));
let input = "name=value; SameSite=InvalidValue";
assert_eq!(Cookie::parse(input), expected);
}
#[test]
fn cookie_with_trailing_semicolon() {
let expected = Cookie::builder("name", "value").build();
let input = "name=value;";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_with_invalid_format() {
let expected = Err(ParseError::MissingPair(MissingPair::NameValue));
let input = "name-value";
assert_eq!(Cookie::parse(input), expected);
}
#[test]
fn cookie_with_non_ascii_name() {
let expected = Cookie::builder("имя", "значение").build();
let input = "имя=значение";
assert_eq!(Cookie::parse(input), Ok(expected));
}
#[test]
fn cookie_into_owned_preserves_fields() {
let input = String::from("session=abc123; Path=/; Domain=example.com; Secure");
let cookie: Cookie<'static> = Cookie::parse(input).unwrap().into_owned();
assert_eq!(cookie.name(), "session");
assert_eq!(cookie.value(), "abc123");
assert_eq!(cookie.path(), Some("/"));
assert_eq!(cookie.domain(), Some("example.com"));
assert_eq!(cookie.secure(), Some(true));
}
#[test]
fn cookie_into_owned_from_borrowed() {
let cookie: Cookie<'static> = Cookie::new("name", "value").into_owned();
assert_eq!(cookie.name(), "name");
assert_eq!(cookie.value(), "value");
}
#[test]
fn cookie_into_owned_with_all_attributes() {
let input =
String::from("name=value; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Strict");
let cookie: Cookie<'static> = Cookie::parse(input).unwrap().into_owned();
assert_eq!(cookie.domain(), Some("example.com"));
assert_eq!(cookie.path(), Some("/"));
assert_eq!(cookie.secure(), Some(true));
assert_eq!(cookie.http_only(), Some(true));
assert_eq!(cookie.same_site(), Some(SameSite::Strict));
}
#[cfg(feature = "percent-encoding")]
#[test]
fn cookie_value_decoded_on_parse() {
let cookie = Cookie::parse("data=hello%20world").unwrap();
assert_eq!(cookie.value(), "hello world");
}
#[cfg(feature = "percent-encoding")]
#[test]
fn cookie_value_decoded_utf8() {
let cookie = Cookie::parse("data=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82").unwrap();
assert_eq!(cookie.value(), "привет");
}
#[cfg(feature = "percent-encoding")]
#[test]
fn cookie_value_invalid_encoding_passthrough() {
let cookie = Cookie::parse("data=%ZZ").unwrap();
assert_eq!(cookie.value(), "%ZZ");
}
#[cfg(feature = "percent-encoding")]
#[test]
fn cookie_value_percent_sign_roundtrip() {
let cookie = Cookie::new("data", "50% off");
let parsed = Cookie::parse(cookie.to_string()).unwrap();
assert_eq!(parsed.value(), "50% off");
}