Skip to content

Commit

Permalink
[PAY-2055] Project Currency Country Code Display Error (#1754) (#1756)
Browse files Browse the repository at this point in the history
* added a project currency, oddly build is crashing when opening a project, but unrelated to any new code.

* removed extaneous currency field from top level project and used existing stats field.

* fixed incorrect parameter build issue

* fixed extra parameter in lenses

* removed unused line

* corrected display issues for rewards and reward addons.

* reverting spacing in ProjectLenses, unneeded change, cluttering pr

* more ProjectLenses updated

* bonus support currency fix on pledge page.

* updated a shared function of min max pledge amount to use the project's currency country instead of project country.

* updated Apple Pay request currency code to be from project currency first, then project country currency. Also updated the supported networks of apple pay to be based on project currency country instead of project country

* updated analytics to come from the project currency country not project country

* updated summary view, apple pay alert, and expandable rewards header (spacing) to use project currency country first then project country

* total values for pledge summary view using project currency country before project country

* handled logged currency display scenarios (manage pledge flow)

* formatting

* fixed currency issue when user logged in and about to manage pledge, fetch backing doesn't update the chosen currency in the project.

* added view model tests

* more view model tests

* project summary view model tests

* pledge view model and project page view model tests

* project page snapshot tests added, existing project lense hadn't accounted for extended project properties, now it does.

* pr comments.

Co-authored-by: Mubarak Sadoon <msadoon@gmail.com>
  • Loading branch information
scottkicks and msadoon committed Nov 22, 2022
1 parent d3eb050 commit d2360b0
Show file tree
Hide file tree
Showing 86 changed files with 1,423 additions and 345 deletions.
Expand Up @@ -23,7 +23,6 @@ final class CancelPledgeViewControllerTests: TestCase {

let data = CancelPledgeViewData(
project: project,
projectCountry: project.country,
projectName: project.name,
omitUSCurrencyCode: project.stats.omitUSCurrencyCode,
backingId: String(project.personalization.backing?.id ?? 0),
Expand Down
Expand Up @@ -48,9 +48,26 @@ final class PledgeAmountViewControllerTests: TestCase {
}
}

func testView_ShowsCurrencySymbol() {
func testView_ShowsCurrencySymbol_NonUS_ProjectCurrency_US_ProjectCountry() {
let project = Project.template
|> Project.lens.country .~ Project.Country.ca
|> Project.lens.country .~ Project.Country.us
|> Project.lens.stats.currency .~ Project.Country.ca.currencyCode

[Device.phone4_7inch, Device.pad].forEach { device in
let controller = PledgeAmountViewController.instantiate()
let (parent, _) = traitControllers(device: device, orientation: .portrait, child: controller)
parent.view.frame.size.height = regularHeight

controller.configureWith(value: (project: project, reward: .template, 0))

FBSnapshotVerifyView(parent.view, identifier: "device_\(device)")
}
}

func testView_ShowsCurrencySymbol_US_ProjectCurrency_US_ProjectCountry() {
let project = Project.template
|> Project.lens.country .~ Project.Country.us
|> Project.lens.stats.currency .~ Project.Country.us.currencyCode

[Device.phone4_7inch, Device.pad].forEach { device in
let controller = PledgeAmountViewController.instantiate()
Expand Down
Expand Up @@ -101,7 +101,7 @@ internal final class ProjectPageViewControllerTests: TestCase {
fetchProjectRewardsResult: .success([reward])
)

combos(Language.allLanguages, [Device.phone4inch, Device.pad]).forEach { language, device in
combos([Language.en], [Device.phone4inch]).forEach { language, device in
withEnvironment(
apiService: mockService,
config: config, currentUser: .template, language: language
Expand Down Expand Up @@ -474,6 +474,198 @@ internal final class ProjectPageViewControllerTests: TestCase {
}
}

func testLoggedIn_Backer_LiveProject_NonUS_ProjectCurrency_US_ProjectCountry_US_UserChosenCurrency_Success() {
let config = Config.template
let reward = Reward.template
|> Reward.lens.title .~ "Magic Lamp"
let project = Project.cosmicSurgery
|> Project.lens.stats.currency .~ Project.Country.mx.currencyCode
|> Project.lens.country .~ Project.Country.us
|> Project.lens.stats.currentCurrency .~ Project.Country.us.currencyCode
|> Project.lens.photo.full .~ ""
|> (Project.lens.creator.avatar .. User.Avatar.lens.small) .~ ""
|> Project.lens.personalization.isBacking .~ false
|> Project.lens.personalization.backing .~ nil
|> Project.lens.state .~ .live
|> Project.lens.stats.convertedPledgedAmount .~ 29_236
|> Project.lens.rewardData.rewards .~ []
|> \.extendedProjectProperties .~ self.extendedProjectProperties

let backing = Backing.template
|> Backing.lens.reward .~ reward

let projectPamphletData = Project.ProjectPamphletData(project: project, backingId: 1)
let projectAndEnvelope = ProjectAndBackingEnvelope(project: project, backing: backing)

let mockService = MockService(
fetchManagePledgeViewBackingResult: .success(projectAndEnvelope),
fetchProjectPamphletResult: .success(projectPamphletData),
fetchProjectRewardsResult: .success([reward])
)

combos(Language.allLanguages, [Device.phone5_8inch, Device.pad]).forEach { language, device in
withEnvironment(
apiService: mockService,
config: config, currentUser: .template, language: language
) {
let vc = ProjectPageViewController.configuredWith(
projectOrParam: .left(project), refTag: nil
)

let (parent, _) = traitControllers(device: device, orientation: .portrait, child: vc)
parent.view.frame.size.height = device == .pad ? 1_200 : parent.view.frame.size.height

self.scheduler.run()

FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)")
}
}
}

func testLoggedIn_Backer_LiveProject_US_ProjectCurrency_US_ProjectCountry_US_UserChosenCurrency_OmittingCurrencyCode_Success() {
let config = Config.template
let reward = Reward.template
|> Reward.lens.title .~ "Magic Lamp"
let project = Project.cosmicSurgery
|> Project.lens.stats.currency .~ Project.Country.us.currencyCode
|> Project.lens.country .~ Project.Country.us
|> Project.lens.stats.currentCurrency .~ Project.Country.us.currencyCode
|> Project.lens.photo.full .~ ""
|> (Project.lens.creator.avatar .. User.Avatar.lens.small) .~ ""
|> Project.lens.personalization.isBacking .~ false
|> Project.lens.personalization.backing .~ nil
|> Project.lens.state .~ .live
|> Project.lens.stats.convertedPledgedAmount .~ 29_236
|> Project.lens.rewardData.rewards .~ []
|> \.extendedProjectProperties .~ self.extendedProjectProperties

let backing = Backing.template
|> Backing.lens.reward .~ reward

let projectPamphletData = Project.ProjectPamphletData(project: project, backingId: 1)
let projectAndEnvelope = ProjectAndBackingEnvelope(project: project, backing: backing)

let mockService = MockService(
fetchManagePledgeViewBackingResult: .success(projectAndEnvelope),
fetchProjectPamphletResult: .success(projectPamphletData),
fetchProjectRewardsResult: .success([reward])
)

combos(Language.allLanguages, [Device.phone5_8inch, Device.pad]).forEach { language, device in
withEnvironment(
apiService: mockService,
config: config, currentUser: .template, language: language
) {
let vc = ProjectPageViewController.configuredWith(
projectOrParam: .left(project), refTag: nil
)

let (parent, _) = traitControllers(device: device, orientation: .portrait, child: vc)
parent.view.frame.size.height = device == .pad ? 1_200 : parent.view.frame.size.height

self.scheduler.run()

FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)")
}
}
}

func testLoggedIn_Backer_LiveProject_NonUS_ProjectCurrency_US_ProjectCountry_NonUS_UserChosenCurrency_NotOmittingCurrencyCode_Success() {
let config = Config.template
let reward = Reward.template
|> Reward.lens.title .~ "Magic Lamp"
let project = Project.cosmicSurgery
|> Project.lens.stats.currency .~ Project.Country.mx.currencyCode
|> Project.lens.country .~ Project.Country.us
|> Project.lens.stats.currentCurrency .~ Project.Country.mx.currencyCode
|> Project.lens.photo.full .~ ""
|> (Project.lens.creator.avatar .. User.Avatar.lens.small) .~ ""
|> Project.lens.personalization.isBacking .~ false
|> Project.lens.personalization.backing .~ nil
|> Project.lens.state .~ .live
|> Project.lens.stats.convertedPledgedAmount .~ 29_236
|> Project.lens.rewardData.rewards .~ []
|> \.extendedProjectProperties .~ self.extendedProjectProperties

let backing = Backing.template
|> Backing.lens.reward .~ reward

let projectPamphletData = Project.ProjectPamphletData(project: project, backingId: 1)
let projectAndEnvelope = ProjectAndBackingEnvelope(project: project, backing: backing)

let mockService = MockService(
fetchManagePledgeViewBackingResult: .success(projectAndEnvelope),
fetchProjectPamphletResult: .success(projectPamphletData),
fetchProjectRewardsResult: .success([reward])
)

combos(Language.allLanguages, [Device.phone5_8inch, Device.pad]).forEach { language, device in
withEnvironment(
apiService: mockService,
config: config, currentUser: .template, language: language
) {
let vc = ProjectPageViewController.configuredWith(
projectOrParam: .left(project), refTag: nil
)

let (parent, _) = traitControllers(device: device, orientation: .portrait, child: vc)
parent.view.frame.size.height = device == .pad ? 1_200 : parent.view.frame.size.height

self.scheduler.run()

FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)")
}
}
}

func testLoggedIn_Backer_LiveProject_US_ProjectCurrency_US_ProjectCountry_NonUS_UserChosenCurrency_Success() {
let config = Config.template
let reward = Reward.template
|> Reward.lens.title .~ "Magic Lamp"
let project = Project.cosmicSurgery
|> Project.lens.stats.currency .~ Project.Country.us.currencyCode
|> Project.lens.country .~ Project.Country.us
|> Project.lens.stats.currentCurrency .~ Project.Country.mx.currencyCode
|> Project.lens.photo.full .~ ""
|> (Project.lens.creator.avatar .. User.Avatar.lens.small) .~ ""
|> Project.lens.personalization.isBacking .~ false
|> Project.lens.personalization.backing .~ nil
|> Project.lens.state .~ .live
|> Project.lens.stats.convertedPledgedAmount .~ 29_236
|> Project.lens.rewardData.rewards .~ []
|> \.extendedProjectProperties .~ self.extendedProjectProperties

let backing = Backing.template
|> Backing.lens.reward .~ reward

let projectPamphletData = Project.ProjectPamphletData(project: project, backingId: 1)
let projectAndEnvelope = ProjectAndBackingEnvelope(project: project, backing: backing)

let mockService = MockService(
fetchManagePledgeViewBackingResult: .success(projectAndEnvelope),
fetchProjectPamphletResult: .success(projectPamphletData),
fetchProjectRewardsResult: .success([reward])
)

combos(Language.allLanguages, [Device.phone5_8inch, Device.pad]).forEach { language, device in
withEnvironment(
apiService: mockService,
config: config, currentUser: .template, language: language
) {
let vc = ProjectPageViewController.configuredWith(
projectOrParam: .left(project), refTag: nil
)

let (parent, _) = traitControllers(device: device, orientation: .portrait, child: vc)
parent.view.frame.size.height = device == .pad ? 1_200 : parent.view.frame.size.height

self.scheduler.run()

FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)")
}
}
}

// MARK: - Logged Out

func testLoggedOut_NonBacker_LiveProject_ShowEnvironmentalCommitments_Success() {
Expand Down
67 changes: 67 additions & 0 deletions Kickstarter-iOS/Library/SharedFunctionsTests.swift
Expand Up @@ -473,4 +473,71 @@ internal final class SharedFunctionsTests: TestCase {
XCTAssertEqual(rewardLimitRemainingForBacker(project: project, reward: reward), nil)
XCTAssertEqual(rewardLimitPerBackerRemainingForBacker(project: project, reward: reward), nil)
}

func testProjectCountryForCurrency() {
let projectCountry = projectCountry(forCurrency: "MXN")

XCTAssertEqual(projectCountry, .mx)
}

func testFormattedAmountForRewardOrBacking() {
let mexicanCurrencyProjectTemplate = Project.template
|> Project.lens.stats.currency .~ Project.Country.mx.currencyCode

let backing = Backing.template

var currencyText = formattedAmountForRewardOrBacking(
project: mexicanCurrencyProjectTemplate,
rewardOrBacking: .right(backing)
)

XCTAssertEqual(currencyText, "MX$ 10")

let reward = Reward.template
|> Reward.lens.minimum .~ 12.00

currencyText = formattedAmountForRewardOrBacking(
project: mexicanCurrencyProjectTemplate,
rewardOrBacking: .left(reward)
)

XCTAssertEqual(currencyText, "MX$ 12")
}

func testMinAndMaxPledgeAmount_NoReward_ProjectCurrencyCountry_MinMaxPledgeReturned_Success() {
let mexicanCurrencyProjectTemplate = Project.template
|> Project.lens.stats.currency .~ Project.Country.mx.currencyCode

let (min, max) = minAndMaxPledgeAmount(forProject: mexicanCurrencyProjectTemplate, reward: nil)

XCTAssertEqual(min, 10)
XCTAssertEqual(max, 200_000)
}

func testMinAndMaxPledgeAmount_Reward_ProjectCurrencyCountry_MinMaxPledgeReturned_Success() {
let mexicanCurrencyProjectTemplate = Project.template
|> Project.lens.stats.currency .~ Project.Country.mx.currencyCode

let reward = Reward.template
|> Reward.lens.minimum .~ 12.00

let (min, max) = minAndMaxPledgeAmount(forProject: mexicanCurrencyProjectTemplate, reward: reward)

XCTAssertEqual(min, 12)
XCTAssertEqual(max, 200_000)
}

func testMinAndMaxPledgeAmount_NoReward_NoProjectCurrencyCountry_DefaultMinMaxPledgeReturned_Success() {
let mexicanCurrencyProjectTemplate = Project.template
|> Project.lens.stats.currency .~ Project.Country.mx.currencyCode

let emptyLaunchedCountries = LaunchedCountries(countries: [])

withEnvironment(launchedCountries: emptyLaunchedCountries) {
let (min, max) = minAndMaxPledgeAmount(forProject: mexicanCurrencyProjectTemplate, reward: .noReward)

XCTAssertEqual(min, 1)
XCTAssertEqual(max, 10_000)
}
}
}

0 comments on commit d2360b0

Please sign in to comment.