mod common;
use axum::http::StatusCode;
use common::*;
use what_core::server::create_router;
#[tokio::test]
async fn form_w_validate_injects_hidden_field() {
let proj = TestProject::new();
proj.add_page(
"form.html",
r#"<form w-validate action="/w-action/users?w-redirect=/form">
<input type="text" name="email" w-required w-type="email">
<input type="submit" value="Submit">
</form>"#,
);
let (_dir, state) = proj.build_state();
let router = create_router(state);
let resp = get(&router, "/form").await;
assert_eq!(resp.status, StatusCode::OK);
resp.assert_contains(r#"name="w-rules""#);
resp.assert_contains(r#"type="hidden""#);
}
#[tokio::test]
async fn form_without_w_validate_no_hidden_field() {
let proj = TestProject::new();
proj.add_page(
"form.html",
r#"<form action="/w-action/users?w-redirect=/form">
<input type="text" name="email" w-required>
<input type="submit" value="Submit">
</form>"#,
);
let (_dir, state) = proj.build_state();
let router = create_router(state);
let resp = get(&router, "/form").await;
assert_eq!(resp.status, StatusCode::OK);
resp.assert_not_contains(r#"name="w-rules""#);
}
#[tokio::test]
async fn validation_redirect_on_failure() {
let proj = TestProject::new();
proj.add_page(
"form.html",
r##"<form w-validate action="/w-action/users?w-redirect=/success">
<input type="text" name="email" w-required w-type="email">
<input type="submit" value="Submit">
</form>
<p>#errors.email|default:"no-error"#</p>"##,
);
proj.add_page("success.html", "<h1>Success</h1>");
let (_dir, state) = proj.build_state();
let router = create_router(state);
let form_resp = get(&router, "/form").await;
let body = &form_resp.body;
let token_start =
body.find(r#"name="w-rules" value=""#).unwrap() + r#"name="w-rules" value=""#.len();
let token_end = body[token_start..].find('"').unwrap() + token_start;
let token = &body[token_start..token_end];
let form_data = format!("email=&w-rules={}", token);
let resp = post_form_with_headers(
&router,
"/w-action/users?w-redirect=/success",
&form_data,
vec![("referer", "/form")],
)
.await;
assert_eq!(resp.status, StatusCode::SEE_OTHER);
assert_eq!(resp.location(), Some("/form"));
}
#[tokio::test]
async fn validation_passes_on_valid_data() {
let proj = TestProject::new();
proj.add_page(
"form.html",
r#"<form w-validate action="/w-action/users?w-redirect=/success">
<input type="text" name="email" w-required w-type="email">
<input type="submit">
</form>"#,
);
proj.add_page("success.html", "<h1>Success</h1>");
let (_dir, state) = proj.build_state();
let router = create_router(state);
let form_resp = get(&router, "/form").await;
let body = &form_resp.body;
let token_start =
body.find(r#"name="w-rules" value=""#).unwrap() + r#"name="w-rules" value=""#.len();
let token_end = body[token_start..].find('"').unwrap() + token_start;
let token = &body[token_start..token_end];
let form_data = format!("email=test@example.com&w-rules={}", token);
let resp = post_form(&router, "/w-action/users?w-redirect=/success", &form_data).await;
assert_eq!(resp.status, StatusCode::SEE_OTHER);
assert_eq!(resp.location(), Some("/success"));
}
#[tokio::test]
async fn validation_errors_in_flash() {
let proj = TestProject::new();
proj.add_page(
"form.html",
r##"<form w-validate action="/w-action/users?w-redirect=/success">
<input type="text" name="name" w-required>
<input type="submit">
</form>
<p>error: #errors.name|default:"none"#</p>
<p>has: #has_errors#</p>"##,
);
let (_dir, state) = proj.build_state();
let router = create_router(state);
let form_resp = get(&router, "/form").await;
let body = &form_resp.body;
let token_start =
body.find(r#"name="w-rules" value=""#).unwrap() + r#"name="w-rules" value=""#.len();
let token_end = body[token_start..].find('"').unwrap() + token_start;
let token = &body[token_start..token_end];
let form_data = format!("name=&w-rules={}", token);
let resp = post_form_with_headers(
&router,
"/w-action/users?w-redirect=/success",
&form_data,
vec![("referer", "/form")],
)
.await;
let cookie = resp.set_cookie().expect("should set session cookie");
let resp = get_with_headers(&router, "/form", vec![("cookie", cookie)]).await;
resp.assert_contains("name is required");
resp.assert_contains("has: true");
}