Skip to content

Commit 1cefd8f

Browse files
committed
Update feature to use WPCOM geo public API
1 parent 59782fb commit 1cefd8f

File tree

7 files changed

+23
-180
lines changed

7 files changed

+23
-180
lines changed

Networking/Networking/Remote/IPLocationRemote.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import Foundation
22

3-
/// Remote type to fetch the user's IP Location using a 3rd party API.
3+
/// Remote type to fetch the user's IP Location using the public `geo` API.
44
///
55
public final class IPLocationRemote: Remote {
66

77
/// Fetches the country code from the device ip.
88
///
99
public func getIPCountryCode(onCompletion: @escaping (Result<String, Error>) -> Void) {
10-
guard let url = URL(string: "https://ipinfo.io/json") else {
10+
let path = "geo"
11+
guard let url = URL(string: "\(Settings.wordpressApiBaseURL)/\(path)") else {
1112
return onCompletion(.failure(IPLocationError.malformedURL)) // Should not happen.
1213
}
1314

@@ -33,7 +34,7 @@ private struct IPCountryCodeMapper: Mapper {
3334
///
3435
struct Response: Decodable {
3536
enum CodingKeys: String, CodingKey {
36-
case countryCode = "country"
37+
case countryCode = "country_short"
3738
}
3839

3940
let countryCode: String

Networking/NetworkingTests/Remote/IPLocationRemoteTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ final class IPLocationRemoteTests: XCTestCase {
1616
func test_country_code_is_correctly_parsed() {
1717
// Given
1818
let remote = IPLocationRemote(network: network)
19-
network.simulateResponse(requestUrlSuffix: "json", filename: "ip-location")
19+
network.simulateResponse(requestUrlSuffix: "geo", filename: "ip-location")
2020

2121
// When
2222
let countryCode = waitFor { promise in
Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
{
2-
"ip": "111.111.111.111",
3-
"hostname": "static-adsl190-250-18-50.internet.net.co",
4-
"city": "Medellín",
5-
"region": "Antioquia",
6-
"country": "CO",
7-
"loc": "6.23214,-75.76565",
8-
"org": "AS13489 EPM Telecomunicaciones S.A. E.S.P.",
9-
"postal": "050001",
10-
"timezone": "America/Bogota",
11-
"readme": "https://ipinfo.io/missingauth"
2+
"latitude": "25.77427",
3+
"longitude": "-80.1936",
4+
"country_short": "CO",
5+
"country_long": "United States of America",
6+
"region": "Florida",
7+
"city": "Miami"
128
}

WooCommerce/Classes/ViewRelated/Dashboard/Settings/Privacy/PrivacyBannerPresentationUseCase.swift

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -47,43 +47,9 @@ final class PrivacyBannerPresentationUseCase {
4747
// MARK: Private Helpers
4848
private extension PrivacyBannerPresentationUseCase {
4949

50-
/// Determines the user country code by the following algorithm.
51-
/// - If the user has a WPCOM account:
52-
/// - Use the ip country code.
53-
/// - If the user does not has a WPCOM account:
54-
/// - Use a 3rd party ip country code or current locale country code upon failure.
50+
/// Determines the user country. Relies on the public WordPress API.
5551
///
5652
func fetchUsersCountryCode() async throws -> String {
57-
// Use ip country code for WPCom accounts
58-
if !stores.isAuthenticatedWithoutWPCom {
59-
return try await fetchWPCOMIPCountryCode()
60-
}
61-
62-
// Use 3rd party ip-country code or locale as a fallback.
63-
do {
64-
return try await fetch3rdPartyIPCountryCode()
65-
} catch {
66-
return fetchLocaleCountryCode()
67-
}
68-
}
69-
70-
/// Fetches the ip country code using the Account API.
71-
///
72-
func fetchWPCOMIPCountryCode() async throws -> String {
73-
try await withCheckedThrowingContinuation { continuation in
74-
let action = AccountAction.synchronizeAccount { result in
75-
let ipCountryCodeResult = result.map { $0.ipCountryCode }
76-
continuation.resume(with: ipCountryCodeResult)
77-
}
78-
Task { @MainActor in
79-
stores.dispatch(action)
80-
}
81-
}
82-
}
83-
84-
/// Fetches the ip country code using a 3rd party API.
85-
///
86-
func fetch3rdPartyIPCountryCode() async throws -> String {
8753
try await withCheckedThrowingContinuation { continuation in
8854
let action = UserAction.fetchUserIPCountryCode { result in
8955
continuation.resume(with: result)
@@ -93,12 +59,6 @@ private extension PrivacyBannerPresentationUseCase {
9359
}
9460
}
9561
}
96-
97-
/// Fetches the country code from the current locate.
98-
///
99-
func fetchLocaleCountryCode() -> String {
100-
currentLocale.regionCode ?? ""
101-
}
10262
}
10363

10464
private extension UserDefaults {

WooCommerce/WooCommerceTests/ViewRelated/Settings/Privacy/PrivacyBannerPresentationUseCaseTests.swift

Lines changed: 9 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,18 @@ import TestKit
66

77
final class PrivacyBannerPresentationUseCaseTests: XCTestCase {
88

9-
@MainActor func test_show_banner_is_true_when_WPCOM_user_is_in_EU_and_choices_havent_been_saved() async throws {
9+
@MainActor func test_show_banner_is_true_when_user_is_in_EU_and_choices_havent_been_saved() async throws {
1010
// Given
1111
let defaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
1212
defaults[.hasSavedPrivacyBannerSettings] = false
1313

1414
// Iterate through all of the country codes
1515
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: true))
1616
for euCode in Country.GDPRCountryCodes {
17-
stores.whenReceivingAction(ofType: AccountAction.self) { action in
17+
stores.whenReceivingAction(ofType: UserAction.self) { action in
1818
switch action {
19-
case .synchronizeAccount(let onCompletion):
20-
let account = Account(userID: 123, displayName: "", email: "", username: "", gravatarUrl: "", ipCountryCode: euCode)
21-
onCompletion(.success(account))
19+
case .fetchUserIPCountryCode(let onCompletion):
20+
onCompletion(.success(euCode))
2221
default:
2322
break
2423
}
@@ -33,77 +32,16 @@ final class PrivacyBannerPresentationUseCaseTests: XCTestCase {
3332
}
3433
}
3534

36-
@MainActor func test_show_banner_is_false_when_WPCOM_user_is_outside_of_EU_and_choices_have_not_been_saved() async throws {
35+
@MainActor func test_show_banner_is_false_when_user_is_outside_of_EU_and_choices_have_not_been_saved() async throws {
3736
// Given
3837
let defaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
3938
defaults[.hasSavedPrivacyBannerSettings] = false
4039

4140
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: true))
42-
stores.whenReceivingAction(ofType: AccountAction.self) { action in
43-
switch action {
44-
case .synchronizeAccount(let onCompletion):
45-
let account = Account(userID: 123, displayName: "", email: "", username: "", gravatarUrl: "", ipCountryCode: "US")
46-
onCompletion(.success(account))
47-
default:
48-
break
49-
}
50-
}
51-
52-
// When
53-
let useCase = PrivacyBannerPresentationUseCase(defaults: defaults, stores: stores)
54-
let shouldShowBanner = await useCase.shouldShowPrivacyBanner()
55-
56-
// Then
57-
XCTAssertFalse(shouldShowBanner)
58-
}
59-
60-
@MainActor func test_show_banner_is_false_when_WPCOM_user_is_inside_of_EU_and_choices_have_been_saved() async throws {
61-
// Given
62-
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: true))
63-
let defaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
64-
defaults[.hasSavedPrivacyBannerSettings] = true
65-
66-
// When
67-
let useCase = PrivacyBannerPresentationUseCase(defaults: defaults, stores: stores)
68-
let shouldShowBanner = await useCase.shouldShowPrivacyBanner()
69-
70-
// Then
71-
XCTAssertFalse(shouldShowBanner)
72-
}
73-
74-
@MainActor func test_show_banner_is_true_when_non_WPCOM_is_in_EU_and_choices_have_not_been_saved() async throws {
75-
// Given
76-
let defaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
77-
defaults[.hasSavedPrivacyBannerSettings] = false
78-
79-
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: false))
80-
stores.whenReceivingAction(ofType: UserAction.self) { action in
81-
switch action {
82-
case .fetchUserIPCountryCode(let onCompletion):
83-
onCompletion(.success("GB"))
84-
default:
85-
break
86-
}
87-
}
88-
89-
// When
90-
let useCase = PrivacyBannerPresentationUseCase(defaults: defaults, stores: stores)
91-
let shouldShowBanner = await useCase.shouldShowPrivacyBanner()
92-
93-
// Then
94-
XCTAssertTrue(shouldShowBanner)
95-
}
96-
97-
@MainActor func test_show_banner_is_false_when_non_WPCOM_is_not_in_EU_and_choices_have_not_been_saved() async throws {
98-
// Given
99-
let defaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
100-
defaults[.hasSavedPrivacyBannerSettings] = false
101-
102-
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: false))
10341
stores.whenReceivingAction(ofType: UserAction.self) { action in
10442
switch action {
10543
case .fetchUserIPCountryCode(let onCompletion):
106-
onCompletion(.success("PE"))
44+
onCompletion(.success("US"))
10745
default:
10846
break
10947
}
@@ -117,69 +55,17 @@ final class PrivacyBannerPresentationUseCaseTests: XCTestCase {
11755
XCTAssertFalse(shouldShowBanner)
11856
}
11957

120-
@MainActor func test_show_banner_is_true_when_non_WPCOM_user_has_EU_locale_and_choices_have_not_been_saved() async throws {
121-
// Given
122-
let defaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
123-
defaults[.hasSavedPrivacyBannerSettings] = false
124-
125-
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: false))
126-
stores.whenReceivingAction(ofType: UserAction.self) { action in
127-
switch action {
128-
case .fetchUserIPCountryCode(let onCompletion):
129-
onCompletion(.failure(NSError(domain: "", code: 0)))
130-
default:
131-
break
132-
}
133-
}
134-
135-
// When
136-
let useCase = PrivacyBannerPresentationUseCase(defaults: defaults, stores: stores, currentLocale: .init(identifier: "en_GB"))
137-
let shouldShowBanner = await useCase.shouldShowPrivacyBanner()
138-
139-
// Then
140-
XCTAssertTrue(shouldShowBanner)
141-
}
142-
143-
@MainActor func test_show_banner_is_false_when_non_WPCOM_user_has_none_EU_locale_and_choices_have_not_been_saved() async throws {
144-
// Given
145-
let defaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
146-
defaults[.hasSavedPrivacyBannerSettings] = false
147-
148-
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: false))
149-
stores.whenReceivingAction(ofType: UserAction.self) { action in
150-
switch action {
151-
case .fetchUserIPCountryCode(let onCompletion):
152-
onCompletion(.failure(NSError(domain: "", code: 0)))
153-
default:
154-
break
155-
}
156-
}
157-
158-
// When
159-
let useCase = PrivacyBannerPresentationUseCase(defaults: defaults, stores: stores, currentLocale: .init(identifier: "en_US"))
160-
let shouldShowBanner = await useCase.shouldShowPrivacyBanner()
161-
162-
// Then
163-
XCTAssertFalse(shouldShowBanner)
164-
}
165-
166-
@MainActor func test_show_banner_is_false_when_non_WPCOM_user_has_EU_locale_and_choices_have_been_saved() async throws {
58+
@MainActor func test_show_banner_is_false_when_choices_have_been_saved() async throws {
16759
// Given
60+
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: true))
16861
let defaults = try XCTUnwrap(UserDefaults(suiteName: "TestingSuite"))
16962
defaults[.hasSavedPrivacyBannerSettings] = true
17063

171-
let stores = MockStoresManager(sessionManager: .makeForTesting(authenticated: true, isWPCom: false))
172-
17364
// When
174-
let useCase = PrivacyBannerPresentationUseCase(defaults: defaults, stores: stores, currentLocale: .init(identifier: "en_GB"))
65+
let useCase = PrivacyBannerPresentationUseCase(defaults: defaults, stores: stores)
17566
let shouldShowBanner = await useCase.shouldShowPrivacyBanner()
17667

17768
// Then
17869
XCTAssertFalse(shouldShowBanner)
17970
}
180-
181-
override class func tearDown() {
182-
super.tearDown()
183-
SessionManager.removeTestingDatabase()
184-
}
18571
}

Yosemite/Yosemite/Actions/UserAction.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public enum UserAction: Action {
1111
///
1212
case retrieveUser(siteID: Int64, onCompletion: (Result<User, Error>) -> Void)
1313

14-
/// Fetches the user IP's country code. Uses a 3rd party API to fetch it.
14+
/// Fetches the user IP's country code. Uses the WordPress public API..
1515
///
1616
case fetchUserIPCountryCode(onCompletion: (Result<String, Error>) -> Void)
1717
}

Yosemite/YosemiteTests/Stores/UserStoreTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ final class UserStoreTests: XCTestCase {
7272

7373
func test_get_ip_location_returns_a_success() {
7474
// Given
75-
let urlSuffix = "json"
75+
let urlSuffix = "geo"
7676
network.simulateResponse(requestUrlSuffix: urlSuffix, filename: "ip-location")
7777
let store = UserStore(dispatcher: dispatcher, storageManager: storageManager, network: network)
7878

0 commit comments

Comments
 (0)