createConfig(true); self::assertSame($expectedQuantity, $config->getTargetQuantity($subtotal, 16)); } public static function thresholdProvider(): array { return [ 'below first tier' => [198.99, 0], 'first tier boundary' => [199.00, 1], 'between first and second' => [298.99, 1], 'second tier boundary' => [299.00, 2], 'between second and third' => [398.99, 2], 'third tier boundary' => [399.00, 3], 'above third tier' => [1000.00, 3], ]; } public function testDisabledCampaignReturnsNoGift(): void { self::assertSame(0, $this->createConfig(false)->getTargetQuantity(500.00, 16)); } private function createConfig(bool $enabled): Config { $values = [ 'esun_free_gift/general/gift_sku' => 'FREE-FILAMENT', 'esun_free_gift/general/start_date' => '2026-08-01', 'esun_free_gift/general/end_date' => '2026-08-31', 'esun_free_gift/tiers/items' => '[{"amount":199,"qty":1},{"amount":299,"qty":2},{"amount":399,"qty":3}]', 'esun_free_gift/tiers/tier_1_amount' => '199', 'esun_free_gift/tiers/tier_1_qty' => '1', 'esun_free_gift/tiers/tier_2_amount' => '299', 'esun_free_gift/tiers/tier_2_qty' => '2', 'esun_free_gift/tiers/tier_3_amount' => '399', 'esun_free_gift/tiers/tier_3_qty' => '3', ]; $scopeConfig = $this->createMock(ScopeConfigInterface::class); $scopeConfig->method('isSetFlag')->willReturn($enabled); $scopeConfig->method('getValue')->willReturnCallback( static fn (string $path): ?string => $values[$path] ?? null ); $timezone = $this->createMock(TimezoneInterface::class); $timezone->method('scopeDate')->willReturn(new \DateTime('2026-08-18')); return new Config($scopeConfig, $timezone, new Json()); } }