diff --git a/Sources/Misc/PriceFormatterProvider.swift b/Sources/Misc/PriceFormatterProvider.swift index 08e594e512..08138e0ba5 100644 --- a/Sources/Misc/PriceFormatterProvider.swift +++ b/Sources/Misc/PriceFormatterProvider.swift @@ -41,17 +41,20 @@ final class PriceFormatterProvider: Sendable { private let cachedPriceFormatterForSK2: Atomic = nil - func priceFormatterForSK2(withCurrencyCode currencyCode: String) -> NumberFormatter { + func priceFormatterForSK2( + withCurrencyCode currencyCode: String, + locale: Locale = .autoupdatingCurrent + ) -> NumberFormatter { func makePriceFormatterForSK2(with currencyCode: String) -> NumberFormatter { let formatter = NumberFormatter() formatter.numberStyle = .currency - formatter.locale = .autoupdatingCurrent + formatter.locale = locale formatter.currencyCode = currencyCode return formatter } return self.cachedPriceFormatterForSK2.modify { formatter in - guard let formatter = formatter, formatter.currencyCode == currencyCode else { + guard let formatter = formatter, formatter.currencyCode == currencyCode, formatter.locale == locale else { let newFormatter = makePriceFormatterForSK2(with: currencyCode) formatter = newFormatter diff --git a/Sources/Purchasing/StoreKitAbstractions/Test Data/TestStoreProduct.swift b/Sources/Purchasing/StoreKitAbstractions/Test Data/TestStoreProduct.swift index d338a43a33..b39300aed7 100644 --- a/Sources/Purchasing/StoreKitAbstractions/Test Data/TestStoreProduct.swift +++ b/Sources/Purchasing/StoreKitAbstractions/Test Data/TestStoreProduct.swift @@ -59,6 +59,7 @@ public struct TestStoreProduct { public var isFamilyShareable: Bool public var introductoryDiscount: StoreProductDiscount? public var discounts: [StoreProductDiscount] + public var locale: Locale public init( localizedTitle: String, @@ -71,7 +72,8 @@ public struct TestStoreProduct { subscriptionPeriod: SubscriptionPeriod? = nil, isFamilyShareable: Bool = false, introductoryDiscount: TestStoreProductDiscount? = nil, - discounts: [TestStoreProductDiscount] = [] + discounts: [TestStoreProductDiscount] = [], + locale: Locale = .current ) { self.localizedTitle = localizedTitle self.price = price @@ -84,6 +86,7 @@ public struct TestStoreProduct { self.isFamilyShareable = isFamilyShareable self.introductoryDiscount = introductoryDiscount?.toStoreProductDiscount() self.discounts = discounts.map { $0.toStoreProductDiscount() } + self.locale = locale } // swiftlint:enable missing_docs @@ -98,13 +101,12 @@ extension TestStoreProduct: StoreProductType { internal var productCategory: StoreProduct.ProductCategory { return self.productType.productCategory } internal var currencyCode: String? { - // Test currency defaults to current locale - return Locale.current.rc_currencyCode + return self.locale.rc_currencyCode } internal var priceFormatter: NumberFormatter? { return self.currencyCode.map { - self.priceFormatterProvider.priceFormatterForSK2(withCurrencyCode: $0) + self.priceFormatterProvider.priceFormatterForSK2(withCurrencyCode: $0, locale: self.locale) } } diff --git a/Tests/APITesters/SwiftAPITester/SwiftAPITester/TestStoreProductAPI.swift b/Tests/APITesters/SwiftAPITester/SwiftAPITester/TestStoreProductAPI.swift index e8fb5dac22..86ccabf138 100644 --- a/Tests/APITesters/SwiftAPITester/SwiftAPITester/TestStoreProductAPI.swift +++ b/Tests/APITesters/SwiftAPITester/SwiftAPITester/TestStoreProductAPI.swift @@ -24,6 +24,7 @@ func checkTestStoreProductAPI() { let isFamilyShareable: Bool = testProduct.isFamilyShareable let introductoryDiscount: StoreProductDiscount? = testProduct.introductoryDiscount let discounts: [StoreProductDiscount] = testProduct.discounts + let locale: Locale = testProduct.locale // Setters testProduct.localizedTitle = localizedTitle @@ -37,6 +38,7 @@ func checkTestStoreProductAPI() { testProduct.isFamilyShareable = isFamilyShareable testProduct.introductoryDiscount = introductoryDiscount testProduct.discounts = discounts + testProduct.locale = locale let _: StoreProduct = testProduct.toStoreProduct() } @@ -62,6 +64,7 @@ private func checkStoreProductCreation(discount: TestStoreProductDiscount) { subscriptionPeriod: Optional.some(.init(value: 1, unit: .day)), isFamilyShareable: true, introductoryDiscount: Optional.some(discount), - discounts: [discount] + discounts: [discount], + locale: Locale.current ) } diff --git a/Tests/StoreKitUnitTests/StoreProductTests.swift b/Tests/StoreKitUnitTests/StoreProductTests.swift index 16597a178f..be6841be0d 100644 --- a/Tests/StoreKitUnitTests/StoreProductTests.swift +++ b/Tests/StoreKitUnitTests/StoreProductTests.swift @@ -382,10 +382,29 @@ class StoreProductTests: StoreKitConfigTestCase { expect(storeProduct.subscriptionGroupIdentifier) == subscriptionGroup expect(storeProduct.subscriptionPeriod) == period expect(storeProduct.currencyCode) == Locale.current.rc_currencyCode - expect(storeProduct.priceFormatter).toNot(beNil()) + expect(storeProduct.priceFormatter?.locale) == Locale.current + expect(storeProduct.priceFormatter?.currencyCode) == "USD" expect(storeProduct.isFamilyShareable) == isFamilyShareable } + func testTestProductWithCustomLocale() { + let locale: Locale = .init(identifier: "es_ES") + let product = TestStoreProduct( + localizedTitle: "product", + price: 3.99, + localizedPriceString: "$3.99", + productIdentifier: "identifier", + productType: .autoRenewableSubscription, + localizedDescription: "", + locale: locale + ) + let storeProduct = product.toStoreProduct() + + expect(storeProduct.currencyCode) == "EUR" + expect(storeProduct.priceFormatter?.locale) == locale + expect(storeProduct.priceFormatter?.currencyCode) == "EUR" + } + func testWarningLogWhenGettingSK1ProductType() { let product = StoreProduct(sk1Product: .init()) self.logger.verifyMessageWasNotLogged(Strings.storeKit.sk1_no_known_product_type)