Skip to content

Commit 8abd219

Browse files
authored
Add country field support to subscribers API (#809)
- Add `include` parameter to request country field for subscribers - Make `SubscriberCountry` fields optional to handle API returning false - Add integration test for country field inclusion BREAKING CHANGE: `SubscriberCountry` fields are now optional
1 parent d8acc04 commit 8abd219

File tree

2 files changed

+68
-13
lines changed

2 files changed

+68
-13
lines changed

wp_api/src/wp_com/subscribers.rs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
};
88
use serde::{Deserialize, Serialize};
99
use std::{collections::HashMap, ops::Not};
10-
use wp_serde_helper::deserialize_u64_or_string;
10+
use wp_serde_helper::{deserialize_false_or_string, deserialize_u64_or_string};
1111

1212
#[derive(Debug, Serialize, Deserialize, uniffi::Record)]
1313
pub struct Subscriber {
@@ -74,8 +74,10 @@ pub enum SubscriptionStatus {
7474

7575
#[derive(Debug, Serialize, Deserialize, uniffi::Record)]
7676
pub struct SubscriberCountry {
77-
code: String,
78-
name: String,
77+
#[serde(default, deserialize_with = "deserialize_false_or_string")]
78+
code: Option<String>,
79+
#[serde(default, deserialize_with = "deserialize_false_or_string")]
80+
name: Option<String>,
7981
}
8082

8183
#[derive(Debug, Serialize, Deserialize, uniffi::Record)]
@@ -95,27 +97,30 @@ pub struct SubscriptionPlan {
9597

9698
#[derive(Debug, Default, PartialEq, Eq, uniffi::Record)]
9799
pub struct SubscribersListParams {
98-
// The current page.
100+
/// The current page.
99101
#[uniffi(default = None)]
100102
pub page: Option<u64>,
101-
// The amount of items to show per page.
103+
/// The amount of items to show per page.
102104
#[uniffi(default = None)]
103105
pub per_page: Option<u64>,
104-
// Search for subscribers
106+
/// Search for subscribers
105107
#[uniffi(default = None)]
106108
pub search: Option<String>,
107-
// Sort subscribers by a specific field
109+
/// Sort subscribers by a specific field
108110
#[uniffi(default = None)]
109111
pub sort: Option<ListSubscribersSortField>,
110-
// Sort order
112+
/// Sort order
111113
#[uniffi(default = None)]
112114
pub sort_order: Option<WpApiParamOrder>,
113-
// Filter subscribers by a specific subscriber type
115+
/// Filter subscribers by a specific subscriber type
114116
#[uniffi(default = None)]
115117
pub filter: Option<SubscriberType>,
116-
// Array of filters to apply (combined with AND logic). If provided, overrides the single filter parameter.
118+
/// Array of filters to apply (combined with AND logic). If provided, overrides the single filter parameter.
117119
#[uniffi(default = None)]
118120
pub filters: Option<Vec<SubscriberType>>,
121+
/// An array of additional fields to include
122+
#[uniffi(default = [])]
123+
pub include: Vec<ListSubscribersIncludeField>,
119124
}
120125

121126
impl AppendUrlQueryPairs for SubscribersListParams {
@@ -125,7 +130,8 @@ impl AppendUrlQueryPairs for SubscribersListParams {
125130
.append_option_query_value_pair("per_page", self.per_page.as_ref())
126131
.append_option_query_value_pair("search", self.search.as_ref())
127132
.append_option_query_value_pair("sort", self.sort.as_ref())
128-
.append_option_query_value_pair("sort_order", self.sort_order.as_ref());
133+
.append_option_query_value_pair("sort_order", self.sort_order.as_ref())
134+
.append_vec_query_value_pair("include", self.include.as_ref());
129135

130136
if let Some(filters) = &self.filters {
131137
query_pairs_mut.append_pair(
@@ -165,6 +171,23 @@ pub enum ListSubscribersSortField {
165171

166172
impl_as_query_value_from_to_string!(ListSubscribersSortField);
167173

174+
#[derive(
175+
Debug,
176+
Serialize,
177+
Deserialize,
178+
Eq,
179+
PartialEq,
180+
uniffi::Enum,
181+
strum_macros::EnumString,
182+
strum_macros::Display,
183+
)]
184+
#[strum(serialize_all = "snake_case")]
185+
pub enum ListSubscribersIncludeField {
186+
Country,
187+
}
188+
189+
impl_as_query_value_from_to_string!(ListSubscribersIncludeField);
190+
168191
#[derive(Debug, Serialize, Deserialize, uniffi::Record)]
169192
pub struct ListSubscribersResponse {
170193
pub total: u64,
@@ -396,6 +419,7 @@ mod tests {
396419
sort_order: Some(WpApiParamOrder::Asc),
397420
filter: Some(SubscriberType::All),
398421
filters: Some(vec![SubscriberType::All]),
422+
include: vec![],
399423
};
400424

401425
let mut query_pairs = url.query_pairs_mut();
@@ -421,6 +445,7 @@ mod tests {
421445
sort_order: Some(WpApiParamOrder::Asc),
422446
filter: Some(SubscriberType::EmailSubscriber),
423447
filters: None,
448+
include: vec![],
424449
};
425450

426451
let mut query_pairs = url.query_pairs_mut();

wp_api_integration_tests/tests/test_wp_com_subscribers_immut.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use wp_api::wp_com::{
22
WpComSiteId,
33
subscribers::{
4-
IndividualSubscriberParams, IndividualSubscriberStatsParams, ListSubscribersSortField,
5-
SubscribersListParams, SubscriptionId,
4+
IndividualSubscriberParams, IndividualSubscriberStatsParams, ListSubscribersIncludeField,
5+
ListSubscribersSortField, SubscribersListParams, SubscriptionId,
66
},
77
};
88
use wp_api_integration_tests::{WpComTestCredentials, prelude::*, wp_com_client};
@@ -26,6 +26,36 @@ async fn list_subscribers(#[case] params: SubscribersListParams) {
2626
);
2727
}
2828

29+
#[tokio::test]
30+
#[parallel]
31+
#[ignore]
32+
async fn list_subscribers_include_country() {
33+
let subscribers = wp_com_client()
34+
.subscribers()
35+
.list_subscribers(
36+
&WpComSiteId(WpComTestCredentials::instance().site_id),
37+
&SubscribersListParams {
38+
include: vec![ListSubscribersIncludeField::Country],
39+
..Default::default()
40+
},
41+
)
42+
.await
43+
.assert_response();
44+
assert!(
45+
subscribers.data.total > 0,
46+
"Retrieved no subscribers: {subscribers:#?}"
47+
);
48+
let first_subscriber = subscribers
49+
.data
50+
.subscribers
51+
.first()
52+
.expect("Confirmed that there is at least one subscriber");
53+
assert!(
54+
first_subscriber.country.is_some(),
55+
"'country' field is requested and should be available"
56+
);
57+
}
58+
2959
#[tokio::test]
3060
#[apply(retrieve_cases)]
3161
#[parallel]

0 commit comments

Comments
 (0)