@@ -82,10 +82,10 @@ final class OpenIapProviderTests: XCTestCase {
8282 @MainActor
8383 func testListenerCleanupOnEndConnection( ) async throws {
8484 let module = OpenIapModule . shared
85-
85+
8686 // Initialize connection
8787 _ = try await module. initConnection ( )
88-
88+
8989 // Create subscriptions
9090 autoreleasepool {
9191 _ = module. purchaseUpdatedListener { _ in
@@ -95,10 +95,91 @@ final class OpenIapProviderTests: XCTestCase {
9595 print ( " This will also be cleaned up " )
9696 }
9797 }
98-
98+
9999 // End connection - should clean up all listeners
100100 _ = try await module. endConnection ( )
101-
101+
102102 // All listeners should have been cleaned up automatically
103103 }
104+
105+ // MARK: - Introductory Offer Eligibility Tests
106+
107+ @MainActor
108+ func testIsEligibleForIntroOfferIOS_withValidGroupID( ) async throws {
109+ let module = OpenIapModule . shared
110+
111+ // Initialize connection
112+ _ = try await module. initConnection ( )
113+
114+ // Test with a valid subscription group ID
115+ // Note: This will return the actual eligibility based on StoreKit's records
116+ let groupID = " test_subscription_group "
117+ let isEligible = try await module. isEligibleForIntroOfferIOS ( groupID: groupID)
118+
119+ // Verify the function returns without throwing
120+ // The actual value depends on the user's subscription history
121+ XCTAssertTrue ( isEligible || !isEligible, " Function should return a boolean value " )
122+
123+ // Clean up
124+ _ = try await module. endConnection ( )
125+ }
126+
127+ @MainActor
128+ func testIsEligibleForIntroOfferIOS_withEmptyGroupID( ) async throws {
129+ let module = OpenIapModule . shared
130+
131+ // Initialize connection
132+ _ = try await module. initConnection ( )
133+
134+ // Test with empty group ID
135+ let groupID = " "
136+ let isEligible = try await module. isEligibleForIntroOfferIOS ( groupID: groupID)
137+
138+ // Empty group ID should return true (no previous subscription)
139+ // This matches StoreKit's behavior
140+ XCTAssertTrue ( isEligible, " Empty group ID should indicate eligibility " )
141+
142+ // Clean up
143+ _ = try await module. endConnection ( )
144+ }
145+
146+ @MainActor
147+ func testIsEligibleForIntroOfferIOS_multipleGroupIDs( ) async throws {
148+ let module = OpenIapModule . shared
149+
150+ // Initialize connection
151+ _ = try await module. initConnection ( )
152+
153+ // Test with multiple different group IDs
154+ let groupID1 = " group_1 "
155+ let groupID2 = " group_2 "
156+
157+ let isEligible1 = try await module. isEligibleForIntroOfferIOS ( groupID: groupID1)
158+ let isEligible2 = try await module. isEligibleForIntroOfferIOS ( groupID: groupID2)
159+
160+ // Both should return valid boolean values
161+ XCTAssertTrue ( isEligible1 || !isEligible1, " First group should return boolean " )
162+ XCTAssertTrue ( isEligible2 || !isEligible2, " Second group should return boolean " )
163+
164+ // Clean up
165+ _ = try await module. endConnection ( )
166+ }
167+
168+ @MainActor
169+ func testIsEligibleForIntroOfferIOS_viaStore( ) async throws {
170+ let store = OpenIapStore ( )
171+
172+ // Initialize connection
173+ try await store. initConnection ( )
174+
175+ // Test via OpenIapStore wrapper
176+ let groupID = " test_group "
177+ let isEligible = try await store. isEligibleForIntroOfferIOS ( groupID: groupID)
178+
179+ // Verify it works through the store interface
180+ XCTAssertTrue ( isEligible || !isEligible, " Store wrapper should return boolean " )
181+
182+ // Clean up
183+ try await store. endConnection ( )
184+ }
104185}
0 commit comments