Doubles
2 months ago
Providers
2 months ago
BulkReviewsUpdateStuckStateTest.php
2 months ago
ClearCacheRelayResetTest.php
2 months ago
DeleteSourceRelayFailureTest.php
2 months ago
ErrorHandlerFalsyOptionTest.php
2 months ago
FeedCacheUpdateServiceTest.php
2 months ago
FeedMalformedPayloadTest.php
2 months ago
ForceKeylessRefetchTest.php
2 months ago
LicenseDeactivateStaleStateTest.php
2 months ago
MediaFinderMemoTest.php
2 months ago
MultiSourceAggregationTest.php
2 months ago
ReconcileMigratedLicenseRoutineTest.php
2 months ago
ReconcileRemovalTest.php
2 months ago
RegisterWebsiteRoutineTest.php
2 months ago
RemoteRequestMemoTest.php
2 months ago
ReviewAlertHeaderTotalsTest.php
2 months ago
ReviewAlertPageTargetingTest.php
2 months ago
ReviewAlertStarFillTest.php
2 months ago
ShortcodeNeutralizationTest.php
2 months ago
SiteMigrationRecoveryTest.php
2 months ago
Smash1583HeaderParityTest.php
2 months ago
SourceIdLookupTest.php
2 months ago
WpmlGetCurrentLanguageTest.php
2 months ago
WpmlLanguageMappingTest.php
2 months ago
LicenseDeactivateStaleStateTest.php
92 lines
| 1 | <?php |
| 2 | |
| 3 | namespace SmashBalloon\Reviews\Tests\Unit; |
| 4 | |
| 5 | use PHPUnit\Framework\TestCase; |
| 6 | use SmashBalloon\Reviews\Pro\Integrations\LicenseManagerService; |
| 7 | |
| 8 | /** |
| 9 | * SMASH-1585 — deactivate stale-state recovery. |
| 10 | * |
| 11 | * When a migrated site clicks Deactivate, EDD has no activation for the new |
| 12 | * URL, so the relay returns errorId `licenseNotDeactivated` + edd_reason |
| 13 | * `failed`. ajax_deactivate_license() must recognize that as "nothing to |
| 14 | * deactivate, the local `valid` flag is stale" and clear local state so the |
| 15 | * panel falls back to Activate — instead of dead-ending on an error the |
| 16 | * customer cannot clear. |
| 17 | * |
| 18 | * These pin the detection predicate `is_nothing_to_deactivate()`, including the |
| 19 | * load-bearing detail that it reads FLAT keys (`$response['id']` / |
| 20 | * `$response['edd_reason']`) because SBRelay::call() unwraps the error envelope |
| 21 | * — reading `$response['data'][...]` (as the original support report proposed) |
| 22 | * would never fire. |
| 23 | */ |
| 24 | class LicenseDeactivateStaleStateTest extends TestCase |
| 25 | { |
| 26 | private function predicate($response): bool |
| 27 | { |
| 28 | // The predicate only reads its argument — construct without deps. |
| 29 | $svc = (new \ReflectionClass(LicenseManagerService::class)) |
| 30 | ->newInstanceWithoutConstructor(); |
| 31 | $method = new \ReflectionMethod(LicenseManagerService::class, 'is_nothing_to_deactivate'); |
| 32 | $method->setAccessible(true); |
| 33 | |
| 34 | return $method->invoke($svc, $response); |
| 35 | } |
| 36 | |
| 37 | public function test_fires_on_flat_licenseNotDeactivated_failed(): void |
| 38 | { |
| 39 | // The shape SBRelay::call() actually hands the plugin on this error |
| 40 | // (envelope unwrapped → flat keys). |
| 41 | $this->assertTrue($this->predicate([ |
| 42 | 'id' => 'licenseNotDeactivated', |
| 43 | 'edd_reason' => 'failed', |
| 44 | ])); |
| 45 | } |
| 46 | |
| 47 | public function test_does_not_fire_on_nested_shape(): void |
| 48 | { |
| 49 | // Proves we read FLAT keys. The original report's `$response['data']['id']` |
| 50 | // read would match this shape but never the real (unwrapped) response — |
| 51 | // so this MUST be false. |
| 52 | $this->assertFalse($this->predicate([ |
| 53 | 'data' => [ |
| 54 | 'id' => 'licenseNotDeactivated', |
| 55 | 'edd_reason' => 'failed', |
| 56 | ], |
| 57 | ])); |
| 58 | } |
| 59 | |
| 60 | public function test_does_not_fire_on_other_edd_reason(): void |
| 61 | { |
| 62 | // Scoped to `failed` — the "no activation for this URL" code. A transient |
| 63 | // or different reason must not clear local state. |
| 64 | $this->assertFalse($this->predicate([ |
| 65 | 'id' => 'licenseNotDeactivated', |
| 66 | 'edd_reason' => 'expired', |
| 67 | ])); |
| 68 | } |
| 69 | |
| 70 | public function test_does_not_fire_on_different_error_id(): void |
| 71 | { |
| 72 | $this->assertFalse($this->predicate([ |
| 73 | 'id' => 'invalidToken', |
| 74 | 'edd_reason' => 'failed', |
| 75 | ])); |
| 76 | } |
| 77 | |
| 78 | public function test_does_not_fire_on_success_response(): void |
| 79 | { |
| 80 | $this->assertFalse($this->predicate([ |
| 81 | 'success' => true, |
| 82 | 'data' => ['license' => 'deactivated'], |
| 83 | ])); |
| 84 | } |
| 85 | |
| 86 | public function test_does_not_fire_on_non_array(): void |
| 87 | { |
| 88 | $this->assertFalse($this->predicate(null)); |
| 89 | $this->assertFalse($this->predicate('licenseNotDeactivated')); |
| 90 | } |
| 91 | } |
| 92 |