diff --git a/integration/tests/cookies.hurl b/integration/tests/cookies.hurl index 21543ae9a..4767e333f 100644 --- a/integration/tests/cookies.hurl +++ b/integration/tests/cookies.hurl @@ -64,8 +64,8 @@ cookie "LSID[Expires]" equals "Wed, 13 Jan 2021 22:23:01 GMT" cookie "LSID[Max-Age]" not exists cookie "LSID[Domain]" not exists cookie "LSID[Path]" equals "/accounts" -cookie "LSID[Secure]" equals true -cookie "LSID[HttpOnly]" equals true +cookie "LSID[Secure]" exists +cookie "LSID[HttpOnly]" exists cookie "LSID[SameSite]" not exists diff --git a/integration/tests/error_assert_query_cookie.err b/integration/tests/error_assert_query_cookie.err new file mode 100644 index 000000000..712c78ea4 --- /dev/null +++ b/integration/tests/error_assert_query_cookie.err @@ -0,0 +1,16 @@ +error: Assert Failure + --> tests/error_assert_query_cookie.hurl:4:0 + | + 4 | cookie "cookie1[Secure]" equals false # This is not valid, Secure attribute exists or not but does have a value + | actual: none + | expected: bool + | + +error: Assert Failure + --> tests/error_assert_query_cookie.hurl:6:0 + | + 6 | cookie "cookie2[Secure]" equals true # This is not valid, Secure attribute exists or not but does have a value + | actual: unit + | expected: bool + | + diff --git a/integration/tests/error_assert_query_cookie.exit b/integration/tests/error_assert_query_cookie.exit new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/integration/tests/error_assert_query_cookie.exit @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/integration/tests/error_assert_query_cookie.hurl b/integration/tests/error_assert_query_cookie.hurl new file mode 100644 index 000000000..debaa443e --- /dev/null +++ b/integration/tests/error_assert_query_cookie.hurl @@ -0,0 +1,8 @@ +GET http://localhost:8000/error-assert-query-cookie +HTTP/1.0 200 +[Asserts] +cookie "cookie1[Secure]" equals false # This is not valid, Secure attribute exists or not but does have a value +cookie "cookie1[Secure]" not exists +cookie "cookie2[Secure]" equals true # This is not valid, Secure attribute exists or not but does have a value +cookie "cookie2[Secure]" exists + diff --git a/integration/tests/error_assert_query_cookie.py b/integration/tests/error_assert_query_cookie.py new file mode 100644 index 000000000..54fe24c68 --- /dev/null +++ b/integration/tests/error_assert_query_cookie.py @@ -0,0 +1,10 @@ +from flask import request, make_response +from tests import app + +@app.route("/error-assert-query-cookie") +def error_assert_query_cookie(): + resp = make_response() + resp.set_cookie('cookie1', 'value1') + resp.set_cookie('cookie2', 'value2', secure=True) + return resp + diff --git a/src/core/common.rs b/src/core/common.rs index 3b60867df..d7081601a 100644 --- a/src/core/common.rs +++ b/src/core/common.rs @@ -34,6 +34,7 @@ pub enum DeprecatedValue { #[derive(Clone, Debug, PartialEq, Eq)] //#[derive(Clone, Debug, PartialEq, PartialOrd)] pub enum Value { + Unit, Bool(bool), Integer(i64), @@ -65,6 +66,7 @@ impl fmt::Display for Value { Value::Nodeset(x) => format!("Nodeset{:?}", x), Value::Bytes(x) => format!("Bytes({:x?})", x), Value::Null => "Null".to_string(), + Value::Unit => "Unit".to_string(), }; write!(f, "{}", value) } @@ -81,7 +83,8 @@ impl Value { Value::Object(_) => "object".to_string(), Value::Nodeset(_) => "nodeset".to_string(), Value::Bytes(_) => "bytes".to_string(), - Value::Null => "unit".to_string(), + Value::Null => "null".to_string(), + Value::Unit => "unit".to_string(), } } @@ -194,6 +197,7 @@ impl Serialize for Value { serializer.serialize_str(&encoded) } Value::Null => serializer.serialize_none(), + Value::Unit => todo!("how to serialize that in json?"), } } } @@ -213,6 +217,7 @@ impl Value { Value::Nodeset(_) => todo!(), Value::Bytes(_) => todo!(), Value::Null => todo!(), + Value::Unit => todo!(), } } @@ -230,6 +235,7 @@ impl Value { Value::Nodeset(_) => todo!(), Value::Bytes(_) => todo!(), Value::Null => todo!(), + Value::Unit => todo!(), } } } diff --git a/src/runner/predicate.rs b/src/runner/predicate.rs index 2c072aafb..2b3400b00 100644 --- a/src/runner/predicate.rs +++ b/src/runner/predicate.rs @@ -126,6 +126,7 @@ impl Value { Value::Object(_) => "object".to_string(), Value::Bytes(values) => format!("byte array of size <{}>", values.len()), Value::Null => "null".to_string(), + Value::Unit => "unit".to_string(), } } } @@ -396,7 +397,7 @@ impl PredicateFunc { source_info: self.source_info.clone(), inner: RunnerError::InvalidRegex(), assert: false, - }) + }); } }; match value.clone() { @@ -581,10 +582,7 @@ mod tests { ); assert_eq!(error.source_info, SourceInfo::init(1, 0, 1, 0)); - assert_eq!( - predicate.eval(&variables, Some(Value::Integer(1))).unwrap(), - () - ); + assert!(predicate.eval(&variables, Some(Value::Integer(1))).is_ok()); } #[test] @@ -609,6 +607,27 @@ mod tests { assert_eq!(assert_result.expected.as_str(), "int <10>"); } + #[test] + fn test_predicate_type_mismatch_with_unit() { + let variables = HashMap::new(); + let whitespace = Whitespace { + value: String::from(" "), + source_info: SourceInfo::init(0, 0, 0, 0), + }; + let assert_result = PredicateFunc { + value: PredicateFuncValue::EqualInt { + space0: whitespace, + value: 10, + }, + source_info: SourceInfo::init(0, 0, 0, 0), + } + .eval(&variables, Some(Value::Unit)) + .unwrap(); + assert_eq!(assert_result.success, false); + assert_eq!(assert_result.type_mismatch, true); + assert_eq!(assert_result.actual.as_str(), "unit"); + assert_eq!(assert_result.expected.as_str(), "int <10>"); + } #[test] fn test_predicate_value_error() { let variables = HashMap::new(); @@ -667,6 +686,28 @@ mod tests { ); } + #[test] + fn test_predicate_exist() { + let variables = HashMap::new(); + let predicate = PredicateFunc { + value: PredicateFuncValue::Exist {}, + source_info: SourceInfo::init(0, 0, 0, 0), + }; + + let assert_result = predicate + .clone() + .eval(&variables, Some(Value::Unit)) + .unwrap(); + assert_eq!(assert_result.success, true); + assert_eq!(assert_result.actual.as_str(), "unit"); + assert_eq!(assert_result.expected.as_str(), "something"); + + let assert_result = predicate.eval(&variables, None).unwrap(); + assert_eq!(assert_result.success, false); + assert_eq!(assert_result.actual.as_str(), "none"); + assert_eq!(assert_result.expected.as_str(), "something"); + } + #[test] fn test_predicate_value_equals() { let variables = HashMap::new(); diff --git a/src/runner/query.rs b/src/runner/query.rs index 9186b2f06..cb93c274a 100644 --- a/src/runner/query.rs +++ b/src/runner/query.rs @@ -232,14 +232,14 @@ impl CookieAttributeName { CookieAttributeName::Path(_) => cookie.path().map(Value::String), CookieAttributeName::Secure(_) => { if cookie.has_secure() { - Some(Value::Bool(true)) + Some(Value::Unit) } else { None } } CookieAttributeName::HttpOnly(_) => { if cookie.has_httponly() { - Some(Value::Bool(true)) + Some(Value::Unit) } else { None } @@ -616,7 +616,7 @@ pub mod tests { }; assert_eq!( query.eval(&variables, response.clone()).unwrap().unwrap(), - Value::Bool(true) + Value::Unit ); // cookie "LSID[Domain]" @@ -698,13 +698,13 @@ pub mod tests { CookieAttributeName::Secure("_".to_string()) .eval(cookie.clone()) .unwrap(), - Value::Bool(true) + Value::Unit ); assert_eq!( CookieAttributeName::HttpOnly("_".to_string()) .eval(cookie.clone()) .unwrap(), - Value::Bool(true) + Value::Unit ); assert_eq!( CookieAttributeName::SameSite("_".to_string()).eval(cookie),