{ "output": "\nIMPORTANT: The file content has been truncated.\nStatus: Showing lines 120-260 of 608 total lines.\nAction: To read more of the file, you can use the 'start_line' and 'end_line' parameters in a subsequent 'read_file' call. For example, to read the next section of the file, use start_line: 261.\n\n--- FILE CONTENT (truncated) ---\n billingResult: BillingResult,\n purchases: List = emptyList(),\n ) {\n val listenerSlot = slot()\n every {\n mockBillingClient.queryPurchasesAsync(any(), capture(listenerSlot))\n } answers {\n listenerSlot.captured.onQueryPurchasesResponse(billingResult, purchases)\n }\n }\n\n /**\n * Stubs [BillingClient.queryProductDetailsAsync] to invoke the [ProductDetailsResponseListener]\n * synchronously with an OK result and empty list (product details pre-fetched for launch).\n */\n private fun stubQueryProductDetailsOk(details: ProductDetails = mockk(relaxed = true)) {\n val listenerSlot = slot()\n every {\n mockBillingClient.queryProductDetailsAsync(any(), capture(listenerSlot))\n } answers {\n listenerSlot.captured.onProductDetailsResponse(okResult(), listOf(details))\n }\n }\n\n /**\n * Stubs [BillingClient.acknowledgePurchase] to invoke the\n * [AcknowledgePurchaseResponseListener] synchronously with an OK result.\n */\n private fun stubAcknowledgePurchaseOk() {\n val listenerSlot = slot()\n every {\n mockBillingClient.acknowledgePurchase(any(), capture(listenerSlot))\n } answers {\n listenerSlot.captured.onAcknowledgePurchaseResponse(okResult())\n }\n }\n\n // ── Tests: PURCHASED flip ────────────────────────────────────────────────────\n\n @Test\n fun `isPremium flips to true when PURCHASED premium purchase is found`() =\n testScope.runTest {\n preferences.isPremiumCached = false\n val purchasedPurchase = makePurchase(state = Purchase.PurchaseState.PURCHASED, acknowledged = true)\n stubStartConnectionOk()\n stubQueryPurchases(okResult(), listOf(purchasedPurchase))\n stubQueryProductDetailsOk()\n\n billingManagerImpl.startConnection()\n advanceUntilIdle()\n\n assertThat(billingManagerImpl.isPremium.value).isTrue()\n assertThat(billingManagerImpl.hasPendingPurchase.value).isFalse()\n }\n\n @Test\n fun `isPremium flips from false to true when purchase state transitions from PENDING to PURCHASED`() =\n testScope.runTest {\n preferences.isPremiumCached = false\n val pendingPurchase = makePurchase(state = Purchase.PurchaseState.PENDING, token = \"token_1\")\n stubStartConnectionOk()\n stubQueryPurchases(okResult(), listOf(pendingPurchase))\n stubQueryProductDetailsOk()\n\n billingManagerImpl.startConnection()\n advanceUntilIdle()\n\n assertThat(billingManagerImpl.isPremium.value).isFalse()\n assertThat(billingManagerImpl.hasPendingPurchase.value).isTrue()\n\n // Transition to PURCHASED\n val purchasedPurchase = makePurchase(state = Purchase.PurchaseState.PURCHASED, token = \"token_1\")\n capturedPurchasesUpdatedListener.onPurchasesUpdated(okResult(), listOf(purchasedPurchase))\n advanceUntilIdle()\n\n assertThat(billingManagerImpl.isPremium.value).isTrue()\n assertThat(billingManagerImpl.hasPendingPurchase.value).isFalse()\n }\n\n @Test\n fun `hasPendingPurchase clears when onPurchasesUpdated returns non-OK result`() =\n testScope.runTest {\n // First set to pending\n val pendingPurchase = makePurchase(state = Purchase.PurchaseState.PENDING, token = \"token_1\")\n stubStartConnectionOk()\n stubQueryPurchases(okResult(), listOf(pendingPurchase))\n billingManagerImpl.startConnection()\n advanceUntilIdle()\n assertThat(billingManagerImpl.hasPendingPurchase.value).isTrue()\n\n // Transition to error/cancel\n capturedPurchasesUpdatedListener.onPurchasesUpdated(errorResult(BillingClient.BillingResponseCode.USER_CANCELED), null)\n advanceUntilIdle()\n\n assertThat(billingManagerImpl.hasPendingPurchase.value).isFalse()\n }\n\n @Test\n fun `launchPremiumPurchaseFlow returns BillingUnavailable when cachedProductDetails is null`() =\n testScope.runTest {\n stubStartConnectionOk()\n // Stub queryProductDetails to return empty list, so cachedProductDetails remains null\n val listenerSlot = slot()\n every {\n mockBillingClient.queryProductDetailsAsync(any(), capture(listenerSlot))\n } answers {\n listenerSlot.captured.onProductDetailsResponse(okResult(), emptyList())\n }\n\n billingManagerImpl.startConnection()\n advanceUntilIdle()\n\n val mockActivity = mockk(relaxed = true)\n val result = billingManagerImpl.launchPremiumPurchaseFlow(mockActivity)\n\n assertThat(result).isEqualTo(BillingLaunchResult.BillingUnavailable)\n }\n\n @Test\n fun `launchPremiumPurchaseFlow returns BillingUnavailable when queryProductDetailsAsync fails`() =\n testScope.runTest {\n stubStartConnectionOk()\n // Stub queryProductDetails to return an error code\n val listenerSlot = slot()\n every {\n mockBillingClient.queryProductDetailsAsync(any(), capture(listenerSlot))\n } answers {\n listenerSlot.captured.onProductDetailsResponse(\n errorResult(BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE),\n emptyList(),\n )\n }\n\n billingManagerImpl.startConnection()\n advanceUntilIdle()\n\n val mockActivity = mockk(relaxed = true)\n val result = billingManagerImpl.launchPremiumPurchaseFlow(mockActivity)\n\n assertThat(result).isEqualTo(BillingLaunchResult.BillingUnavailable)\n }" }