2025-01-05 15:28:57 +01:00

698 regels
25 KiB
PHP

<?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\integration\Resources;
use D3\KlicktippPhpClient\Entities\Subscriber as SubscriberEntity;
use D3\KlicktippPhpClient\Entities\SubscriberList;
use D3\KlicktippPhpClient\Exceptions\BaseException;
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;
/**
* @coversNothing
*/
class SubscriberTest extends IntegrationTestCase
{
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Model::__construct
*/
public function testConstruct(): void
{
$connection = $this->getConnectionMock(new Response(200, [], json_encode([])));
$sut = new Subscriber($connection);
$this->assertSame(
$connection,
$this->getValue($sut, 'connection')
);
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::index
* @dataProvider indexDataProvider
*/
public function testIndex(ResponseInterface $response, ?SubscriberList $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'index',
)
);
}
public static function indexDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '[
"29513792",
"29513793",
"29513794",
"29513795"
]'), new SubscriberList([
"29513792",
"29513793",
"29513794",
"29513795",
])];
yield 'no subscriber available' => [new Response(404, [], '["Es existieren keine Kontakte."]'), null, true];
yield 'wrong request type' => [new Response(406, [], '["Bei der Erstellung des Objekt ist ein Fehler aufgetreten."]'), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::get
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::getEntity
* @dataProvider getDataProvider
*/
public function testGet(ResponseInterface $response, ?array $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$return = $this->callMethod(
$sut,
'getEntity',
['155988456']
);
$this->assertInstanceOf(SubscriberEntity::class, $return);
$this->assertSame($expected, $return->toArray());
}
public static function getDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '{
"'.Subscriber::ID.'": "155988456",
"'.Subscriber::LISTID.'": "368370",
"'.Subscriber::OPTIN.'": "28.12.2024 22:52:09",
"'.Subscriber::OPTIN_IP.'": "0.0.0.0 - By API Request",
"'.Subscriber::EMAIL.'": "testsubscriber@mydomain.com",
"'.Subscriber::STATUS.'": "Opt-In Pending",
"'.Subscriber::BOUNCE.'": "Not Bounced",
"'.Subscriber::DATE.'": "",
"'.Subscriber::IP.'": "0.0.0.0 - By API Request",
"'.Subscriber::UNSUBSCRIPTION.'": "",
"'.Subscriber::UNSUBSCRIPTION_IP.'": "0.0.0.0",
"'.Subscriber::REFERRER.'": "",
"'.Subscriber::SMS_PHONE.'": null,
"'.Subscriber::SMS_STATUS.'": null,
"'.Subscriber::SMS_BOUNCE.'": null,
"'.Subscriber::SMS_DATE.'": "",
"'.Subscriber::SMS_UNSUBSCRIPTION.'": "",
"'.Subscriber::SMS_REFERRER.'": null,
"'.Subscriber::FIELD_FIRSTNAME.'": "",
"'.Subscriber::FIELD_LASTNAME.'": "",
"'.Subscriber::FIELD_COMPANYNAME.'": "",
"'.Subscriber::FIELD_STREET1.'": "",
"'.Subscriber::FIELD_STREET2.'": "",
"'.Subscriber::FIELD_CITY.'": "",
"'.Subscriber::FIELD_STATE.'": "",
"'.Subscriber::FIELD_ZIP.'": "",
"'.Subscriber::FIELD_COUNTRY.'": "",
"'.Subscriber::FIELD_PRIVATEPHONE.'": "",
"'.Subscriber::FIELD_MOBILEPHONE.'": "",
"'.Subscriber::FIELD_PHONE.'": "",
"'.Subscriber::FIELD_FAX.'": "",
"'.Subscriber::FIELD_WEBSITE.'": "",
"'.Subscriber::FIELD_BIRTHDAY.'": "",
"'.Subscriber::FIELD_LEADVALUE.'": ""
}'), [
Subscriber::ID => "155988456",
Subscriber::LISTID => "368370",
Subscriber::OPTIN => "28.12.2024 22:52:09",
Subscriber::OPTIN_IP => "0.0.0.0 - By API Request",
Subscriber::EMAIL => "testsubscriber@mydomain.com",
Subscriber::STATUS => "Opt-In Pending",
Subscriber::BOUNCE => "Not Bounced",
Subscriber::DATE => "",
Subscriber::IP => "0.0.0.0 - By API Request",
Subscriber::UNSUBSCRIPTION => "",
Subscriber::UNSUBSCRIPTION_IP => "0.0.0.0",
Subscriber::REFERRER => "",
Subscriber::SMS_PHONE => null,
Subscriber::SMS_STATUS => null,
Subscriber::SMS_BOUNCE => null,
Subscriber::SMS_DATE => "",
Subscriber::SMS_UNSUBSCRIPTION => "",
Subscriber::SMS_REFERRER => null,
Subscriber::FIELD_FIRSTNAME => "",
Subscriber::FIELD_LASTNAME => "",
Subscriber::FIELD_COMPANYNAME => "",
Subscriber::FIELD_STREET1 => "",
Subscriber::FIELD_STREET2 => "",
Subscriber::FIELD_CITY => "",
Subscriber::FIELD_STATE => "",
Subscriber::FIELD_ZIP => "",
Subscriber::FIELD_COUNTRY => "",
Subscriber::FIELD_PRIVATEPHONE => "",
Subscriber::FIELD_MOBILEPHONE => "",
Subscriber::FIELD_PHONE => "",
Subscriber::FIELD_FAX => "",
Subscriber::FIELD_WEBSITE => "",
Subscriber::FIELD_BIRTHDAY => "",
Subscriber::FIELD_LEADVALUE => "",
]];
yield 'unknown id' => [new Response(404, [], ''), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::search
* @dataProvider searchDataProvider
*/
public function testSearch(ResponseInterface $response, ?string $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'search',
['testsubscriber@mydomain.com']
)
);
}
public static function searchDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '[155986456]'), '155986456'];
yield 'unknown id' => [new Response(404, [], '[Diesen Kontakt gibt es nicht.]'), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::subscribe
* @dataProvider subscribeDataProvider
*/
public function testSubscribe(ResponseInterface $response, ?string $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'subscribe',
['testsubscriber@mydomain.com', '1234567', '2345678', ['field1' => 'abcd', 'field2' => 'efgh']]
)
);
/** @var RequestInterface $request */
$request = current($this->getHistoryContainer())['request'];
$requestFormParams = $request->getBody()->getContents();
$this->assertMatchesRegularExpression('/fields%5Bfield1%5D=abcd/m', $requestFormParams);
$this->assertMatchesRegularExpression('/fields%5Bfield2%5D=efgh/m', $requestFormParams);
$this->assertMatchesRegularExpression('/email=testsubscriber%40mydomain.com/m', $requestFormParams);
}
public static function subscribeDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '{
"'.Subscriber::ID.'": "155988456",
"'.Subscriber::LISTID.'": "368370",
"'.Subscriber::OPTIN.'": "28.12.2024 22:52:09",
"'.Subscriber::OPTIN_IP.'": "0.0.0.0 - By API Request",
"'.Subscriber::EMAIL.'": "testsubscriber@mydomain.com",
"'.Subscriber::STATUS.'": "Opt-In Pending",
"'.Subscriber::BOUNCE.'": "Not Bounced",
"'.Subscriber::DATE.'": "",
"'.Subscriber::IP.'": "0.0.0.0 - By API Request",
"'.Subscriber::UNSUBSCRIPTION.'": "",
"'.Subscriber::UNSUBSCRIPTION_IP.'": "0.0.0.0",
"'.Subscriber::REFERRER.'": "",
"'.Subscriber::SMS_PHONE.'": null,
"'.Subscriber::SMS_STATUS.'": null,
"'.Subscriber::SMS_BOUNCE.'": null,
"'.Subscriber::SMS_DATE.'": "",
"'.Subscriber::SMS_UNSUBSCRIPTION.'": "",
"'.Subscriber::SMS_REFERRER.'": null,
"'.Subscriber::FIELD_FIRSTNAME.'": "",
"'.Subscriber::FIELD_LASTNAME.'": "",
"'.Subscriber::FIELD_COMPANYNAME.'": "",
"'.Subscriber::FIELD_STREET1.'": "",
"'.Subscriber::FIELD_STREET2.'": "",
"'.Subscriber::FIELD_CITY.'": "",
"'.Subscriber::FIELD_STATE.'": "",
"'.Subscriber::FIELD_ZIP.'": "",
"'.Subscriber::FIELD_COUNTRY.'": "",
"'.Subscriber::FIELD_PRIVATEPHONE.'": "",
"'.Subscriber::FIELD_MOBILEPHONE.'": "",
"'.Subscriber::FIELD_PHONE.'": "",
"'.Subscriber::FIELD_FAX.'": "",
"'.Subscriber::FIELD_WEBSITE.'": "",
"'.Subscriber::FIELD_BIRTHDAY.'": "",
"'.Subscriber::FIELD_LEADVALUE.'": ""
}'), '155988456'];
yield 'missing mail' => [new Response(401, [], '{"error": 32}'), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::unsubscribe
* @dataProvider unsubscribeDataProvider
*/
public function testUnsubscribe(ResponseInterface $response, ?bool $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'unsubscribe',
['testsubscriber@mydomain.com']
)
);
}
public static function unsubscribeDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '[true]'), true];
yield 'missing mail' => [new Response(401, [], '[Missing required argument email]'), null, true];
yield 'unknown mail' => [new Response(406, [], '{"error": 7}'), null, true];
yield 'pending opt in' => [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::tag
* @dataProvider tagDataProvider
*/
public function testTag(ResponseInterface $response, ?bool $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'tag',
['testsubscriber@mydomain.com', ['2354758', ' 2354858']]
)
);
/** @var RequestInterface $request */
$request = current($this->getHistoryContainer())['request'];
$requestFormParams = $request->getBody()->getContents();
$this->assertMatchesRegularExpression('/tagids%5B0%5D=2354758/m', $requestFormParams);
$this->assertMatchesRegularExpression('/tagids%5B1%5D=2354858/m', $requestFormParams);
$this->assertMatchesRegularExpression('/email=testsubscriber%40mydomain.com/m', $requestFormParams);
}
public static function tagDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '[true]'), true];
yield 'missing mail' => [new Response(401, [], '[Missing required argument email]'), null, true];
yield 'unknown mail / tag' => [new Response(406, [], '{"error": 7}'), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::untag
* @dataProvider untagDataProvider
*/
public function testUntag(ResponseInterface $response, ?bool $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'untag',
['testsubscriber@mydomain.com', '2354758']
)
);
}
public static function untagDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '[true]'), true];
yield 'missing mail' => [new Response(401, [], '[Missing required argument email]'), null, true];
yield 'unknown mail' => [new Response(406, [], '{"error": 7}'), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::tagged
* @dataProvider taggedDataProvider
*/
public function testTagged(ResponseInterface $response, ?array $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$return = $this->callMethod(
$sut,
'tagged',
['2354758']
);
$this->assertInstanceOf(SubscriberList::class, $return);
$this->assertSame($expected, $return->toArray());
}
public static function taggedDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '{
"155986456": "1735426641",
"155986457": "1735426642"
}'), [
"155986456" => "1735426641",
"155986457" => "1735426642",
]];
yield 'missing tagid' => [new Response(401, [], '[Missing required argument tagid]'), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::update
* @dataProvider updateDataProvider
*/
public function testUpdate(ResponseInterface $response, ?bool $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'update',
['2354758', [Subscriber::FIELD_CITY => 'Berlin', Subscriber::FIELD_STREET2 => 'Straße unter den Linden 25'], 'mymail@mydomain.com']
)
);
/** @var RequestInterface $request */
$request = current($this->getHistoryContainer())['request'];
$requestFormParams = $request->getBody()->getContents();
$this->assertMatchesRegularExpression('/fields%5BfieldCity%5D=Berlin/m', $requestFormParams);
$this->assertMatchesRegularExpression('/fields%5BfieldStreet2%5D=Stra%C3%9Fe\+unter\+den\+Linden\+25/m', $requestFormParams);
$this->assertMatchesRegularExpression('/newemail=mymail%40mydomain.com/m', $requestFormParams);
}
public static function updateDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '[true]'), true];
yield 'unknown subscriber' => [new Response(406, [], '["Der Kontakt existiert nicht."]'), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::delete
* @dataProvider deleteDataProvider
*/
public function testDelete(ResponseInterface $response, ?bool $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'delete',
['2354758']
)
);
}
public static function deleteDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '[true]'), true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::signin
* @dataProvider signinDataProvider
*/
public function testSignin(ResponseInterface $response, ?string $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'signin',
['7gefzp8255z8z8469', 'subsriber@mydomain.com', ['field1' => 'abcd', 'field2' => 'efgh']]
)
);
/** @var RequestInterface $request */
$request = current($this->getHistoryContainer())['request'];
$requestFormParams = $request->getBody()->getContents();
$this->assertMatchesRegularExpression('/fields%5Bfield1%5D=abcd/m', $requestFormParams);
$this->assertMatchesRegularExpression('/fields%5Bfield2%5D=efgh/m', $requestFormParams);
$this->assertMatchesRegularExpression('/apikey=7gefzp8255z8z8469/m', $requestFormParams);
}
public static function signinDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '["https://klick.marketron.io/pending/p9i3z8e6az2xxgcnzzpze5fa"]'), 'https://klick.marketron.io/pending/p9i3z8e6az2xxgcnzzpze5fa'];
yield 'missing mandatory data' => [new Response(401, [], '["Missing required argument apikey"]'), null, true];
yield 'wrong api key' => [new Response(500, [], ''), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::signout
* @dataProvider signoutDataProvider
*/
public function testSignout(ResponseInterface $response, ?bool $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'signout',
['7gefzp8255z8z8469', 'subsriber@mydomain.com']
)
);
}
public static function signoutDataProvider(): Generator
{
// ToDo: unknown success result
//yield 'success' => [new Response(200, [], '[true]'), true];
yield 'unknown error' => [new Response(406, [], '{"error": 403}'), null, true];
yield 'access denied' => [new Response(403, [], '["API Zugriff verweigert"]'), null, true];
}
/**
* @test
* @throws ReflectionException
* @covers \D3\KlicktippPhpClient\Resources\Subscriber::signoff
* @dataProvider signoffDataProvider
*/
public function testSignoff(ResponseInterface $response, ?bool $expected, bool $expectException = false): void
{
$sut = new Subscriber($this->getConnectionMock($response));
if ($expectException) {
$this->expectException(BaseException::class);
}
$this->assertEquals(
$expected,
$this->callMethod(
$sut,
'signoff',
['7gefzp8255z8z8469', 'subsriber@mydomain.com']
)
);
}
public static function signoffDataProvider(): Generator
{
yield 'success' => [new Response(200, [], '[true]'), true];
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', 'getEntity'])
->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('getEntity')->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', 'getEntity'])
->getMock();
$sut->expects($this->once())->method('search')->willReturn('myId');
$sut->expects($this->once())->method('getEntity')->with(
$this->identicalTo('myId')
)->willReturn(new SubscriberEntity());
$this->callMethod(
$sut,
'getSubscriberByMailAddress',
['myMailAddress']
);
}
}