8
0

deal with missing entity endpoint

Dieser Commit ist enthalten in:
Daniel Seifert 2025-01-17 11:14:11 +01:00
Ursprung d7b24bb81c
Commit cb32040f6e
13 geänderte Dateien mit 185 neuen und 16 gelöschten Zeilen

Datei anzeigen

@ -19,11 +19,14 @@ namespace D3\KlicktippPhpClient\Entities;
use D3\KlicktippPhpClient\Exceptions\CommunicationException; use D3\KlicktippPhpClient\Exceptions\CommunicationException;
use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException; use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Account as AccountEndpoint; use D3\KlicktippPhpClient\Resources\Account as AccountEndpoint;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
class Account extends Entity class Account extends Entity
{ {
use EndpointTrait;
private ?AccountEndpoint $endpoint; private ?AccountEndpoint $endpoint;
public function __construct(array $elements = [], ?AccountEndpoint $endpoint = null) public function __construct(array $elements = [], ?AccountEndpoint $endpoint = null)
@ -193,9 +196,10 @@ class Account extends Entity
/** /**
* @return null|bool * @return null|bool
* @throws CommunicationException * @throws CommunicationException
* @throws MissingEndpointException
*/ */
public function persist(): ?bool public function persist(): ?bool
{ {
return $this->endpoint?->update(); return $this->getEndpoint()->update();
} }
} }

Datei anzeigen

