Skip to content

Commit

Permalink
test: expose view model flush method for consistent tests (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
Seavenly authored Jan 31, 2024
1 parent 6b9e949 commit 9c1406f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 47 deletions.
23 changes: 15 additions & 8 deletions Sources/PayPalMessages/PayPalMessageModalViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,24 @@ class PayPalMessageModalViewModel: NSObject, WKNavigationDelegate, WKScriptMessa
withTimeInterval: queueTimeInterval,
repeats: false
) { _ in
guard let jsonData = try? JSONEncoder().encode(self.makeConfig()),
let jsonString = String(data: jsonData, encoding: .utf8) else { return }
self.flushUpdates()
}
}

log(.debug, "Update props: \(jsonString)")
// Exposed internally for tests
func flushUpdates() {
guard let jsonData = try? JSONEncoder().encode(self.makeConfig()),
let jsonString = String(data: jsonData, encoding: .utf8) else { return }

self.webView.evaluateJavaScript(
"window.actions.updateProps(\(jsonString))"
) { _, _ in
// TODO: Does the JS error text get returned here?
}
log(.debug, "Update props: \(jsonString)")

self.webView.evaluateJavaScript(
"window.actions.updateProps(\(jsonString))"
) { _, _ in
// TODO: Does the JS error text get returned here?
}

queuedTimer?.invalidate()
}

func userContentController(
Expand Down
19 changes: 13 additions & 6 deletions Sources/PayPalMessages/PayPalMessageViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,19 +194,26 @@ class PayPalMessageViewModel: PayPalMessageModalEventDelegate {
withTimeInterval: queueTimeInterval,
repeats: false
) { _ in
if self.fetchMessageContentPending {
self.fetchMessageContent()
self.fetchMessageContentPending = false
} else {
self.delegate?.refreshContent(messageParameters: self.messageParameters)
}
self.flushUpdates()
}

if fireImmediately {
queuedTimer?.fire()
}
}

// Exposed internally for tests
func flushUpdates() {
if fetchMessageContentPending {
fetchMessageContent()
fetchMessageContentPending = false
} else {
delegate?.refreshContent(messageParameters: self.messageParameters)
}

queuedTimer?.invalidate()
}

