in components/push/src/internal/communications.rs [401:577]
fn test_communications() {
viaduct_reqwest::use_reqwest_backend();
// mockito forces task serialization, so for now, we test everything in one go.
let config = PushConfiguration {
http_protocol: Protocol::Http,
server_host: server_address().to_string(),
sender_id: SENDER_ID.to_owned(),
..Default::default()
};
// SUBSCRIPTION with secret
{
let body = json!({
"uaid": DUMMY_UAID,
"channelID": DUMMY_CHID,
"endpoint": "https://example.com/update",
"senderid": SENDER_ID,
"secret": SECRET,
})
.to_string();
let ap_mock = mock("POST", &*format!("/v1/fcm/{}/registration", SENDER_ID))
.with_status(200)
.with_header("content-type", "application/json")
.with_body(body)
.create();
let conn = ConnectHttp::connect(config.clone());
let response = conn.register(SENDER_ID, &None).unwrap();
ap_mock.assert();
assert_eq!(response.uaid, DUMMY_UAID);
}
// Second subscription, after first is send with uaid
{
let body = json!({
"uaid": DUMMY_UAID,
"channelID": DUMMY_CHID,
"endpoint": "https://example.com/update",
"senderid": SENDER_ID,
"secret": SECRET,
})
.to_string();
let ap_mock = mock("POST", &*format!("/v1/fcm/{}/registration", SENDER_ID))
.with_status(200)
.with_header("content-type", "application/json")
.with_body(body)
.create();
let conn = ConnectHttp::connect(config.clone());
let response = conn.register(SENDER_ID, &None).unwrap();
ap_mock.assert();
assert_eq!(response.uaid, DUMMY_UAID);
assert_eq!(response.channel_id, DUMMY_CHID);
assert_eq!(response.endpoint, "https://example.com/update");
let body_2 = json!({
"uaid": DUMMY_UAID,
"channelID": DUMMY_CHID2,
"endpoint": "https://example.com/otherendpoint",
"senderid": SENDER_ID,
"secret": SECRET,
})
.to_string();
let ap_mock_2 = mock(
"POST",
&*format!(
"/v1/fcm/{}/registration/{}/subscription",
SENDER_ID, DUMMY_UAID
),
)
.with_status(200)
.with_header("content-type", "application/json")
.with_body(body_2)
.create();
let response = conn
.subscribe(DUMMY_UAID, SECRET, SENDER_ID, &None)
.unwrap();
ap_mock_2.assert();
assert_eq!(response.endpoint, "https://example.com/otherendpoint");
}
// UNSUBSCRIBE - Single channel
{
let ap_mock = mock(
"DELETE",
&*format!(
"/v1/fcm/{}/registration/{}/subscription/{}",
SENDER_ID, DUMMY_UAID, DUMMY_CHID
),
)
.match_header("authorization", format!("webpush {}", SECRET).as_str())
.with_status(200)
.with_header("content-type", "application/json")
.with_body("{}")
.create();
let conn = ConnectHttp::connect(config.clone());
conn.unsubscribe(DUMMY_CHID, DUMMY_UAID, SECRET).unwrap();
ap_mock.assert();
}
// UNSUBSCRIBE - All for UAID
{
let ap_mock = mock(
"DELETE",
&*format!("/v1/fcm/{}/registration/{}", SENDER_ID, DUMMY_UAID),
)
.match_header("authorization", format!("webpush {}", SECRET).as_str())
.with_status(200)
.with_header("content-type", "application/json")
.with_body("{}")
.create();
let conn = ConnectHttp::connect(config.clone());
conn.unsubscribe_all(DUMMY_UAID, SECRET).unwrap();
ap_mock.assert();
}
// UPDATE
{
let ap_mock = mock(
"PUT",
&*format!("/v1/fcm/{}/registration/{}", SENDER_ID, DUMMY_UAID),
)
.match_header("authorization", format!("webpush {}", SECRET).as_str())
.with_status(200)
.with_header("content-type", "application/json")
.with_body("{}")
.create();
let conn = ConnectHttp::connect(config.clone());
conn.update("NewTokenValue", DUMMY_UAID, SECRET).unwrap();
ap_mock.assert();
}
// CHANNEL LIST
{
let body_cl_success = json!({
"uaid": DUMMY_UAID,
"channelIDs": [DUMMY_CHID],
})
.to_string();
let ap_mock = mock(
"GET",
&*format!("/v1/fcm/{}/registration/{}", SENDER_ID, DUMMY_UAID),
)
.match_header("authorization", format!("webpush {}", SECRET).as_str())
.with_status(200)
.with_header("content-type", "application/json")
.with_body(body_cl_success)
.create();
let conn = ConnectHttp::connect(config);
let response = conn.channel_list(DUMMY_UAID, SECRET).unwrap();
ap_mock.assert();
assert!(response == [DUMMY_CHID.to_owned()]);
}
// we test that we properly return a `AlreadyRegisteredError` when a client
// gets a `CONFLICT` status code
{
let config = PushConfiguration {
http_protocol: Protocol::Http,
server_host: server_address().to_string(),
sender_id: SENDER_ID.to_owned(),
..Default::default()
};
// We mock that the server thinks
// we already registered!
let body = json!({
"code": status_codes::CONFLICT,
"errno": 999u32,
"error": "",
"message": "Already registered"
})
.to_string();
let ap_mock = mock("POST", &*format!("/v1/fcm/{}/registration", SENDER_ID))
.with_status(status_codes::CONFLICT as usize)
.with_header("content-type", "application/json")
.with_body(body)
.create();
let conn = ConnectHttp::connect(config);
let err = conn.register(SENDER_ID, &None).unwrap_err();
ap_mock.assert();
assert!(matches!(err, error::PushError::AlreadyRegisteredError));
}
}