diff options
Diffstat (limited to 'src/push/handlers/subscribe/test.rs')
| -rw-r--r-- | src/push/handlers/subscribe/test.rs | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/src/push/handlers/subscribe/test.rs b/src/push/handlers/subscribe/test.rs new file mode 100644 index 0000000..b72624d --- /dev/null +++ b/src/push/handlers/subscribe/test.rs @@ -0,0 +1,236 @@ +use axum::{ + extract::{Json, State}, + http::StatusCode, +}; + +use crate::{ + push::app::SubscribeError, + test::{fixtures, fixtures::event}, +}; + +#[tokio::test] +async fn accepts_new_subscription() { + let app = fixtures::scratch_app().await; + let subscriber = fixtures::identity::create(&app, &fixtures::now()).await; + + // Issue a VAPID key. + + app.vapid() + .refresh_key(&fixtures::now()) + .await + .expect("refreshing the VAPID key always succeeds"); + + // Find out what that VAPID key is. + + let boot = app.boot().snapshot().await.expect("boot always succeeds"); + let vapid = boot + .events + .into_iter() + .filter_map(event::vapid) + .filter_map(event::vapid::changed) + .next_back() + .expect("the application will have a vapid key after a refresh"); + + // 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: vapid.key, + }; + 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; + + // Issue a VAPID key. + + app.vapid() + .refresh_key(&fixtures::now()) + .await + .expect("refreshing the VAPID key always succeeds"); + + // Find out what that VAPID key is. + + let boot = app.boot().snapshot().await.expect("boot always succeeds"); + let vapid = boot + .events + .into_iter() + .filter_map(event::vapid) + .filter_map(event::vapid::changed) + .next_back() + .expect("the application will have a vapid key after a refresh"); + + // 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: vapid.key, + }; + 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; + + // Issue a VAPID key. + + app.vapid() + .refresh_key(&fixtures::now()) + .await + .expect("refreshing the VAPID key always succeeds"); + + // Find out what that VAPID key is. + + let boot = app.boot().snapshot().await.expect("boot always succeeds"); + let vapid = boot + .events + .into_iter() + .filter_map(event::vapid) + .filter_map(event::vapid::changed) + .next_back() + .expect("the application will have a vapid key after a refresh"); + + // 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: vapid.key, + }; + 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: vapid.key, + }; + 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; + + // Issue a VAPID key. + + app.vapid() + .refresh_key(&fixtures::now()) + .await + .expect("refreshing the VAPID key always succeeds"); + + // Find out what that VAPID key is. + + let boot = app.boot().snapshot().await.expect("boot always succeeds"); + let vapid = boot + .events + .into_iter() + .filter_map(event::vapid) + .filter_map(event::vapid::changed) + .next_back() + .expect("the application will have a vapid key after a refresh"); + + // Change the VAPID key. + + app.vapid() + .rotate_key() + .await + .expect("key rotation always succeeds"); + app.vapid() + .refresh_key(&fixtures::now()) + .await + .expect("refreshing the VAPID key always succeeds"); + + // Find out what the new VAPID key is. + + let boot = app.boot().snapshot().await.expect("boot always succeeds"); + let fresh_vapid = boot + .events + .into_iter() + .filter_map(event::vapid) + .filter_map(event::vapid::changed) + .next_back() + .expect("the application will have a vapid key after a refresh"); + + // 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: vapid.key, + }; + 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.key + )); +} |
