Skip to content

Commit 18ab984

Browse files
authored
feat(client) introduce store kit url client factory methods (#208)
* feat(client): add specified factory methods - createForStoreKit - createForStoreKitSandbox - createForITunes - createForITunesSandbox * chore(client): deprecate un-specific factory methods * chore(client): remove param deprecation message * chore(client): deprecate un-specific constants
1 parent 2085187 commit 18ab984

File tree

5 files changed

+122
-34
lines changed

5 files changed

+122
-34
lines changed

UPGRADE-2.0.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
## Client Factory
44

5-
- The `$sandbox` parameter in the `ClientFactory::create()` method is removed, use the `ClientFactory::createSandbox()`
6-
method instead.
5+
- The `ClientFactory::create()` & `ClientFactory:createSandbox()` methods are removed, use the specific factory methods
6+
instead.
7+
- The `ClientFactory::BASE_URI` & `ClientFactory::SANDBOX_BASE_URI` constants are removed, use the specific constants
8+
instead.
79

810
## Value objects
911

src/ClientFactory.php

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,35 @@
1515

1616
class ClientFactory
1717
{
18+
/**@deprecated use {@see self::ITUNES_PRODUCTION_URI} */
1819
public const BASE_URI = 'https://buy.itunes.apple.com';
20+
/**@deprecated use {@see self::ITUNES_SANDBOX_URI} */
1921
public const BASE_URI_SANDBOX = 'https://sandbox.itunes.apple.com';
22+
2023
public const STORE_KIT_PRODUCTION_URI = 'https://api.storekit.itunes.apple.com';
2124
public const STORE_KIT_SANDBOX_URI = 'https://api.storekit-sandbox.itunes.apple.com';
25+
public const ITUNES_PRODUCTION_URI = 'https://buy.itunes.apple.com';
26+
public const ITUNES_SANDBOX_URI = 'https://sandbox.itunes.apple.com';
2227

28+
/**
29+
* @deprecated use specific create methods instead.
30+
*/
2331
public static function create(bool $sandbox = false, array $options = []): ClientInterface
2432
{
25-
if ($sandbox) {
26-
trigger_error(
27-
'The $sandbox parameter is deprecated and will be removed in the next major version. Use createSandbox instead.',
28-
E_USER_DEPRECATED
29-
);
30-
}
31-
32-
$options = array_merge(['base_uri' => $sandbox ? self::BASE_URI_SANDBOX : self::BASE_URI], $options);
33+
$options = array_merge(
34+
['base_uri' => $sandbox ? self::ITUNES_SANDBOX_URI : self::ITUNES_PRODUCTION_URI],
35+
$options
36+
);
3337

3438
return new Client($options);
3539
}
3640

41+
/**
42+
* @deprecated use specific create methods instead.
43+
*/
3744
public static function createSandbox(array $options = []): ClientInterface
3845
{
39-
$options = array_merge(['base_uri' => self::BASE_URI_SANDBOX], $options);
46+
$options = array_merge(['base_uri' => self::ITUNES_SANDBOX_URI], $options);
4047

4148
return new Client($options);
4249
}
@@ -86,4 +93,31 @@ public static function mockError(
8693

8794
return new Client(['handler' => $handlerStack]);
8895
}
96+
97+
public static function createForStoreKit(array $options = []): ClientInterface
98+
{
99+
return self::createByURI(self::STORE_KIT_PRODUCTION_URI, $options);
100+
}
101+
102+
public static function createForStoreKitSandbox(array $options = []): ClientInterface
103+
{
104+
return self::createByURI(self::STORE_KIT_SANDBOX_URI, $options);
105+
}
106+
107+
public static function createForITunes(array $options = []): ClientInterface
108+
{
109+
return self::createByURI(self::ITUNES_PRODUCTION_URI, $options);
110+
}
111+
112+
public static function createForITunesSandbox(array $options = []): ClientInterface
113+
{
114+
return self::createByURI(self::ITUNES_SANDBOX_URI, $options);
115+
}
116+
117+
private static function createByURI(string $uri, array $options = []): ClientInterface
118+
{
119+
$options = array_merge(['base_uri' => $uri], $options);
120+
121+
return new Client($options);
122+
}
89123
}

src/Receipts/Verifier.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ class Verifier
3939
* Receipt constructor.
4040
*
4141
* @param ClientInterface $client
42-
* @param string $receiptData
43-
* @param string $password
42+
* @param string $receiptData
43+
* @param string $password
4444
*/
4545
public function __construct(ClientInterface $client, string $receiptData, string $password)
4646
{
@@ -62,7 +62,7 @@ public function verifyRenewable(?ClientInterface $sandboxClient = null): Receipt
6262
}
6363

6464
/**
65-
* @param bool $excludeOldTransactions
65+
* @param bool $excludeOldTransactions
6666
* @param ClientInterface|null $sandboxClient
6767
*
6868
* @return ReceiptResponse
@@ -80,15 +80,15 @@ public function verify(
8080
}
8181

8282
if ($this->isFromTestEnv($status)) {
83-
$sandboxClient = $sandboxClient ?? ClientFactory::createSandbox();
83+
$sandboxClient = $sandboxClient ?? ClientFactory::createForITunesSandbox();
8484
$responseBody = $this->sendVerifyRequest($excludeOldTransactions, $sandboxClient);
8585
}
8686

8787
return ReceiptResponse::fromArray($responseBody);
8888
}
8989

9090
/**
91-
* @param bool $excludeOldTransactions
91+
* @param bool $excludeOldTransactions
9292
* @param ClientInterface|null $client
9393
*
9494
* @return array

tests/TestCase.php

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,14 @@
33
namespace Imdhemy\AppStore\Tests;
44

55
use JsonException;
6+
use ReflectionClass;
67

78
/**
89
* Class TestCase
910
* All test cases should extend this class
1011
*/
1112
class TestCase extends \PHPUnit\Framework\TestCase
1213
{
13-
/**
14-
* @var Faker
15-
*/
1614
protected Faker $faker;
1715

1816
/**
@@ -24,24 +22,19 @@ protected function setUp(): void
2422
$this->faker = Faker::create();
2523
}
2624

27-
/**
28-
* @return string
29-
*/
3025
protected function getSubscriptionReceipt(): string
3126
{
32-
return file_get_contents(__DIR__ . '/fixtures/subscription_receipt.json');
27+
return file_get_contents(__DIR__.'/fixtures/subscription_receipt.json');
3328
}
3429

3530

3631
/**
37-
* @param array $override
3832
*
39-
* @return string
4033
* @throws JsonException
4134
*/
4235
protected function getVerifyReceiptResponse(array $override = []): string
4336
{
44-
$contents = file_get_contents(__DIR__ . '/fixtures/verify_receipt_response.json');
37+
$contents = file_get_contents(__DIR__.'/fixtures/verify_receipt_response.json');
4538
$data = json_decode($contents, true, 512, JSON_THROW_ON_ERROR);
4639
$response = array_merge($data, $override);
4740

@@ -51,40 +44,44 @@ protected function getVerifyReceiptResponse(array $override = []): string
5144
/**
5245
* Get RSA private key contents
5346
*
54-
* @return string
5547
*/
5648
protected function getRsaPrivateKey(): string
5749
{
58-
return file_get_contents(__DIR__ . '/fixtures/keys/rsa-private.pem');
50+
return file_get_contents(__DIR__.'/fixtures/keys/rsa-private.pem');
5951
}
6052

6153
/**
6254
* Get RSA public key contents
6355
*
64-
* @return string
6556
*/
6657
protected function getRsaPublicKey(): string
6758
{
68-
return file_get_contents(__DIR__ . '/fixtures/keys/rsa-public.pem');
59+
return file_get_contents(__DIR__.'/fixtures/keys/rsa-public.pem');
6960
}
7061

7162
/**
7263
* Get EC private key contents
7364
*
74-
* @return string
7565
*/
7666
protected function getEcdsaPrivateKey(): string
7767
{
78-
return file_get_contents(__DIR__ . '/fixtures/keys/ecdsa-private.pem');
68+
return file_get_contents(__DIR__.'/fixtures/keys/ecdsa-private.pem');
7969
}
8070

8171
/**
8272
* Get EC public key contents
8373
*
84-
* @return string
8574
*/
8675
protected function getEcdsaPublicKey(): string
8776
{
88-
return file_get_contents(__DIR__ . '/fixtures/keys/ecdsa-public.pem');
77+
return file_get_contents(__DIR__.'/fixtures/keys/ecdsa-public.pem');
78+
}
79+
80+
protected function getPropertyByReflection(object $object, string $property): mixed
81+
{
82+
$reflection = new ReflectionClass($object);
83+
$property = $reflection->getProperty($property);
84+
85+
return $property->getValue($object);
8986
}
9087
}

tests/Unit/ClientFactoryTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,71 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Imdhemy\AppStore\Tests\Unit;
46

57
use GuzzleHttp\Exception\RequestException;
68
use GuzzleHttp\Psr7\Request;
79
use GuzzleHttp\Psr7\Response;
10+
use GuzzleHttp\Psr7\Uri;
811
use Imdhemy\AppStore\ClientFactory;
912
use Imdhemy\AppStore\Tests\TestCase;
1013
use ReflectionClass;
1114

1215
final class ClientFactoryTest extends TestCase
1316
{
17+
/** @test */
18+
public function create_for_store_kit(): void
19+
{
20+
$options = ['headers' => ['X-Custom-Header' => 'CustomValue']];
21+
22+
$storeKitClient = ClientFactory::createForStoreKit($options);
23+
24+
/** @var array{base_uri: Uri, headers: array} $config */
25+
$config = $this->getPropertyByReflection($storeKitClient, 'config');
26+
$this->assertSame('https://api.storekit.itunes.apple.com', (string)$config['base_uri']);
27+
$this->assertSame('CustomValue', $config['headers']['X-Custom-Header']);
28+
}
29+
30+
/** @test */
31+
public function create_for_store_kit_sandbox(): void
32+
{
33+
$options = ['headers' => ['X-Custom-Header' => 'CustomValue']];
34+
35+
$storeKitClient = ClientFactory::createForStoreKitSandbox($options);
36+
37+
/** @var array{base_uri: Uri, headers: array} $config */
38+
$config = $this->getPropertyByReflection($storeKitClient, 'config');
39+
$this->assertSame('https://api.storekit-sandbox.itunes.apple.com', (string)$config['base_uri']);
40+
$this->assertSame('CustomValue', $config['headers']['X-Custom-Header']);
41+
}
42+
43+
/** @test */
44+
public function create_for_i_tunes(): void
45+
{
46+
$options = ['headers' => ['X-Custom-Header' => 'CustomValue']];
47+
48+
$itunesClient = ClientFactory::createForITunes($options);
49+
50+
/** @var array{base_uri: Uri, headers: array} $config */
51+
$config = $this->getPropertyByReflection($itunesClient, 'config');
52+
$this->assertSame('https://buy.itunes.apple.com', (string)$config['base_uri']);
53+
$this->assertSame('CustomValue', $config['headers']['X-Custom-Header']);
54+
}
55+
56+
/** @test */
57+
public function create_for_i_tunes_sandbox(): void
58+
{
59+
$options = ['headers' => ['X-Custom-Header' => 'CustomValue']];
60+
61+
$itunesClient = ClientFactory::createForITunesSandbox($options);
62+
63+
/** @var array{base_uri: Uri, headers: array} $config */
64+
$config = $this->getPropertyByReflection($itunesClient, 'config');
65+
$this->assertSame('https://sandbox.itunes.apple.com', (string)$config['base_uri']);
66+
$this->assertSame('CustomValue', $config['headers']['X-Custom-Header']);
67+
}
68+
1469
/**
1570
* @test
1671
* @psalm-suppress MixedArrayAccess

0 commit comments

Comments
 (0)