Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plus): user subscription transitions #421

Merged
merged 12 commits into from
Feb 21, 2024
Merged
12 changes: 11 additions & 1 deletion src/db/fxa_webhook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ pub async fn update_subscription_state_from_webhook(
status: FxaEventStatus::Pending,
payload: serde_json::value::to_value(&update).unwrap(),
};
debug!("Got subscription state change event: {:?}", update);

if let Some(user) = user {
let ignore = schema::webhook_events::table
Expand Down Expand Up @@ -239,7 +240,16 @@ pub async fn update_subscription_state_from_webhook(
// Record the subscription state change in its table.
let old_subscription = user.get_subscription_type();
if let Some(old_subscription) = old_subscription {
// We have the user id, the old and new subscription, store it.
// Do not record transitions that are not transitioning anything.
// This can happen if the user cancels, but their subscription
// has some time left (monthly/yearly subscription).
// When the subscription actually ends, the system will send us a
// new event.
if old_subscription == subscription {
return Ok(());
}
// We have the user id, the old and new subscription,
// they are different, so go ahead storing it.
let subscription_change = SubscriptionChangeInsert {
user_id: user.id,
old_subscription_type: old_subscription,
Expand Down
35 changes: 35 additions & 0 deletions tests/api/fxa_webhooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,41 @@ async fn record_subscription_state_transitions_test() -> Result<(), Error> {
);
}

// Now, reate an event where the new subscription is matching the old one.
// We do not record those.
{
let json_str = std::fs::read_to_string(
"tests/data/set_tokens/set_token_subscription_state_change_to_10m.json",
)
.unwrap();
let mut claim: Value = serde_json::from_str(&json_str).unwrap();
// Add some time to the event to be sure it is after the previous event.
claim["iat"] = json!(1654425317000i64 + 600000);
claim["events"]["https://schemas.accounts.firefox.com/event/subscription-state-change"]
["changeTime"] = json!(1654425317000i64 + 600000);
// We also add some unknown capability to the event to check that they are ignored correctly.
claim["events"]["https://schemas.accounts.firefox.com/event/subscription-state-change"]
["capabilities"] = json!(["mdn_plus_10m"]);
let set_token = token_from_claim(&claim);

let res = logged_in_client.trigger_webhook(&set_token).await;
assert!(res.response().status().is_success());

// check the transition is not recorded
let transitions = schema::user_subscription_transitions::table
.order(schema::user_subscription_transitions::created_at)
.load::<SubscriptionChangeQuery>(&mut conn)?;
assert_eq!(transitions.len(), 2);
assert_eq!(
transitions[0].created_at,
NaiveDateTime::from_timestamp_opt(1654425317, 0).unwrap()
);
assert_eq!(
transitions[1].created_at,
NaiveDateTime::from_timestamp_opt(1654425617, 0).unwrap()
);
}

drop_stubr(stubr).await;
Ok(())
}
Loading