@ -0,0 +1,36 @@
<?php
/**
* Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\KlicktippPhpClient\Entities;
use Assert\Assert;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Model;
trait EndpointTrait
{
private function getEndpoint(): Model
{
Assert::lazy()
->setExceptionClass(MissingEndpointException::class)
->that($this->endpoint)
->isInstanceOf(Model::class)
->verifyNow();
return $this->endpoint;
}
}

Datei anzeigen

@ -18,10 +18,13 @@ declare(strict_types=1);
namespace D3\KlicktippPhpClient\Entities; namespace D3\KlicktippPhpClient\Entities;
use D3\KlicktippPhpClient\Exceptions\CommunicationException; use D3\KlicktippPhpClient\Exceptions\CommunicationException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Field as FieldEndpoint; use D3\KlicktippPhpClient\Resources\Field as FieldEndpoint;
class Field extends Entity class Field extends Entity
{ {
use EndpointTrait;
private ?FieldEndpoint $endpoint; private ?FieldEndpoint $endpoint;
public function __construct(array $elements = [], ?FieldEndpoint $endpoint = null) public function __construct(array $elements = [], ?FieldEndpoint $endpoint = null)
@ -50,11 +53,12 @@ class Field extends Entity
/** /**
* @return null|bool * @return null|bool
* @throws CommunicationException * @throws CommunicationException
* @throws MissingEndpointException
*/ */
public function persist(): ?bool public function persist(): ?bool
{ {
return !is_null($this->getId()) ? return !is_null($this->getId()) ?
$this->endpoint?->update( $this->getEndpoint()->update(
$this->getId(), $this->getId(),
$this->getName() ?? '' $this->getName() ?? ''
) : ) :

Datei anzeigen

@ -18,12 +18,15 @@ declare(strict_types=1);
namespace D3\KlicktippPhpClient\Entities; namespace D3\KlicktippPhpClient\Entities;
use D3\KlicktippPhpClient\Exceptions\CommunicationException; use D3\KlicktippPhpClient\Exceptions\CommunicationException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Subscriber as SubscriberEndpoint; use D3\KlicktippPhpClient\Resources\Subscriber as SubscriberEndpoint;
use DateTime; use DateTime;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
class Subscriber extends Entity class Subscriber extends Entity
{ {
use EndpointTrait;
public const STATUS_SUBSCRIBED = 'subscribed'; public const STATUS_SUBSCRIBED = 'subscribed';
public const BOUNCE_NOTBOUNCED = 'Not Bounced'; public const BOUNCE_NOTBOUNCED = 'Not Bounced';
@ -314,11 +317,12 @@ class Subscriber extends Entity
/** /**
* @return null|bool * @return null|bool
* @throws CommunicationException * @throws CommunicationException
* @throws MissingEndpointException
*/ */
public function persist(): ?bool public function persist(): ?bool
{ {
if (!is_null($this->getId())) { if (!is_null($this->getId())) {
$return = $this->endpoint?->update( $return = $this->getEndpoint()->update(
$this->getId(), $this->getId(),
$this->getFields()->toArray(), $this->getFields()->toArray(),
$this->getEmailAddress() ?? '', $this->getEmailAddress() ?? '',
@ -335,14 +339,11 @@ class Subscriber extends Entity
/** /**
* @throws CommunicationException * @throws CommunicationException
* @throws MissingEndpointException
*/ */
protected function persistTags(): void protected function persistTags(): void
{ {
if (!$this->endpoint instanceof SubscriberEndpoint) { $currentTags = $this->getEndpoint()->getEntity($this->getId() ?? '')->getTags();
return;
}
$currentTags = $this->endpoint->getEntity($this->getId() ?? '')->getTags();
$removeTags = array_diff( $removeTags = array_diff(
$currentTags?->toArray() ?? [], $currentTags?->toArray() ?? [],
@ -352,7 +353,7 @@ class Subscriber extends Entity
if (count($removeTags)) { if (count($removeTags)) {
foreach ($removeTags as $removeTag) { foreach ($removeTags as $removeTag) {
if (!is_null($this->getEmailAddress())) { if (!is_null($this->getEmailAddress())) {
$this->endpoint->untag($this->getEmailAddress(), $removeTag); $this->getEndpoint()->untag($this->getEmailAddress(), $removeTag);
} }
} }
} }
@ -363,7 +364,7 @@ class Subscriber extends Entity
); );
if (count($addTags)) { if (count($addTags)) {
if (!is_null($this->getEmailAddress())) { if (!is_null($this->getEmailAddress())) {
$this->endpoint->tag($this->getEmailAddress(), $addTags); $this->getEndpoint()->tag($this->getEmailAddress(), $addTags);
} }
} }
} }
@ -384,7 +385,7 @@ class Subscriber extends Entity
?string $smsNumber = null ?string $smsNumber = null
): void { ): void {
if (!$this->isSubscribed()) { if (!$this->isSubscribed()) {
$this->endpoint->subscribe( $this->getEndpoint()->subscribe(
$this->getEmailAddress(), $this->getEmailAddress(),
$listId, $listId,
$tagId, $tagId,

Datei anzeigen

@ -18,10 +18,13 @@ declare(strict_types=1);
namespace D3\KlicktippPhpClient\Entities; namespace D3\KlicktippPhpClient\Entities;
use D3\KlicktippPhpClient\Exceptions\CommunicationException; use D3\KlicktippPhpClient\Exceptions\CommunicationException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\SubscriptionProcess; use D3\KlicktippPhpClient\Resources\SubscriptionProcess;
class Subscription extends Entity class Subscription extends Entity
{ {
use EndpointTrait;
private ?SubscriptionProcess $endpoint; private ?SubscriptionProcess $endpoint;
public function __construct(array $elements = [], ?SubscriptionProcess $endpoint = null) public function __construct(array $elements = [], ?SubscriptionProcess $endpoint = null)
@ -78,11 +81,12 @@ class Subscription extends Entity
/** /**
* @return null|bool * @return null|bool
* @throws CommunicationException * @throws CommunicationException
* @throws MissingEndpointException
*/ */
public function persist(): ?bool public function persist(): ?bool
{ {
return !is_null($this->getListId()) ? return !is_null($this->getListId()) ?
$this->endpoint?->update( $this->getEndpoint()->update(
$this->getListId(), $this->getListId(),
$this->getName() ?? '' $this->getName() ?? ''
) : ) :

Datei anzeigen

@ -18,10 +18,13 @@ declare(strict_types=1);
namespace D3\KlicktippPhpClient\Entities; namespace D3\KlicktippPhpClient\Entities;
use D3\KlicktippPhpClient\Exceptions\CommunicationException; use D3\KlicktippPhpClient\Exceptions\CommunicationException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Tag as TagEndpoint; use D3\KlicktippPhpClient\Resources\Tag as TagEndpoint;
class Tag extends Entity class Tag extends Entity
{ {
use EndpointTrait;
private ?TagEndpoint $endpoint; private ?TagEndpoint $endpoint;
public function __construct(array $elements = [], ?TagEndpoint $endpoint = null) public function __construct(array $elements = [], ?TagEndpoint $endpoint = null)
@ -62,11 +65,12 @@ class Tag extends Entity
/** /**
* @return null|bool * @return null|bool
* @throws CommunicationException * @throws CommunicationException
* @throws MissingEndpointException
*/ */
public function persist(): ?bool public function persist(): ?bool
{ {
return !is_null($this->getId()) ? return !is_null($this->getId()) ?
$this->endpoint?->update( $this->getEndpoint()->update(
$this->getId(), $this->getId(),
$this->getName() ?? '', $this->getName() ?? '',
$this->getText() ?? '' $this->getText() ?? ''

Datei anzeigen

@ -0,0 +1,29 @@
<?php
/**
* Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\KlicktippPhpClient\Exceptions;
use Assert\LazyAssertionException;
class MissingEndpointException extends LazyAssertionException implements KlicktippExceptionInterface
{
public function __construct($message, array $errors)
{
unset($message);
parent::__construct('required endpoint for this action missing', $errors);
}
}

Datei anzeigen

@ -19,6 +19,7 @@ namespace D3\KlicktippPhpClient\tests\unit\Entities;
use D3\KlicktippPhpClient\Entities\Account; use D3\KlicktippPhpClient\Entities\Account;
use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException; use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Account as AccountEndpoint; use D3\KlicktippPhpClient\Resources\Account as AccountEndpoint;
use D3\KlicktippPhpClient\tests\TestCase; use D3\KlicktippPhpClient\tests\TestCase;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
@ -526,6 +527,10 @@ class AccountTest extends TestCase
$sut = new Account([AccountEndpoint::UID => 'foo'], $endpointSet ? $endpointMock : null); $sut = new Account([AccountEndpoint::UID => 'foo'], $endpointSet ? $endpointMock : null);
if (!$endpointSet) {
$this->expectException(MissingEndpointException::class);
}
$this->assertSame( $this->assertSame(
$expectedReturn, $expectedReturn,
$this->callMethod( $this->callMethod(

Datei anzeigen

@ -19,6 +19,7 @@ namespace D3\KlicktippPhpClient\tests\unit\Entities;
use D3\KlicktippPhpClient\Entities\Field; use D3\KlicktippPhpClient\Entities\Field;
use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException; use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Field as FieldEndpoint; use D3\KlicktippPhpClient\Resources\Field as FieldEndpoint;
use D3\KlicktippPhpClient\tests\TestCase; use D3\KlicktippPhpClient\tests\TestCase;
use Generator; use Generator;
@ -184,6 +185,10 @@ class FieldTest extends TestCase
$endpointSet ? $endpointMock : null $endpointSet ? $endpointMock : null
); );
if (!$endpointSet) {
$this->expectException(MissingEndpointException::class);
}
$this->assertSame( $this->assertSame(
$expectedReturn, $expectedReturn,
$this->callMethod( $this->callMethod(

Datei anzeigen

@ -19,6 +19,7 @@ namespace D3\KlicktippPhpClient\tests\unit\Entities;
use D3\KlicktippPhpClient\Entities\Subscriber; use D3\KlicktippPhpClient\Entities\Subscriber;
use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException; use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Subscriber as SubscriberEndpoint; use D3\KlicktippPhpClient\Resources\Subscriber as SubscriberEndpoint;
use D3\KlicktippPhpClient\tests\TestCase; use D3\KlicktippPhpClient\tests\TestCase;
use DateTime; use DateTime;
@ -844,6 +845,10 @@ class SubscriberTest extends TestCase
->getMock(); ->getMock();
$sut->expects($persistTagsInvocation)->method('persistTags'); $sut->expects($persistTagsInvocation)->method('persistTags');
if (!$endpointSet) {
$this->expectException(MissingEndpointException::class);
}
$this->assertSame( $this->assertSame(
$expectedReturn, $expectedReturn,
$this->callMethod( $this->callMethod(
@ -856,7 +861,7 @@ class SubscriberTest extends TestCase
public static function persistDataProvider(): Generator public static function persistDataProvider(): Generator
{ {
yield 'has endpoint' => [true, 'fixture', self::once(), self::once(), true]; yield 'has endpoint' => [true, 'fixture', self::once(), self::once(), true];
yield 'has no endpoint' => [false, 'fixture', self::never(), self::once(), null]; yield 'has no endpoint' => [false, 'fixture', self::never(), self::never(), null];
yield 'has endpoint, no id' => [true, null, self::never(), self::never(), null]; yield 'has endpoint, no id' => [true, null, self::never(), self::never(), null];
} }
@ -895,6 +900,10 @@ class SubscriberTest extends TestCase
$sut->set('tags', $newTagList); $sut->set('tags', $newTagList);
} }
if (!$endpointSet) {
$this->expectException(MissingEndpointException::class);
}
$this->callMethod( $this->callMethod(
$sut, $sut,
'persistTags' 'persistTags'
@ -983,14 +992,14 @@ class SubscriberTest extends TestCase
* @test * @test
* @throws ReflectionException * @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Entities\Subscriber::resubscribe * @covers \D3\KlicktippPhpClient\Entities\Subscriber::resubscribe
* @covers \D3\KlicktippPhpClient\Entities\Subscriber::getEndpoint
* @dataProvider resubscribeDataProvider * @dataProvider resubscribeDataProvider
*/ */
public function testReSubscribe( public function testReSubscribe(
bool $endpointSet, bool $endpointSet,
InvokedCount $subscribeExpections, InvokedCount $subscribeExpections,
bool $isSubscribed bool $isSubscribed
): void ): void {
{
$endpointMock = $this->getMockBuilder(SubscriberEndpoint::class) $endpointMock = $this->getMockBuilder(SubscriberEndpoint::class)
->disableOriginalConstructor() ->disableOriginalConstructor()
->onlyMethods(['subscribe']) ->onlyMethods(['subscribe'])
@ -1004,6 +1013,10 @@ class SubscriberTest extends TestCase
$sut->method('isSubscribed')->willReturn($isSubscribed); $sut->method('isSubscribed')->willReturn($isSubscribed);
$sut->method('getEmailAddress')->willReturn('mail@mydomain.tld'); $sut->method('getEmailAddress')->willReturn('mail@mydomain.tld');
if (!$endpointSet && !$isSubscribed) {
$this->expectException(MissingEndpointException::class);
}
$this->callMethod( $this->callMethod(
$sut, $sut,
'resubscribe', 'resubscribe',

Datei anzeigen

@ -19,6 +19,7 @@ namespace D3\KlicktippPhpClient\tests\unit\Entities;
use D3\KlicktippPhpClient\Entities\Subscription; use D3\KlicktippPhpClient\Entities\Subscription;
use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException; use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\SubscriptionProcess as SubscriptionEndpoint; use D3\KlicktippPhpClient\Resources\SubscriptionProcess as SubscriptionEndpoint;
use D3\KlicktippPhpClient\tests\TestCase; use D3\KlicktippPhpClient\tests\TestCase;
use Generator; use Generator;
@ -223,6 +224,10 @@ class SubscriptionTest extends TestCase
$endpointSet ? $endpointMock : null $endpointSet ? $endpointMock : null
); );
if (!$endpointSet) {
$this->expectException(MissingEndpointException::class);
}
$this->assertSame( $this->assertSame(
$expectedReturn, $expectedReturn,
$this->callMethod( $this->callMethod(

Datei anzeigen

@ -19,6 +19,7 @@ namespace D3\KlicktippPhpClient\tests\unit\Entities;
use D3\KlicktippPhpClient\Entities\Tag; use D3\KlicktippPhpClient\Entities\Tag;
use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException; use D3\KlicktippPhpClient\Exceptions\InvalidCredentialTypeException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\Resources\Tag as TagEndpoint; use D3\KlicktippPhpClient\Resources\Tag as TagEndpoint;
use D3\KlicktippPhpClient\tests\TestCase; use D3\KlicktippPhpClient\tests\TestCase;
use Generator; use Generator;
@ -198,6 +199,10 @@ class TagTest extends TestCase
$endpointSet ? $endpointMock : null $endpointSet ? $endpointMock : null
); );
if (!$endpointSet) {
$this->expectException(MissingEndpointException::class);
}
$this->assertSame( $this->assertSame(
$expectedReturn, $expectedReturn,
$this->callMethod( $this->callMethod(

Datei anzeigen

@ -0,0 +1,54 @@
<?php
/**
* Copyright (c) D3 Data Development (Inh. Thomas Dartsch)
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\KlicktippPhpClient\tests\unit\Exceptions;
use D3\KlicktippPhpClient\Exceptions\CommunicationException;
use D3\KlicktippPhpClient\Exceptions\MissingEndpointException;
use D3\KlicktippPhpClient\tests\TestCase;
use ReflectionException;
/**
* @covers \D3\KlicktippPhpClient\Exceptions\MissingEndpointException
*/
class MissingEndpointExceptionTest extends TestCase
{
/**
* @test
* @return void
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Exceptions\MissingEndpointException::__construct
*/
public function testConstructor(): void
{
/** @var MissingEndpointException $sutMock */
$sutMock = $this->getMockBuilder(MissingEndpointException::class)
->disableOriginalConstructor()
->getMock();
$this->callMethod(
$sutMock,
'__construct',
['myMessage', []]
);
$this->assertMatchesRegularExpression(
'/.*?endpoint.*?missing.*/i',
$sutMock->getMessage()
);
}
}