Skip to content

Commit 5e2baf6

Browse files
authored
Add Individual Subscriber Stats Endpoint (#782)
* Adds `/sites/<wp_com_site_id>/individual-subscriber-stats` endpoint * Rename `GetSubscriberQuery` as `GetSubscriberParams` for consistenty
1 parent 4f6e82a commit 5e2baf6

File tree

4 files changed

+73
-16
lines changed

4 files changed

+73
-16
lines changed

wp_api/src/wp_com/endpoint/subscribers.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ use crate::{
33
wp_com::{
44
WpComNamespace, WpComSiteId,
55
subscribers::{
6-
AddSubscribersParams, AddSubscribersResponse, GetSubscriberQuery,
7-
ListSubscribersResponse, Subscriber, SubscriberImportJob,
8-
SubscriberImportJobsListParams, SubscriberStatsResponse, SubscribersListParams,
9-
UploadId,
6+
AddSubscribersParams, AddSubscribersResponse, GetSubscriberParams,
7+
IndividualSubscriberStats, IndividualSubscriberStatsParams, ListSubscribersResponse,
8+
Subscriber, SubscriberImportJob, SubscriberImportJobsListParams,
9+
SubscriberStatsResponse, SubscribersListParams, UploadId,
1010
},
1111
},
1212
};
@@ -16,8 +16,10 @@ use wp_derive_request_builder::WpDerivedRequest;
1616
enum SubscribersRequest {
1717
#[get(url = "/sites/<wp_com_site_id>/subscribers", params = &SubscribersListParams, output = ListSubscribersResponse)]
1818
ListSubscribers,
19-
#[get(url = "/sites/<wp_com_site_id>/subscribers/individual", params = &GetSubscriberQuery, output = Subscriber)]
19+
#[get(url = "/sites/<wp_com_site_id>/subscribers/individual", params = &GetSubscriberParams, output = Subscriber)]
2020
GetSubscriber,
21+
#[get(url = "/sites/<wp_com_site_id>/individual-subscriber-stats", params = &IndividualSubscriberStatsParams, output = IndividualSubscriberStats)]
22+
IndividualSubscriberStats,
2123
#[get(url = "/sites/<wp_com_site_id>/subscribers/import", params = &SubscriberImportJobsListParams, output = Vec<SubscriberImportJob>)]
2224
ListSubscriberImportJobs,
2325
#[get(url = "/sites/<wp_com_site_id>/subscribers/import/<upload_id>", output = SubscriberImportJob)]

wp_api/src/wp_com/subscribers.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,29 +179,50 @@ pub struct ListSubscribersResponse {
179179
// MARK: - Get Subscriber
180180

181181
#[derive(Debug, uniffi::Enum)]
182-
pub enum GetSubscriberQuery {
182+
pub enum GetSubscriberParams {
183183
// Return subscribers that receive notifications via WordPress.com for new posts.
184184
WpCom(UserId),
185185

186186
// Return subscribers that receive notifications via email for new posts.
187187
Email(SubscriptionId),
188188
}
189189

190-
impl AppendUrlQueryPairs for GetSubscriberQuery {
190+
impl AppendUrlQueryPairs for GetSubscriberParams {
191191
fn append_query_pairs(&self, query_pairs_mut: &mut QueryPairs) {
192192
match self {
193-
GetSubscriberQuery::WpCom(user_id) => {
193+
GetSubscriberParams::WpCom(user_id) => {
194194
query_pairs_mut.append_pair("user_id", &user_id.to_string());
195195
query_pairs_mut.append_pair("type", "wpcom");
196196
}
197-
GetSubscriberQuery::Email(email) => {
197+
GetSubscriberParams::Email(email) => {
198198
query_pairs_mut.append_pair("subscription_id", &email.to_string());
199199
query_pairs_mut.append_pair("type", "email");
200200
}
201201
}
202202
}
203203
}
204204

205+
// MARK: - Individual Subscriber Stats
206+
207+
#[derive(Debug, PartialEq, Eq, uniffi::Record)]
208+
pub struct IndividualSubscriberStatsParams {
209+
pub subscription_id: SubscriptionId,
210+
}
211+
212+
impl AppendUrlQueryPairs for IndividualSubscriberStatsParams {
213+
fn append_query_pairs(&self, query_pairs_mut: &mut QueryPairs) {
214+
query_pairs_mut.append_query_value_pair("subscription_id", &self.subscription_id);
215+
}
216+
}
217+
218+
#[derive(Debug, Serialize, Deserialize, uniffi::Record)]
219+
pub struct IndividualSubscriberStats {
220+
emails_sent: u64,
221+
unique_opens: u64,
222+
unique_clicks: u64,
223+
blog_registration_date: String,
224+
}
225+
205226
// MARK: - Add Subscribers
206227

207228
#[derive(Debug, Serialize, Deserialize, Default, uniffi::Record)]
@@ -445,7 +466,7 @@ mod tests {
445466
.expect("Failed to parse url");
446467

447468
let mut query_pairs = url.query_pairs_mut();
448-
GetSubscriberQuery::WpCom(UserId(123)).append_query_pairs(&mut query_pairs);
469+
GetSubscriberParams::WpCom(UserId(123)).append_query_pairs(&mut query_pairs);
449470
assert_eq!(
450471
query_pairs.finish().as_str(),
451472
"https://public-api.wordpress.com/wpcom/v2/sites/1234/subscribers/individual?user_id=123&type=wpcom"
@@ -460,7 +481,7 @@ mod tests {
460481
.expect("Failed to parse url");
461482

462483
let mut query_pairs = url.query_pairs_mut();
463-
GetSubscriberQuery::Email(SubscriptionId(123)).append_query_pairs(&mut query_pairs);
484+
GetSubscriberParams::Email(SubscriptionId(123)).append_query_pairs(&mut query_pairs);
464485
assert_eq!(
465486
query_pairs.finish().as_str(),
466487
"https://public-api.wordpress.com/wpcom/v2/sites/1234/subscribers/individual?subscription_id=123&type=email"
@@ -566,4 +587,13 @@ mod tests {
566587
assert_eq!(plans.len(), 2);
567588
assert_eq!(plans[0].start_date.to_string(), "2025-01-13T18:51:55+00:00");
568589
}
590+
591+
#[test]
592+
fn test_individual_subscriber_stats_response_deserialization() {
593+
let json_file_path = "tests/wpcom/subscribers/individual-subscriber-stats.json";
594+
let file = std::fs::File::open(json_file_path).expect("Failed to open file");
595+
let stats: IndividualSubscriberStats =
596+
serde_json::from_reader(file).expect("Unable to parse JSON");
597+
assert_eq!(stats.emails_sent, 2);
598+
}
569599
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"emails_sent": 2,
3+
"unique_opens": 1,
4+
"unique_clicks": 2,
5+
"blog_registration_date": "2025-01-21 12:14:50"
6+
}

wp_api_integration_tests/tests/test_wp_com_subscribers_immut.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use wp_api::wp_com::{
22
WpComSiteId,
33
subscribers::{
4-
GetSubscriberQuery, ListSubscribersSortField, SubscribersListParams, SubscriptionId,
4+
GetSubscriberParams, IndividualSubscriberStatsParams, ListSubscribersSortField,
5+
SubscribersListParams, SubscriptionId,
56
},
67
};
78
use wp_api_integration_tests::{WpComTestCredentials, prelude::*, wp_com_client};
@@ -30,7 +31,7 @@ async fn list_subscribers(#[case] params: SubscribersListParams) {
3031
#[apply(retrieve_cases)]
3132
#[parallel]
3233
#[ignore]
33-
async fn retrieve_subscriber(#[case] query: GetSubscriberQuery) {
34+
async fn retrieve_subscriber(#[case] query: GetSubscriberParams) {
3435
wp_com_client()
3536
.subscribers()
3637
.get_subscriber(
@@ -41,6 +42,24 @@ async fn retrieve_subscriber(#[case] query: GetSubscriberQuery) {
4142
.assert_response();
4243
}
4344

45+
#[tokio::test]
46+
#[parallel]
47+
#[ignore]
48+
async fn individual_subscriber_stats() {
49+
wp_com_client()
50+
.subscribers()
51+
.individual_subscriber_stats(
52+
&WpComSiteId(WpComTestCredentials::instance().site_id),
53+
&IndividualSubscriberStatsParams {
54+
subscription_id: SubscriptionId(
55+
WpComTestCredentials::instance().email_subscriber_subscription_id,
56+
),
57+
},
58+
)
59+
.await
60+
.assert_response();
61+
}
62+
4463
#[template]
4564
#[rstest]
4665
#[case::default(SubscribersListParams::default())]
@@ -53,8 +72,8 @@ pub fn list_cases(#[case] params: SubscribersListParams) {}
5372

5473
#[template]
5574
#[rstest]
56-
#[case::wp_com_subscriber(GetSubscriberQuery::WpCom(UserId(WpComTestCredentials::instance().wp_com_subscriber_user_id)))]
57-
#[case::email_subscriber(GetSubscriberQuery::Email(SubscriptionId(
75+
#[case::wp_com_subscriber(GetSubscriberParams::WpCom(UserId(WpComTestCredentials::instance().wp_com_subscriber_user_id)))]
76+
#[case::email_subscriber(GetSubscriberParams::Email(SubscriptionId(
5877
WpComTestCredentials::instance().email_subscriber_subscription_id
5978
)))]
60-
pub fn retrieve_cases(#[case] query: GetSubscriberQuery) {}
79+
pub fn retrieve_cases(#[case] query: GetSubscriberParams) {}

0 commit comments

Comments
 (0)