diff --git a/wp_api/src/wp_com/domains.rs b/wp_api/src/wp_com/domains.rs index 7a0ece5e0..8432f9a1e 100644 --- a/wp_api/src/wp_com/domains.rs +++ b/wp_api/src/wp_com/domains.rs @@ -1,5 +1,6 @@ use crate::{ decimal2::Decimal2, + impl_as_query_value_for_new_type, url_query::{AppendUrlQueryPairs, QueryPairs, QueryPairsExtension}, wp_com::segments::SegmentId, }; @@ -150,6 +151,134 @@ pub struct DomainPolicyNotice { pub message: String, } +impl_as_query_value_for_new_type!(CountryCode); +uniffi::custom_newtype!(CountryCode, String); +/// ISO 3166-1 alpha-2 country code (e.g. `"US"`, `"CA"`, `"GB"`). +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(transparent)] +pub struct CountryCode(pub String); + +impl std::fmt::Display for CountryCode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl From<&str> for CountryCode { + fn from(s: &str) -> Self { + Self(s.to_string()) + } +} + +/// Structured response from `GET /domains/supported-countries`. +/// +/// The raw API response is a flat array where a sentinel entry (empty +/// `code`/`name`, `has_postal_codes: false`) separates "featured" countries +/// from the full alphabetical list. This type deserializes that array and +/// splits it into two vectors, filtering out the sentinel. +/// +/// If no sentinel is found the full list is placed in `all` and `featured` +/// is empty. +#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)] +#[serde(from = "Vec")] +pub struct SupportedCountries { + /// Countries the API surfaces at the top of the picker, in the API's + /// priority order (not alphabetical). + pub featured: Vec, + /// Every supported country, alphabetized by localized name. + pub all: Vec, +} + +impl From> for SupportedCountries { + fn from(mut entries: Vec) -> Self { + let into_countries = |v: Vec| { + v.into_iter() + .filter_map(|e| match e { + SupportedCountryEntry::Country(c) => Some(c), + SupportedCountryEntry::Divider { .. } => None, + }) + .collect() + }; + + let divider_pos = entries + .iter() + .position(|e| matches!(e, SupportedCountryEntry::Divider { .. })); + + match divider_pos { + Some(pos) => { + let all_entries = entries.split_off(pos + 1); + Self { + featured: into_countries(entries), + all: into_countries(all_entries), + } + } + None => Self { + featured: Vec::new(), + all: into_countries(entries), + }, + } + } +} + +/// Internal type used to deserialize the raw API array which mixes real +/// country entries with sentinel dividers. +#[derive(Debug, Clone, Deserialize)] +#[serde(untagged)] +enum SupportedCountryEntry { + Country(SupportedCountry), + Divider { + #[allow(dead_code)] + code: String, + #[allow(dead_code)] + name: String, + #[allow(dead_code)] + has_postal_codes: bool, + }, +} + +/// A country supported by the WordPress.com domain registration flow. +#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)] +pub struct SupportedCountry { + /// ISO 3166-1 alpha-2 code (e.g. `"US"`). + pub code: CountryCode, + /// Localized country name. + pub name: String, + /// Whether this country uses postal codes in addresses. + pub has_postal_codes: bool, + /// Whether VAT is collected for this country. + pub vat_supported: bool, + /// Whether a city is required in the tax address. + pub tax_needs_city: bool, + /// Whether a subdivision (state/province) is required in the tax address. + pub tax_needs_subdivision: bool, + /// Whether a street address is required for tax purposes. + #[serde(default)] + #[uniffi(default = false)] + pub tax_needs_address: bool, + /// Whether an organization name is required for tax purposes. + #[serde(default)] + #[uniffi(default = false)] + pub tax_needs_organization: bool, + /// Additional country codes whose tax rules apply alongside this one. + #[serde(default)] + #[uniffi(default = [])] + pub tax_country_codes: Vec, + /// Localized tax name (e.g. `"GST"`, `"VAT"`). + pub tax_name: Option, +} + +/// A state, province, or other subdivision within a supported country. +/// +/// Returned from `GET /domains/supported-states/`. Countries +/// without subdivision-level address requirements return an empty array. +#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)] +pub struct SupportedState { + /// Subdivision code (e.g. `"CA"` for California, `"ON"` for Ontario). + pub code: String, + /// Localized subdivision name. + pub name: String, +} + #[cfg(test)] mod tests { use std::fs::File; @@ -288,6 +417,83 @@ mod tests { } } + #[test] + fn test_supported_countries_deserialization() { + let file = File::open("tests/wpcom/domains/supported_countries/all.json") + .expect("Failed to open file"); + let response: SupportedCountries = + serde_json::from_reader(file).expect("Unable to parse JSON"); + + assert_eq!(response.featured.len(), 10); + assert_eq!(response.all.len(), 238); + + // US is in featured and has all optional tax fields populated. + let us = response + .featured + .iter() + .find(|c| c.code.0 == "US") + .expect("US missing from featured"); + assert_eq!(us.name, "United States"); + assert!(us.has_postal_codes); + assert!(!us.vat_supported); + assert!(!us.tax_needs_city); + assert!(!us.tax_needs_subdivision); + + // Brazil has no `tax_country_codes` or `tax_name`. + let br = response + .all + .iter() + .find(|c| c.code.0 == "BR") + .expect("BR missing from all"); + assert!(br.tax_country_codes.is_empty()); + assert_eq!(br.tax_name, None); + + // Australia has `tax_country_codes` and `tax_name`. + let au = response + .all + .iter() + .find(|c| c.code.0 == "AU") + .expect("AU missing from all"); + assert_eq!(au.tax_country_codes, vec![CountryCode::from("AU")]); + assert_eq!(au.tax_name.as_deref(), Some("GST")); + + // The separator entry should be filtered out. + let separator = response + .featured + .iter() + .chain(response.all.iter()) + .find(|c| c.code.0.is_empty()); + assert!(separator.is_none(), "separator should be filtered out"); + } + + #[rstest] + #[case("tests/wpcom/domains/supported_states/us.json", 61)] + #[case("tests/wpcom/domains/supported_states/ca.json", 13)] + #[case("tests/wpcom/domains/supported_states/de.json", 0)] + fn test_supported_states_deserialization( + #[case] json_file_path: &str, + #[case] expected_len: usize, + ) { + let file = File::open(json_file_path).expect("Failed to open file"); + let states: Vec = + serde_json::from_reader(file).expect("Unable to parse JSON"); + assert_eq!(states.len(), expected_len); + states.iter().for_each(|state| { + assert!(!state.code.is_empty()); + assert!(!state.name.is_empty()); + }); + } + + #[test] + fn test_supported_states_deserialization_us_details() { + let file = File::open("tests/wpcom/domains/supported_states/us.json") + .expect("Failed to open file"); + let states: Vec = + serde_json::from_reader(file).expect("Unable to parse JSON"); + let alabama = states.iter().find(|s| s.code == "AL").expect("AL missing"); + assert_eq!(alabama.name, "Alabama"); + } + #[test] fn test_domain_suggestions_deserialization_dot_vendor() { let file = File::open("tests/wpcom/domains/suggestions/dot-vendor.json") diff --git a/wp_api/src/wp_com/endpoint/domains_endpoint.rs b/wp_api/src/wp_com/endpoint/domains_endpoint.rs index f063cde3c..a9b215c2a 100644 --- a/wp_api/src/wp_com/endpoint/domains_endpoint.rs +++ b/wp_api/src/wp_com/endpoint/domains_endpoint.rs @@ -2,7 +2,10 @@ use crate::{ request::endpoint::{AsNamespace, DerivedRequest}, wp_com::{ WpComNamespace, - domains::{DomainSuggestion, DomainSuggestionsParams}, + domains::{ + CountryCode, DomainSuggestion, DomainSuggestionsParams, SupportedCountries, + SupportedState, + }, }, }; use wp_derive_request_builder::WpDerivedRequest; @@ -11,6 +14,10 @@ use wp_derive_request_builder::WpDerivedRequest; enum DomainsRequest { #[get(url = "/domains/suggestions", params = &DomainSuggestionsParams, output = Vec)] Suggestions, + #[get(url = "/domains/supported-countries", output = SupportedCountries)] + SupportedCountries, + #[get(url = "/domains/supported-states/", output = Vec)] + SupportedStates, } impl DerivedRequest for DomainsRequest { @@ -25,6 +32,7 @@ mod tests { use crate::{ request::endpoint::ApiUrlResolver, wp_com::{ + domains::CountryCode, endpoint::tests::{ fixture_wp_com_api_url_resolver, validate_wp_com_rest_v1_1_endpoint, }, @@ -78,6 +86,26 @@ mod tests { validate_wp_com_rest_v1_1_endpoint(endpoint.suggestions(¶ms), expected_path); } + #[rstest] + fn supported_countries(endpoint: DomainsRequestEndpoint) { + validate_wp_com_rest_v1_1_endpoint( + endpoint.supported_countries(), + "/domains/supported-countries", + ); + } + + #[rstest] + #[case::us(CountryCode::from("US"), "/domains/supported-states/US")] + #[case::ca(CountryCode::from("CA"), "/domains/supported-states/CA")] + #[case::gb(CountryCode::from("GB"), "/domains/supported-states/GB")] + fn supported_states( + endpoint: DomainsRequestEndpoint, + #[case] country_code: CountryCode, + #[case] expected_path: &str, + ) { + validate_wp_com_rest_v1_1_endpoint(endpoint.supported_states(&country_code), expected_path); + } + fn base_domain_suggestions_params() -> DomainSuggestionsParams { DomainSuggestionsParams { query: "coolsite".to_string(), diff --git a/wp_api/src/wp_com/segments.rs b/wp_api/src/wp_com/segments.rs index 64d1770b3..c449a35ba 100644 --- a/wp_api/src/wp_com/segments.rs +++ b/wp_api/src/wp_com/segments.rs @@ -48,28 +48,28 @@ mod tests { assert_eq!(segments.len(), 5); - let blog = segments + let unicorn = segments .iter() - .find(|s| s.slug == "blog") - .expect("blog segment missing"); - assert_eq!(blog.id, SegmentId(2)); - assert!(blog.mobile); - assert_eq!(blog.title, "Blog"); + .find(|s| s.slug == "unicorn-ranch") + .expect("unicorn-ranch segment missing"); + assert_eq!(unicorn.id, SegmentId(101)); + assert!(unicorn.mobile); + assert_eq!(unicorn.title, "Unicorn Ranch"); assert_eq!( - blog.subtitle, - "Share and discuss ideas, updates, or creations." + unicorn.subtitle, + "Manage your mythical creature farm online." ); assert_eq!( - blog.icon_url, - "https://s.wp.com/i/mobile_segmentation_icons/monochrome/ic_blogger.png" + unicorn.icon_url, + "https://example.invalid/icons/ic_unicorn.png" ); - assert_eq!(blog.icon_color, "#3d4145"); + assert_eq!(unicorn.icon_color, "#ff00ff"); - let online_store = segments + let bakery = segments .iter() - .find(|s| s.slug == "online-store") - .expect("online-store segment missing"); - assert_eq!(online_store.id, SegmentId(3)); - assert!(!online_store.mobile); + .find(|s| s.slug == "cloud-bakery") + .expect("cloud-bakery segment missing"); + assert_eq!(bakery.id, SegmentId(103)); + assert!(!bakery.mobile); } } diff --git a/wp_api/tests/wpcom/domains/supported_countries/all.json b/wp_api/tests/wpcom/domains/supported_countries/all.json new file mode 100644 index 000000000..9854948e7 --- /dev/null +++ b/wp_api/tests/wpcom/domains/supported_countries/all.json @@ -0,0 +1,2227 @@ +[ + { + "code": "AU", + "name": "Australia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "AU" + ], + "tax_name": "GST" + }, + { + "code": "BR", + "name": "Brazil", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CA", + "name": "Canada", + "has_postal_codes": true, + "tax_needs_city": true, + "tax_needs_subdivision": true, + "vat_supported": false, + "tax_name": "GST" + }, + { + "code": "FR", + "name": "France", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "FR" + ], + "tax_name": "VAT" + }, + { + "code": "DE", + "name": "Germany", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "DE" + ], + "tax_name": "VAT" + }, + { + "code": "IT", + "name": "Italy", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "IT" + ], + "tax_name": "VAT" + }, + { + "code": "ES", + "name": "Spain", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "ES" + ], + "tax_name": "VAT" + }, + { + "code": "SE", + "name": "Sweden", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "SE" + ], + "tax_name": "VAT" + }, + { + "code": "GB", + "name": "United Kingdom", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "GB", + "XI" + ], + "tax_name": "VAT" + }, + { + "code": "US", + "name": "United States", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "", + "name": "", + "has_postal_codes": false + }, + { + "code": "AF", + "name": "Afghanistan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AL", + "name": "Albania", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "DZ", + "name": "Algeria", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AS", + "name": "American Samoa", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AD", + "name": "Andorra", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AO", + "name": "Angola", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AI", + "name": "Anguilla", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AG", + "name": "Antigua & Barbuda", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AR", + "name": "Argentina", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AM", + "name": "Armenia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AW", + "name": "Aruba", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "AU", + "name": "Australia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "AU" + ], + "tax_name": "GST" + }, + { + "code": "AT", + "name": "Austria", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "AT" + ], + "tax_name": "VAT" + }, + { + "code": "AZ", + "name": "Azerbaijan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BS", + "name": "Bahamas", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BH", + "name": "Bahrain", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BD", + "name": "Bangladesh", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BB", + "name": "Barbados", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BY", + "name": "Belarus", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BE", + "name": "Belgium", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "BE" + ], + "tax_name": "VAT" + }, + { + "code": "BZ", + "name": "Belize", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BJ", + "name": "Benin", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BM", + "name": "Bermuda", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BT", + "name": "Bhutan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BO", + "name": "Bolivia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BA", + "name": "Bosnia & Herzegovina", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BW", + "name": "Botswana", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BV", + "name": "Bouvet Island", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BR", + "name": "Brazil", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "IO", + "name": "British Indian Ocean Territory", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "VG", + "name": "British Virgin Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BN", + "name": "Brunei", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BG", + "name": "Bulgaria", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "BG" + ], + "tax_name": "VAT" + }, + { + "code": "BF", + "name": "Burkina Faso", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "BI", + "name": "Burundi", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KH", + "name": "Cambodia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CM", + "name": "Cameroon", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CA", + "name": "Canada", + "has_postal_codes": true, + "tax_needs_city": true, + "tax_needs_subdivision": true, + "vat_supported": false, + "tax_name": "GST" + }, + { + "code": "CV", + "name": "Cape Verde", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KY", + "name": "Cayman Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CF", + "name": "Central African Republic", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TD", + "name": "Chad", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CL", + "name": "Chile", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "CL" + ], + "tax_name": "VAT" + }, + { + "code": "CN", + "name": "China", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CX", + "name": "Christmas Island", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CC", + "name": "Cocos (Keeling) Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CO", + "name": "Colombia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KM", + "name": "Comoros", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CG", + "name": "Congo - Brazzaville", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CD", + "name": "Congo - Kinshasa", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CK", + "name": "Cook Islands", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CR", + "name": "Costa Rica", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CI", + "name": "Côte d’Ivoire", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "HR", + "name": "Croatia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "HR" + ], + "tax_name": "VAT" + }, + { + "code": "CW", + "name": "Curaçao", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CY", + "name": "Cyprus", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "CY" + ], + "tax_name": "VAT" + }, + { + "code": "CZ", + "name": "Czechia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "CZ" + ], + "tax_name": "VAT" + }, + { + "code": "DK", + "name": "Denmark", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "DK" + ], + "tax_name": "VAT" + }, + { + "code": "DJ", + "name": "Djibouti", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "DM", + "name": "Dominica", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "DO", + "name": "Dominican Republic", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "EC", + "name": "Ecuador", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "EG", + "name": "Egypt", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "EG" + ], + "tax_name": "VAT" + }, + { + "code": "SV", + "name": "El Salvador", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GQ", + "name": "Equatorial Guinea", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "ER", + "name": "Eritrea", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "EE", + "name": "Estonia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "EE" + ], + "tax_name": "VAT" + }, + { + "code": "SZ", + "name": "Eswatini", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "ET", + "name": "Ethiopia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "FK", + "name": "Falkland Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "FO", + "name": "Faroe Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "FJ", + "name": "Fiji", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "FI", + "name": "Finland", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "FI" + ], + "tax_name": "VAT" + }, + { + "code": "FR", + "name": "France", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "FR" + ], + "tax_name": "VAT" + }, + { + "code": "GF", + "name": "French Guiana", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PF", + "name": "French Polynesia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TF", + "name": "French Southern Territories", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GA", + "name": "Gabon", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GM", + "name": "Gambia", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GE", + "name": "Georgia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "DE", + "name": "Germany", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "DE" + ], + "tax_name": "VAT" + }, + { + "code": "GH", + "name": "Ghana", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GI", + "name": "Gibraltar", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GR", + "name": "Greece", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "EL" + ], + "tax_name": "VAT" + }, + { + "code": "GL", + "name": "Greenland", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GD", + "name": "Grenada", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GP", + "name": "Guadeloupe", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GU", + "name": "Guam", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GT", + "name": "Guatemala", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GG", + "name": "Guernsey", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GN", + "name": "Guinea", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GW", + "name": "Guinea-Bissau", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "GY", + "name": "Guyana", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "HT", + "name": "Haiti", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "HM", + "name": "Heard & McDonald Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "HN", + "name": "Honduras", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "HK", + "name": "Hong Kong SAR China", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "HU", + "name": "Hungary", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "HU" + ], + "tax_name": "VAT" + }, + { + "code": "IS", + "name": "Iceland", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "IS" + ], + "tax_name": "VAT" + }, + { + "code": "IN", + "name": "India", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": true, + "vat_supported": true, + "tax_country_codes": [ + "IN" + ], + "tax_name": "GST" + }, + { + "code": "ID", + "name": "Indonesia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "ID" + ], + "tax_name": "VAT" + }, + { + "code": "IQ", + "name": "Iraq", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "IE", + "name": "Ireland", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "IE" + ], + "tax_name": "VAT" + }, + { + "code": "IM", + "name": "Isle of Man", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "IL", + "name": "Israel", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "IT", + "name": "Italy", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "IT" + ], + "tax_name": "VAT" + }, + { + "code": "JM", + "name": "Jamaica", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "JP", + "name": "Japan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "tax_needs_organization": true, + "vat_supported": true, + "tax_country_codes": [ + "JP" + ], + "tax_name": "CT" + }, + { + "code": "JE", + "name": "Jersey", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "JO", + "name": "Jordan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KZ", + "name": "Kazakhstan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KE", + "name": "Kenya", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "KE" + ], + "tax_name": "VAT" + }, + { + "code": "KI", + "name": "Kiribati", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KW", + "name": "Kuwait", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KG", + "name": "Kyrgyzstan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "LA", + "name": "Laos", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "LV", + "name": "Latvia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "LV" + ], + "tax_name": "VAT" + }, + { + "code": "LB", + "name": "Lebanon", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "LS", + "name": "Lesotho", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "LR", + "name": "Liberia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "LY", + "name": "Libya", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "LI", + "name": "Liechtenstein", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "LT", + "name": "Lithuania", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "LT" + ], + "tax_name": "VAT" + }, + { + "code": "LU", + "name": "Luxembourg", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "LU" + ], + "tax_name": "VAT" + }, + { + "code": "MO", + "name": "Macao SAR China", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MG", + "name": "Madagascar", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MW", + "name": "Malawi", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MY", + "name": "Malaysia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "MY" + ], + "tax_name": "SST" + }, + { + "code": "MV", + "name": "Maldives", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "ML", + "name": "Mali", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MT", + "name": "Malta", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "MT" + ], + "tax_name": "VAT" + }, + { + "code": "MH", + "name": "Marshall Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MQ", + "name": "Martinique", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MR", + "name": "Mauritania", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MU", + "name": "Mauritius", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "YT", + "name": "Mayotte", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MX", + "name": "Mexico", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "MX" + ], + "tax_name": "VAT" + }, + { + "code": "FM", + "name": "Micronesia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MD", + "name": "Moldova", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MC", + "name": "Monaco", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MN", + "name": "Mongolia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "ME", + "name": "Montenegro", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MS", + "name": "Montserrat", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MA", + "name": "Morocco", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MZ", + "name": "Mozambique", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MM", + "name": "Myanmar (Burma)", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NA", + "name": "Namibia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NR", + "name": "Nauru", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NP", + "name": "Nepal", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NL", + "name": "Netherlands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "NL" + ], + "tax_name": "VAT" + }, + { + "code": "NC", + "name": "New Caledonia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NZ", + "name": "New Zealand", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "NZ" + ], + "tax_name": "GST" + }, + { + "code": "NI", + "name": "Nicaragua", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NE", + "name": "Niger", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NG", + "name": "Nigeria", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NU", + "name": "Niue", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NF", + "name": "Norfolk Island", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MK", + "name": "North Macedonia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "MP", + "name": "Northern Mariana Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "NO", + "name": "Norway", + "has_postal_codes": true, + "tax_needs_city": true, + "tax_needs_subdivision": false, + "tax_needs_organization": true, + "vat_supported": true, + "tax_country_codes": [ + "NO" + ], + "tax_name": "VAT" + }, + { + "code": "OM", + "name": "Oman", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PK", + "name": "Pakistan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PW", + "name": "Palau", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PS", + "name": "Palestinian Territories", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PA", + "name": "Panama", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PG", + "name": "Papua New Guinea", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PY", + "name": "Paraguay", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PE", + "name": "Peru", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PH", + "name": "Philippines", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PN", + "name": "Pitcairn Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PL", + "name": "Poland", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "PL" + ], + "tax_name": "VAT" + }, + { + "code": "PT", + "name": "Portugal", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "PT" + ], + "tax_name": "VAT" + }, + { + "code": "PR", + "name": "Puerto Rico", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "QA", + "name": "Qatar", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "RE", + "name": "Réunion", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "RO", + "name": "Romania", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "RO" + ], + "tax_name": "VAT" + }, + { + "code": "RU", + "name": "Russia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "RU" + ], + "tax_name": "VAT" + }, + { + "code": "RW", + "name": "Rwanda", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "WS", + "name": "Samoa", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SM", + "name": "San Marino", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "ST", + "name": "São Tomé & Príncipe", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "CQ", + "name": "Sark", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SA", + "name": "Saudi Arabia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "SA" + ], + "tax_name": "VAT" + }, + { + "code": "SN", + "name": "Senegal", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "RS", + "name": "Serbia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SC", + "name": "Seychelles", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SL", + "name": "Sierra Leone", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SG", + "name": "Singapore", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "SG" + ], + "tax_name": "GST" + }, + { + "code": "SX", + "name": "Sint Maarten", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SK", + "name": "Slovakia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "SK" + ], + "tax_name": "VAT" + }, + { + "code": "SI", + "name": "Slovenia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "SI" + ], + "tax_name": "VAT" + }, + { + "code": "SB", + "name": "Solomon Islands", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SO", + "name": "Somalia", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "ZA", + "name": "South Africa", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "ZA" + ], + "tax_name": "VAT" + }, + { + "code": "GS", + "name": "South Georgia & South Sandwich Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KR", + "name": "South Korea", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "KR" + ], + "tax_name": "VAT" + }, + { + "code": "ES", + "name": "Spain", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "ES" + ], + "tax_name": "VAT" + }, + { + "code": "LK", + "name": "Sri Lanka", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SH", + "name": "St. Helena", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "KN", + "name": "St. Kitts & Nevis", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "LC", + "name": "St. Lucia", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "PM", + "name": "St. Pierre & Miquelon", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "VC", + "name": "St. Vincent & Grenadines", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SR", + "name": "Suriname", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "SE", + "name": "Sweden", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "SE" + ], + "tax_name": "VAT" + }, + { + "code": "CH", + "name": "Switzerland", + "has_postal_codes": true, + "tax_needs_city": true, + "tax_needs_subdivision": false, + "tax_needs_address": true, + "vat_supported": true, + "tax_country_codes": [ + "CH" + ], + "tax_name": "VAT" + }, + { + "code": "TW", + "name": "Taiwan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "TW" + ], + "tax_name": "VAT" + }, + { + "code": "TJ", + "name": "Tajikistan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TZ", + "name": "Tanzania", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TH", + "name": "Thailand", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "TH" + ], + "tax_name": "VAT" + }, + { + "code": "TL", + "name": "Timor-Leste", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TG", + "name": "Togo", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TK", + "name": "Tokelau", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TO", + "name": "Tonga", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TT", + "name": "Trinidad & Tobago", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TN", + "name": "Tunisia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TR", + "name": "Türkiye", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "TR" + ], + "tax_name": "VAT" + }, + { + "code": "TM", + "name": "Turkmenistan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TC", + "name": "Turks & Caicos Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "TV", + "name": "Tuvalu", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "UM", + "name": "U.S. Outlying Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "VI", + "name": "U.S. Virgin Islands", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "UG", + "name": "Uganda", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "UA", + "name": "Ukraine", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "UA" + ], + "tax_name": "VAT" + }, + { + "code": "AE", + "name": "United Arab Emirates", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false, + "tax_name": "VAT" + }, + { + "code": "GB", + "name": "United Kingdom", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": true, + "tax_country_codes": [ + "GB", + "XI" + ], + "tax_name": "VAT" + }, + { + "code": "US", + "name": "United States", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "UY", + "name": "Uruguay", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "UZ", + "name": "Uzbekistan", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "VU", + "name": "Vanuatu", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "VA", + "name": "Vatican City", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "VE", + "name": "Venezuela", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "VN", + "name": "Vietnam", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "WF", + "name": "Wallis & Futuna", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "EH", + "name": "Western Sahara", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "YE", + "name": "Yemen", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "ZM", + "name": "Zambia", + "has_postal_codes": true, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + }, + { + "code": "ZW", + "name": "Zimbabwe", + "has_postal_codes": false, + "tax_needs_city": false, + "tax_needs_subdivision": false, + "vat_supported": false + } +] diff --git a/wp_api/tests/wpcom/domains/supported_states/ca.json b/wp_api/tests/wpcom/domains/supported_states/ca.json new file mode 100644 index 000000000..c2a4123ba --- /dev/null +++ b/wp_api/tests/wpcom/domains/supported_states/ca.json @@ -0,0 +1,54 @@ +[ + { + "code": "AB", + "name": "Alberta" + }, + { + "code": "BC", + "name": "British Columbia" + }, + { + "code": "MB", + "name": "Manitoba" + }, + { + "code": "NB", + "name": "New Brunswick" + }, + { + "code": "NL", + "name": "Newfoundland" + }, + { + "code": "NT", + "name": "Northwest Territories" + }, + { + "code": "NS", + "name": "Nova Scotia" + }, + { + "code": "NU", + "name": "Nunavut" + }, + { + "code": "ON", + "name": "Ontario" + }, + { + "code": "PE", + "name": "Prince Edward Island" + }, + { + "code": "QC", + "name": "Quebec" + }, + { + "code": "SK", + "name": "Saskatchewan" + }, + { + "code": "YT", + "name": "Yukon Territory" + } +] diff --git a/wp_api/tests/wpcom/domains/supported_states/de.json b/wp_api/tests/wpcom/domains/supported_states/de.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/wp_api/tests/wpcom/domains/supported_states/de.json @@ -0,0 +1 @@ +[] diff --git a/wp_api/tests/wpcom/domains/supported_states/us.json b/wp_api/tests/wpcom/domains/supported_states/us.json new file mode 100644 index 000000000..14566067a --- /dev/null +++ b/wp_api/tests/wpcom/domains/supported_states/us.json @@ -0,0 +1,246 @@ +[ + { + "code": "AL", + "name": "Alabama" + }, + { + "code": "AK", + "name": "Alaska" + }, + { + "code": "AS", + "name": "American Samoa" + }, + { + "code": "AZ", + "name": "Arizona" + }, + { + "code": "AR", + "name": "Arkansas" + }, + { + "code": "AA", + "name": "Armed Forces America" + }, + { + "code": "AE", + "name": "Armed Forces Other Areas" + }, + { + "code": "AP", + "name": "Armed Forces Pacific" + }, + { + "code": "CA", + "name": "California" + }, + { + "code": "CO", + "name": "Colorado" + }, + { + "code": "CT", + "name": "Connecticut" + }, + { + "code": "DE", + "name": "Delaware" + }, + { + "code": "DC", + "name": "District of Columbia" + }, + { + "code": "FM", + "name": "Federated States of Micronesia" + }, + { + "code": "FL", + "name": "Florida" + }, + { + "code": "GA", + "name": "Georgia" + }, + { + "code": "GU", + "name": "Guam" + }, + { + "code": "HI", + "name": "Hawaii" + }, + { + "code": "ID", + "name": "Idaho" + }, + { + "code": "IL", + "name": "Illinois" + }, + { + "code": "IN", + "name": "Indiana" + }, + { + "code": "IA", + "name": "Iowa" + }, + { + "code": "KS", + "name": "Kansas" + }, + { + "code": "KY", + "name": "Kentucky" + }, + { + "code": "LA", + "name": "Louisiana" + }, + { + "code": "ME", + "name": "Maine" + }, + { + "code": "MH", + "name": "Marshall Islands" + }, + { + "code": "MD", + "name": "Maryland" + }, + { + "code": "MA", + "name": "Massachusetts" + }, + { + "code": "MI", + "name": "Michigan" + }, + { + "code": "MN", + "name": "Minnesota" + }, + { + "code": "MS", + "name": "Mississippi" + }, + { + "code": "MO", + "name": "Missouri" + }, + { + "code": "MT", + "name": "Montana" + }, + { + "code": "NE", + "name": "Nebraska" + }, + { + "code": "NV", + "name": "Nevada" + }, + { + "code": "NH", + "name": "New Hampshire" + }, + { + "code": "NJ", + "name": "New Jersey" + }, + { + "code": "NM", + "name": "New Mexico" + }, + { + "code": "NY", + "name": "New York" + }, + { + "code": "NC", + "name": "North Carolina" + }, + { + "code": "ND", + "name": "North Dakota" + }, + { + "code": "MP", + "name": "Northern Mariana Islands" + }, + { + "code": "OH", + "name": "Ohio" + }, + { + "code": "OK", + "name": "Oklahoma" + }, + { + "code": "OR", + "name": "Oregon" + }, + { + "code": "PW", + "name": "Palau" + }, + { + "code": "PA", + "name": "Pennsylvania" + }, + { + "code": "PR", + "name": "Puerto Rico" + }, + { + "code": "RI", + "name": "Rhode Island" + }, + { + "code": "SC", + "name": "South Carolina" + }, + { + "code": "SD", + "name": "South Dakota" + }, + { + "code": "TN", + "name": "Tennessee" + }, + { + "code": "TX", + "name": "Texas" + }, + { + "code": "UT", + "name": "Utah" + }, + { + "code": "VT", + "name": "Vermont" + }, + { + "code": "VA", + "name": "Virginia" + }, + { + "code": "WA", + "name": "Washington" + }, + { + "code": "WV", + "name": "West Virginia" + }, + { + "code": "WI", + "name": "Wisconsin" + }, + { + "code": "WY", + "name": "Wyoming" + } +] diff --git a/wp_api/tests/wpcom/segments/all.json b/wp_api/tests/wpcom/segments/all.json index f4359ec36..5be3c5097 100644 --- a/wp_api/tests/wpcom/segments/all.json +++ b/wp_api/tests/wpcom/segments/all.json @@ -1,47 +1,47 @@ [ { - "id": 2, - "slug": "blog", + "id": 101, + "slug": "unicorn-ranch", "mobile": true, - "segment_type_title": "Blog", - "segment_type_subtitle": "Share and discuss ideas, updates, or creations.", - "icon_URL": "https://s.wp.com/i/mobile_segmentation_icons/monochrome/ic_blogger.png", - "icon_color": "#3d4145" + "segment_type_title": "Unicorn Ranch", + "segment_type_subtitle": "Manage your mythical creature farm online.", + "icon_URL": "https://example.invalid/icons/ic_unicorn.png", + "icon_color": "#ff00ff" }, { - "id": 1, - "slug": "business", + "id": 102, + "slug": "time-travel-agency", "mobile": true, - "segment_type_title": "Business", - "segment_type_subtitle": "Promote products and services.", - "icon_URL": "https://s.wp.com/i/mobile_segmentation_icons/monochrome/ic_business.png", - "icon_color": "#3d4145" + "segment_type_title": "Time Travel Agency", + "segment_type_subtitle": "Book trips to the past and future.", + "icon_URL": "https://example.invalid/icons/ic_time_travel.png", + "icon_color": "#00ff00" }, { - "id": 3, - "slug": "online-store", + "id": 103, + "slug": "cloud-bakery", "mobile": false, - "segment_type_title": "Online store", - "segment_type_subtitle": "Sell your collection of products online.", - "icon_URL": "https://s.wp.com/i/mobile_segmentation_icons/monochrome/ic_store.png", - "icon_color": "#3d4145" + "segment_type_title": "Cloud Bakery", + "segment_type_subtitle": "Sell pastries made from actual clouds.", + "icon_URL": "https://example.invalid/icons/ic_cloud_bakery.png", + "icon_color": "#0000ff" }, { - "id": 4, - "slug": "professional", + "id": 104, + "slug": "dragon-daycare", "mobile": true, - "segment_type_title": "Professional", - "segment_type_subtitle": "Showcase your portfolio, skills or work.", - "icon_URL": "https://s.wp.com/i/mobile_segmentation_icons/monochrome/ic_professional.png", - "icon_color": "#3d4145" + "segment_type_title": "Dragon Daycare", + "segment_type_subtitle": "Professional dragon sitting services.", + "icon_URL": "https://example.invalid/icons/ic_dragon.png", + "icon_color": "#ff0000" }, { - "id": 6, - "slug": "blank-canvas", + "id": 105, + "slug": "blank-scroll", "mobile": true, - "segment_type_title": "Blank Canvas", - "segment_type_subtitle": "Start with a blank site.", - "icon_URL": "https://s.wp.com/i/mobile_segmentation_icons/monochrome/ic_blank_canvas.png", - "icon_color": "#3d4145" + "segment_type_title": "Blank Scroll", + "segment_type_subtitle": "Start with an empty enchanted scroll.", + "icon_URL": "https://example.invalid/icons/ic_scroll.png", + "icon_color": "#abcdef" } ] diff --git a/wp_com_e2e/src/domains_tests.rs b/wp_com_e2e/src/domains_tests.rs new file mode 100644 index 000000000..5adc0b529 --- /dev/null +++ b/wp_com_e2e/src/domains_tests.rs @@ -0,0 +1,87 @@ +use crate::context::TestContext; +use libtest_mimic::Trial; +use std::sync::Arc; +use wp_api::wp_com::domains::CountryCode; + +pub fn tests(ctx: Arc) -> Vec { + let mut trials = vec![]; + + trials.push(Trial::test("domains::supported_countries", { + let ctx = Arc::clone(&ctx); + move || { + ctx.runtime.block_on(async { + let response = ctx + .client + .domains() + .supported_countries() + .await + .map_err(|e| e.to_string())? + .data; + + if response.all.is_empty() { + return Err("expected non-empty `all` countries list".into()); + } + + // Verify no separator entries leaked through. + let has_separator = response + .featured + .iter() + .chain(response.all.iter()) + .any(|c| c.code.0.is_empty()); + if has_separator { + return Err("separator entry should be filtered out".into()); + } + + Ok(()) + }) + } + })); + + trials.push(Trial::test("domains::supported_states_us", { + let ctx = Arc::clone(&ctx); + move || { + ctx.runtime.block_on(async { + let states = ctx + .client + .domains() + .supported_states(&CountryCode::from("US")) + .await + .map_err(|e| e.to_string())? + .data; + + if states.is_empty() { + return Err("expected non-empty states list for US".into()); + } + + Ok(()) + }) + } + })); + + trials.push(Trial::test("domains::supported_states_empty", { + let ctx = Arc::clone(&ctx); + move || { + ctx.runtime.block_on(async { + let states = ctx + .client + .domains() + .supported_states(&CountryCode::from("DE")) + .await + .map_err(|e| e.to_string())? + .data; + + if !states.is_empty() { + return Err(format!( + "expected empty states list for DE, got {} entries", + states.len() + ) + .into()); + } + + Ok(()) + }) + } + })); + + trials +} diff --git a/wp_com_e2e/src/main.rs b/wp_com_e2e/src/main.rs index a02050736..06960e305 100644 --- a/wp_com_e2e/src/main.rs +++ b/wp_com_e2e/src/main.rs @@ -5,6 +5,7 @@ use std::sync::Arc; mod api_root_tests; mod context; +mod domains_tests; mod languages_tests; mod me_tests; mod sites_tests; @@ -48,6 +49,7 @@ fn main() { fn collect_tests(ctx: Arc) -> Vec { let mut tests = vec![]; tests.extend(api_root_tests::tests(Arc::clone(&ctx))); + tests.extend(domains_tests::tests(Arc::clone(&ctx))); tests.extend(languages_tests::tests(Arc::clone(&ctx))); tests.extend(me_tests::tests(Arc::clone(&ctx))); tests.extend(stats_city_views_tests::tests(Arc::clone(&ctx)));