use axum::{ extract::{Json, State}, http::StatusCode, }; use crate::{push::app::SubscribeError, test::fixtures}; #[tokio::test] async fn accepts_new_subscription() { let app = fixtures::scratch_app().await; let subscriber = fixtures::identity::create(&app, &fixtures::now()).await; // Find out what that VAPID key is. let vapid = fixtures::vapid::key(&app).await; // Create a dummy subscription with that key. let request = super::Request { subscription: super::Subscription { endpoint: String::from("https://push.example.com/endpoint"), keys: super::Keys { p256dh: String::from("test-p256dh-value"), auth: String::from("test-auth-value"), }, }, vapid, }; let response = super::handler(State(app.push()), subscriber, Json(request)) .await .expect("test request will succeed on a fresh app"); // Check that the response looks as expected. assert_eq!(StatusCode::CREATED, response); } #[tokio::test] async fn accepts_repeat_subscription() { let app = fixtures::scratch_app().await; let subscriber = fixtures::identity::create(&app, &fixtures::now()).await; // Find out what that VAPID key is. let vapid = fixtures::vapid::key(&app).await; // Create a dummy subscription with that key. let request = super::Request { subscription: super::Subscription { endpoint: String::from("https://push.example.com/endpoint"), keys: super::Keys { p256dh: String::from("test-p256dh-value"), auth: String::from("test-auth-value"), }, }, vapid, }; let response = super::handler(State(app.push()), subscriber.clone(), Json(request.clone())) .await .expect("test request will succeed on a fresh app"); // Check that the response looks as expected. assert_eq!(StatusCode::CREATED, response); // Repeat the request let response = super::handler(State(app.push()), subscriber, Json(request)) .await .expect("test request will succeed twice on a fresh app"); // Check that the second response also looks as expected. assert_eq!(StatusCode::CREATED, response); } #[tokio::test] async fn rejects_duplicate_subscription() { let app = fixtures::scratch_app().await; let subscriber = fixtures::identity::create(&app, &fixtures::now()).await; // Find out what that VAPID key is. let vapid = fixtures::vapid::key(&app).await; // Create a dummy subscription with that key. let request = super::Request { subscription: super::Subscription { endpoint: String::from("https://push.example.com/endpoint"), keys: super::Keys { p256dh: String::from("test-p256dh-value"), auth: String::from("test-auth-value"), }, }, vapid, }; super::handler(State(app.push()), subscriber.clone(), Json(request)) .await .expect("test request will succeed on a fresh app"); // Repeat the request with different keys let request = super::Request { subscription: super::Subscription { endpoint: String::from("https://push.example.com/endpoint"), keys: super::Keys { p256dh: String::from("different-test-p256dh-value"), auth: String::from("different-test-auth-value"), }, }, vapid, }; let response = super::handler(State(app.push()), subscriber, Json(request)) .await .expect_err("request with duplicate endpoint should fail"); // Make sure we got the error we expected. assert!(matches!(response, super::Error(SubscribeError::Duplicate))); } #[tokio::test] async fn rejects_stale_vapid_key() { let app = fixtures::scratch_app().await; let subscriber = fixtures::identity::create(&app, &fixtures::now()).await; let stale_vapid = fixtures::vapid::key(&app).await; // Change the VAPID key. app.vapid() .revoke_key() .await .expect("key rotation always succeeds"); app.vapid() .refresh_key(&fixtures::now()) .await .expect("refreshing the VAPID key always succeeds"); let fresh_vapid = fixtures::vapid::key(&app).await; // Create a dummy subscription with the original key. let request = super::Request { subscription: super::Subscription { endpoint: String::from("https://push.example.com/endpoint"), keys: super::Keys { p256dh: String::from("test-p256dh-value"), auth: String::from("test-auth-value"), }, }, vapid: stale_vapid, }; let response = super::handler(State(app.push()), subscriber, Json(request)) .await .expect_err("test request has a stale vapid key"); // Check that the response looks as expected. assert!(matches!( response, super::Error(SubscribeError::StaleVapidKey(key)) if key == fresh_vapid )); }