/// Refreshes the Message content only if there's a new amount or logo type set
private func fetchMessageContent() {
if let stateDelegate, let messageView {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ final class PayPalMessageModalViewModelTests: XCTestCase {
}

func testUpdateConfig() {
let expectation = expectation(description: "Evaluate JavaScript Callback")
let (viewModel, webView, _, _) = makePayPalMessageModalViewModel()
webView.evaluateJavaScriptCallback = { _ in expectation.fulfill() }

XCTAssertNil(viewModel.amount)
XCTAssertNil(viewModel.offerType)
Expand All @@ -92,7 +90,7 @@ final class PayPalMessageModalViewModelTests: XCTestCase {

XCTAssertFalse(webView.evaluateJavaScriptCalled)

waitForExpectations(timeout: 0.5)
viewModel.flushUpdates()

XCTAssertTrue(webView.evaluateJavaScriptCalled)

Expand Down Expand Up @@ -122,9 +120,7 @@ final class PayPalMessageModalViewModelTests: XCTestCase {
}

func testUpdateIndividualProperties() {
let expectation = expectation(description: "Evaluate JavaScript Callback")
let (viewModel, webView, _, _) = makePayPalMessageModalViewModel()
webView.evaluateJavaScriptCallback = { _ in expectation.fulfill() }

XCTAssertNil(viewModel.amount)
XCTAssertNil(viewModel.offerType)
Expand All @@ -137,7 +133,7 @@ final class PayPalMessageModalViewModelTests: XCTestCase {

XCTAssertFalse(webView.evaluateJavaScriptCalled)

waitForExpectations(timeout: 0.5)
viewModel.flushUpdates()

let expectedJSONString = "{\"client_id\":\"testclientid\",\"amount\":300,\"offer\":\"PAYPAL_CREDIT_NO_INTEREST\"}"

Expand Down
63 changes: 36 additions & 27 deletions Tests/PayPalMessagesTests/PayPalMessageViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ final class PayPalMessageViewModelTests: XCTestCase {
viewModel.amount = newAmount
XCTAssertEqual(viewModel.amount, newAmount)

// verify a request has been performed
assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)
}

func testSimplePlacementUpdate() {
Expand All @@ -119,8 +120,9 @@ final class PayPalMessageViewModelTests: XCTestCase {
viewModel.placement = newValue
XCTAssertEqual(viewModel.placement, newValue)

// verify a request has been performed
assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)
}

func testSimpleOfferTypeUpdate() {
Expand All @@ -139,8 +141,9 @@ final class PayPalMessageViewModelTests: XCTestCase {
viewModel.offerType = newValue
XCTAssertEqual(viewModel.offerType, newValue)

// verify a request has been performed
assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)
}

func testBuyerCountryTypeUpdate() {
Expand All @@ -159,8 +162,9 @@ final class PayPalMessageViewModelTests: XCTestCase {
viewModel.buyerCountry = newValue
XCTAssertEqual(viewModel.buyerCountry, newValue)

// verify a request has been performed
assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)
}

func testSimpleLogoTypeUpdate() {
Expand All @@ -181,8 +185,9 @@ final class PayPalMessageViewModelTests: XCTestCase {
viewModel.logoType = newValue
XCTAssertEqual(viewModel.logoType, newValue)

// verify a request has been performed
assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)
}

func testSimpleColorUpdate() {
Expand All @@ -203,8 +208,10 @@ final class PayPalMessageViewModelTests: XCTestCase {
viewModel.color = newValue
XCTAssertEqual(viewModel.color, newValue)

viewModel.flushUpdates()

// verify a request has NOT been performed as color changes shouldn't trigger them
assert(mockedRequest, calledTimes: 1)
XCTAssertEqual(mockedRequest.requestsPerformed, 1)
}

func testSimpleAlignmentUpdate() {
Expand All @@ -225,8 +232,10 @@ final class PayPalMessageViewModelTests: XCTestCase {
viewModel.alignment = newValue
XCTAssertEqual(viewModel.alignment, newValue)

viewModel.flushUpdates()

// verify a request has NOT been performed as alignment changes shouldn't trigger them
assert(mockedRequest, calledTimes: 1)
XCTAssertEqual(mockedRequest.requestsPerformed, 1)
}

// MARK: - Test Duplicated Value Updates
Expand All @@ -246,12 +255,16 @@ final class PayPalMessageViewModelTests: XCTestCase {
let newAmount = Double.random(in: 0...1000)
viewModel.amount = newAmount

assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)

// set the same amount again, verify another redundant request hasn't been performed
viewModel.amount = newAmount

assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)
}

// MARK: - Test Update In Progress Cases
Expand Down Expand Up @@ -309,7 +322,9 @@ final class PayPalMessageViewModelTests: XCTestCase {
let newerAmount = newAmount - 1
viewModel.amount = newerAmount

assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)
}

func testUpdateInProgressFromConfig() {
Expand All @@ -333,13 +348,17 @@ final class PayPalMessageViewModelTests: XCTestCase {
let newAmount = Double.random(in: 1...1000)
viewModel.amount = newAmount

assert(mockedRequest, calledTimes: 2)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 2)

// test a new config being set overrides the update in progress flag and triggers and update
let newConfig = PayPalMessageConfig(data: .init(clientID: "testclientid", environment: .live))
viewModel.config = newConfig

assert(mockedRequest, calledTimes: 3)
viewModel.flushUpdates()

XCTAssertEqual(mockedRequest.requestsPerformed, 3)
}

// MARK: - Test Merchant Provider
Expand All @@ -364,16 +383,6 @@ final class PayPalMessageViewModelTests: XCTestCase {
XCTAssertNotNil(viewModel.messageParameters)
}

// MARK: - Helpers

private func assert(_ mockRequest: PayPalMessageRequestMock, calledTimes count: Int) {
let predicate = NSPredicate { _, _ in
return mockRequest.requestsPerformed == count
}
let expectation = XCTNSPredicateExpectation(predicate: predicate, object: mockRequest)
wait(for: [expectation], timeout: 2)
}

private func makePayPalMessageViewModel(
mockedView: PayPalMessageViewMock = PayPalMessageViewMock(),
mockedDelegate: PayPalMessageViewDelegateMock = PayPalMessageViewDelegateMock(),
Expand Down

0 comments on commit 9c1406f

Please sign in to comment.