diff --git a/src/Klicktipp.php b/src/Klicktipp.php index 6bec18c..f87e1cb 100644 --- a/src/Klicktipp.php +++ b/src/Klicktipp.php @@ -24,7 +24,6 @@ use D3\KlicktippPhpClient\Resources\Subscriber; use D3\KlicktippPhpClient\Resources\SubscriptionProcess; use D3\KlicktippPhpClient\Resources\Tag; use GuzzleHttp\ClientInterface; -use GuzzleHttp\Exception\GuzzleException; class Klicktipp { diff --git a/src/Resources/Subscriber.php b/src/Resources/Subscriber.php index 9ba442f..741ce95 100644 --- a/src/Resources/Subscriber.php +++ b/src/Resources/Subscriber.php @@ -45,7 +45,7 @@ class Subscriber extends Model 'subscriber/'.urlencode(trim($subscriberId)).'.json' ); - return new SubscriberEntity($data); + return new SubscriberEntity($data, $this); } /** @@ -276,4 +276,33 @@ class Subscriber extends Model ) ); } + + /** + * @throws BaseException + */ + public function setSubscriber( + string $mailAddress, + ?string $newMailAddress = null, + ?string $smsNumber = null, + ?array $fields = null + ): SubscriberEntity { + try { + $id = $this->search($mailAddress); + $this->update($id, $fields, $newMailAddress ?? $mailAddress, $smsNumber); + } catch (BaseException) { + $id = $this->subscribe($newMailAddress ?? $mailAddress, null, null, $fields, $smsNumber); + } + + return $this->get($id); + } + + /** + * @throws BaseException + */ + public function getSubscriberByMailAddress(string $mailAddress): SubscriberEntity + { + return $this->get( + $this->search($mailAddress) + ); + } } diff --git a/tests/integration/IntegrationTestCase.php b/tests/integration/IntegrationTestCase.php index ef53c9b..2f76040 100644 --- a/tests/integration/IntegrationTestCase.php +++ b/tests/integration/IntegrationTestCase.php @@ -30,9 +30,11 @@ class IntegrationTestCase extends TestCase { protected array $historyContainer = []; - public function getConnectionMock(ResponseInterface $response): Connection + public function getConnectionMock(ResponseInterface|array $response): Connection { - $mock = new MockHandler([$response]); + $mock = new MockHandler( + is_array($response) ? $response : [$response] + ); $history = Middleware::history($this->historyContainer); diff --git a/tests/integration/Resources/SubscriberTest.php b/tests/integration/Resources/SubscriberTest.php index 1d70e67..687e6fa 100644 --- a/tests/integration/Resources/SubscriberTest.php +++ b/tests/integration/Resources/SubscriberTest.php @@ -22,6 +22,7 @@ use D3\KlicktippPhpClient\Resources\Subscriber; use D3\KlicktippPhpClient\tests\integration\IntegrationTestCase; use Generator; use GuzzleHttp\Psr7\Response; +use PHPUnit\Framework\MockObject\Rule\InvokedCount; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use ReflectionException; @@ -78,7 +79,7 @@ class SubscriberTest extends IntegrationTestCase * @covers \D3\KlicktippPhpClient\Resources\Subscriber::get * @dataProvider getDataProvider */ - public function testGet(ResponseInterface $response, ?SubscriberEntity $expected, bool $expectException = false) + public function testGet(ResponseInterface $response, ?array $expected, bool $expectException = false) { $sut = new Subscriber($this->getConnectionMock($response)); @@ -86,14 +87,14 @@ class SubscriberTest extends IntegrationTestCase $this->expectException(BaseException::class); } - $this->assertEquals( - $expected, - $this->callMethod( - $sut, - 'get', - ['155988456'] - ) + $return = $this->callMethod( + $sut, + 'get', + ['155988456'] ); + + $this->assertInstanceOf(SubscriberEntity::class, $return); + $this->assertSame($expected, $return->toArray()); } public static function getDataProvider(): Generator @@ -133,7 +134,7 @@ class SubscriberTest extends IntegrationTestCase "fieldWebsite": "", "fieldBirthday": "", "fieldLeadValue": "" - }'), new SubscriberEntity([ + }'), [ "id" => "155988456", "listid" => "368370", "optin" => "28.12.2024 22:52:09", @@ -168,7 +169,7 @@ class SubscriberTest extends IntegrationTestCase "fieldWebsite" => "", "fieldBirthday" => "", "fieldLeadValue" => "", - ])]; + ]]; yield 'unknown id' => [new Response(404, [], ''), null, true]; yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true]; } @@ -566,4 +567,91 @@ class SubscriberTest extends IntegrationTestCase yield 'unknown subsriber' => [new Response(406, [], '{"error": 9}'), null, true]; yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true]; } + + /** + * @test + * @throws ReflectionException + * @covers \D3\KlicktippPhpClient\Resources\Subscriber::setSubscriber + * @dataProvider setSubscriberDataProvider + */ + public function testSetSubscriber( + array $responses, + ?string $foundId, + InvokedCount $updateInvocations, + InvokedCount $subscribeInvocations + ): void { + $entityMock = $this->getMockBuilder(SubscriberEntity::class) + ->getMock(); + + $sut = $this->getMockBuilder(Subscriber::class) + ->setConstructorArgs([$this->getConnectionMock($responses)]) + ->onlyMethods(['search', 'update', 'subscribe', 'get']) + ->getMock(); + $sut->expects($this->once())->method('search')->will( + $foundId ? $this->returnValue($foundId) : $this->throwException(new BaseException()) + ); + $sut->expects($updateInvocations)->method('update')->willReturn(true); + $sut->expects($subscribeInvocations)->method('subscribe')->willReturn('myId'); + $sut->expects($this->once())->method('get')->with( + $this->identicalTo('myId') + )->willReturn($entityMock); + + $this->callMethod( + $sut, + 'setSubscriber', + ['oldMailAddress'] + ); + } + + public static function setSubscriberDataProvider(): Generator + { + yield 'update' => [ + [ + new Response(200, [], '[true]'), + new Response(200, [], '[true]'), + new Response(200, [], '[true]'), + ], + 'myId', + self::once(), + self::never(), + ]; + yield 'subscribe' => [ + [ + new Response(200, [], '[true]'), + new Response(200, [], '[true]'), + new Response(200, [], '[true]'), + ], + null, + self::never(), + self::once(), + ]; + } + + /** + * @test + * @throws ReflectionException + * @covers \D3\KlicktippPhpClient\Resources\Subscriber::getSubscriberByMailAddress + */ + public function testGetSubscriberByMailAddress(): void + { + $responses = [ + new Response(200, [], '[true]'), + new Response(200, [], '[true]'), + ]; + + $sut = $this->getMockBuilder(Subscriber::class) + ->setConstructorArgs([$this->getConnectionMock($responses)]) + ->onlyMethods(['search', 'get']) + ->getMock(); + $sut->expects($this->once())->method('search')->willReturn('myId'); + $sut->expects($this->once())->method('get')->with( + $this->identicalTo('myId') + )->willReturn(new SubscriberEntity()); + + $this->callMethod( + $sut, + 'getSubscriberByMailAddress', + ['myMailAddress'] + ); + } }