Skip to content

Commit

Permalink
Simplified tests
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Oct 24, 2023
1 parent 0b01f29 commit 1eb84ad
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 42 deletions.
17 changes: 14 additions & 3 deletions Tests/RevenueCatUITests/BaseSnapshotTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ extension BaseSnapshotTest {
extension View {

/// Adds the receiver to a view hierarchy to be able to test lifetime logic.
func addToHierarchy() throws {
/// - Returns: dispose block that removes the view from the hierarchy.
@discardableResult
func addToHierarchy() throws -> () -> Void {
UIView.setAnimationsEnabled(false)

let controller = UIHostingController(
Expand All @@ -100,16 +102,25 @@ extension View {
window.isHidden = false
window.rootViewController = controller
window.frame.size = BaseSnapshotTest.fullScreenSize
window.makeKeyAndVisible()

window.addSubview(controller.view)
controller.didMove(toParent: controller)

window.setNeedsLayout()
window.layoutIfNeeded()

controller.beginAppearanceTransition(true, animated: false)
controller.endAppearanceTransition()

window.makeKeyAndVisible()

return {
controller.beginAppearanceTransition(false, animated: false)
controller.view.removeFromSuperview()
controller.removeFromParent()
controller.endAppearanceTransition()
window.rootViewController = nil
window.resignKey()
}
}

}
76 changes: 37 additions & 39 deletions Tests/RevenueCatUITests/PaywallViewEventsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,41 +29,34 @@ class PaywallViewEventsTests: TestCase {
private let mode: PaywallViewMode = .random
private let scheme: ColorScheme = Bool.random() ? .dark : .light

private var impressionEventExpectation: XCTestExpectation!
private var closeEventExpectation: XCTestExpectation!
private var cancelEventExpectation: XCTestExpectation!

override func setUp() {
super.setUp()

self.continueAfterFailure = false

self.handler =
.cancelling()
.map { _ in
return { [weak self] event in
await self?.track(event)
}
}

self.impressionEventExpectation = .init(description: "Impression event")
self.closeEventExpectation = .init(description: "Close event")
self.cancelEventExpectation = .init(description: "Cancel event")
}

func testPaywallImpressionEvent() throws {
try self.createView()
.addToHierarchy()
func testPaywallImpressionEvent() async throws {
try await self.runDuringViewLifetime {}

expect(self.events).toEventually(containElementSatisfying { $0.eventType == .impression })
expect(self.events).to(containElementSatisfying { $0.eventType == .impression })

let event = try XCTUnwrap(self.events.first { $0.eventType == .impression })
self.verifyEventData(event.data)
}

func testPaywallCloseEvent() async throws {
try self.createView()
.addToHierarchy()

await self.fulfillment(of: [self.closeEventExpectation], timeout: 1)
try await self.runDuringViewLifetime {}
await self.waitForCloseEvent()

expect(self.events).to(haveCount(2))
expect(self.events).to(containElementSatisfying { $0.eventType == .close })
Expand All @@ -73,24 +66,20 @@ class PaywallViewEventsTests: TestCase {
}

func testCloseEventHasSameSessionID() async throws {
try self.createView()
.addToHierarchy()

await self.fulfillment(of: [self.closeEventExpectation], timeout: 1)
try await self.runDuringViewLifetime {}
await self.waitForCloseEvent()

expect(self.events).to(haveCount(2))
expect(self.events.map(\.eventType)) == [.impression, .close]
expect(Set(self.events.map(\.data.sessionIdentifier))).to(haveCount(1))
}

func testCancelledPurchase() async throws {
try self.createView()
.addToHierarchy()

_ = try await self.handler.purchase(package: try XCTUnwrap(Self.offering.monthly))
try await self.runDuringViewLifetime {
_ = try await self.handler.purchase(package: try XCTUnwrap(Self.offering.monthly))
}

await self.fulfillment(of: [self.cancelEventExpectation, self.closeEventExpectation],
timeout: 1)
await self.waitForCloseEvent()

expect(self.events).to(haveCount(3))
expect(self.events.map(\.eventType)).to(contain([.impression, .cancel, .close]))
Expand All @@ -101,24 +90,15 @@ class PaywallViewEventsTests: TestCase {
}

func testDifferentPaywallsCreateSeparateSessionIdentifiers() async throws {
self.impressionEventExpectation.expectedFulfillmentCount = 2
self.closeEventExpectation.expectedFulfillmentCount = 2

let firstCloseExpectation = XCTestExpectation(description: "First paywall was closed")
try await self.runDuringViewLifetime {}
try await self.runDuringViewLifetime {}

try self.createView()
.onDisappear { firstCloseExpectation.fulfill() }
.addToHierarchy()

await self.fulfillment(of: [firstCloseExpectation], timeout: 1)

try self.createView()
.addToHierarchy()

await self.fulfillment(of: [self.impressionEventExpectation, self.closeEventExpectation], timeout: 1)
await self.waitForCloseEvent()

expect(self.events).to(haveCount(4))
expect(Set(self.events.map(\.eventType))) == [.impression, .close, .impression, .close]
expect(self.events.map(\.eventType)) == [.impression, .close, .impression, .close]
expect(Set(self.events.map(\.data.sessionIdentifier))).to(haveCount(2))
}

Expand All @@ -131,12 +111,26 @@ class PaywallViewEventsTests: TestCase {
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
private extension PaywallViewEventsTests {

/// Invokes `createView` and runs the given `closure` during the lifetime of the view.
/// Returns after the view has been completly removed from the hierarchy.
func runDuringViewLifetime(
_ closure: @escaping () async throws -> Void
) async throws {
// Create a `Task` to run inside of an `autoreleasepool`.
try await Task {
let dispose = try self.createView()
.addToHierarchy()
try await closure()
dispose()
}.value
}

func track(_ event: PaywallEvent) {
self.events.append(event)

switch event {
case .impression: self.impressionEventExpectation.fulfill()
case .cancel: self.cancelEventExpectation.fulfill()
case .impression: break
case .cancel: break
case .close: self.closeEventExpectation.fulfill()
}
}
Expand All @@ -160,6 +154,10 @@ private extension PaywallViewEventsTests {
expect(data.darkMode) == (self.scheme == .dark)
}

func waitForCloseEvent() async {
await self.fulfillment(of: [self.closeEventExpectation], timeout: 1)
}

}

private extension PaywallViewMode {
Expand Down

0 comments on commit 1eb84ad

Please sign in to comment.