From 6412ebbb35c683f1934f46ca03d1f3f3b27046a3 Mon Sep 17 00:00:00 2001 From: Daniel Seifert Date: Sun, 29 Dec 2024 00:49:07 +0100 Subject: [PATCH] add account + fields endpoint tests --- tests/README.md | 11 ++ tests/TestCase.php | 75 +++++++++++ tests/integration/IntegrationTestCase.php | 42 +++++++ tests/integration/Resources/AccountTest.php | 133 ++++++++++++++++++++ tests/integration/Resources/FieldTest.php | 95 ++++++++++++++ 5 files changed, 356 insertions(+) create mode 100644 tests/README.md create mode 100644 tests/TestCase.php create mode 100644 tests/integration/IntegrationTestCase.php create mode 100644 tests/integration/Resources/AccountTest.php create mode 100644 tests/integration/Resources/FieldTest.php diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..14c9e95 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,11 @@ +# Installation + +``` +composer create-project -s dev --prefer-source [--repository '{"type": "vcs", "url": "repository url"}'] d3/klicktipp-php-client . +``` + +# Run tests + +``` +./vendor/bin/phpunit [--no-coverage] [--coverage-html=cov] +``` diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..15996a9 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,75 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\KlicktippPhpClient\tests; + +use PHPUnit\Framework\TestCase as PhpUnitTestCase; +use ReflectionClass; +use ReflectionException; + +abstract class TestCase extends PhpUnitTestCase +{ + /** + * Calls a private or protected object method. + * + * @param object $object + * @param string $methodName + * @param array $arguments + * + * @return mixed + * @throws ReflectionException + */ + public function callMethod(object $object, string $methodName, array $arguments = []) + { + $class = new ReflectionClass($object); + $method = $class->getMethod($methodName); + $method->setAccessible(true); + return $method->invokeArgs($object, $arguments); + } + + /** + * Sets a private or protected property in defined class instance + * + * @param object $object + * @param string $valueName + * @param $value + * @throws ReflectionException + */ + public function setValue(object $object, string $valueName, $value): void + { + $reflection = new ReflectionClass($object); + $property = $reflection->getProperty($valueName); + $property->setAccessible(true); + $property->setValue($object, $value); + } + + /** + * get a private or protected property from defined class instance + * + * @param object $object + * @param string $valueName + * @return mixed + * @throws ReflectionException + */ + public function getValue(object $object, string $valueName) + { + $reflection = new ReflectionClass($object); + $property = $reflection->getProperty($valueName); + $property->setAccessible(true); + return $property->getValue($object); + } +} diff --git a/tests/integration/IntegrationTestCase.php b/tests/integration/IntegrationTestCase.php new file mode 100644 index 0000000..aba36ee --- /dev/null +++ b/tests/integration/IntegrationTestCase.php @@ -0,0 +1,42 @@ + + * @link https://www.oxidmodule.com + */ + +namespace D3\KlicktippPhpClient\tests\integration; + +use D3\KlicktippPhpClient\Connection; +use D3\KlicktippPhpClient\tests\TestCase; +use GuzzleHttp\Client; +use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; +use Psr\Http\Message\ResponseInterface; + +/** + * @coversNothing + */ +class IntegrationTestCase extends TestCase +{ + public function getConnectionMock(ResponseInterface $response): Connection + { + $mock = new MockHandler([$response]); + + $handlerStack = HandlerStack::create($mock); + $client = new Client(['handler' => $handlerStack]); + + $connection = new Connection('userName', 'password'); + $connection->setClient($client); + + return $connection; + } +} diff --git a/tests/integration/Resources/AccountTest.php b/tests/integration/Resources/AccountTest.php new file mode 100644 index 0000000..afb06ae --- /dev/null +++ b/tests/integration/Resources/AccountTest.php @@ -0,0 +1,133 @@ + + * @link https://www.oxidmodule.com + */ + +namespace D3\KlicktippPhpClient\tests\integration\Resources; + +use D3\KlicktippPhpClient\Exceptions\BaseException; +use D3\KlicktippPhpClient\Resources\Account; +use D3\KlicktippPhpClient\tests\integration\IntegrationTestCase; +use Generator; +use GuzzleHttp\Psr7\Response; +use Psr\Http\Message\ResponseInterface; +use ReflectionException; + +/** + * @coversNothing + */ +class AccountTest extends IntegrationTestCase +{ + /** + * @test + * @throws ReflectionException + * @covers \D3\KlicktippPhpClient\Resources\Account::login + * @dataProvider loginDataProvider + */ + public function testLogin(ResponseInterface $response, array $expected, bool $expectException = false): void + { + $sut = new Account($this->getConnectionMock($response)); + + if ($expectException) { + $this->expectException(BaseException::class); + } + + $this->assertEquals( + $expected, + $this->callMethod( + $sut, + 'login', + ) + ); + } + + public static function loginDataProvider(): Generator + { + yield 'success' => [new Response(200, [], '{ + "sessid": "nFnp4uLZCnc3dIEl9PrXgjoUuaJSyJIKpLyU9HH5rxw", + "session_name": "SSESS5bc3b84d3f2031474d7722e94851cff5", + "account": { + "uid": "12345", + "status": "1", + "usergroup": "16", + "email": "info@mydomain.com", + "username": "KTAPIdev", + "firstname": "Developer", + "lastname": "Klicktipper", + "company": "Customer GmbH", + "website": "www.mydomain.de", + "street": "Am Hafen 6", + "city": "Hamburg", + "state": "", + "zip": "20123", + "country": "DE", + "phone": "+49211123456789", + "fax": "", + "affid": "123456" + } + }'), [ + 'sessid' => 'nFnp4uLZCnc3dIEl9PrXgjoUuaJSyJIKpLyU9HH5rxw', + 'session_name' => 'SSESS5bc3b84d3f2031474d7722e94851cff5', + 'account' => [ + 'uid' => '12345', + 'status' => '1', + 'usergroup' => '16', + 'email' => 'info@mydomain.com', + 'username' => 'KTAPIdev', + 'firstname' => 'Developer', + 'lastname' => 'Klicktipper', + 'company' => 'Customer GmbH', + 'website' => 'www.mydomain.de', + 'street' => 'Am Hafen 6', + 'city' => 'Hamburg', + 'state' => '', + 'zip' => '20123', + 'country' => 'DE', + 'phone' => '+49211123456789', + 'fax' => '', + 'affid' => '123456', + ], + ]]; + yield 'wrong credentials' => [new Response(401, [], '["Falscher Benutzername oder Passwort."]'), [], true]; + yield 'already logged in' => [new Response(406, [], '["Sie sind bereits eingeloggt."]'), [], true]; + } + + /** + * @test + * @throws ReflectionException + * @covers \D3\KlicktippPhpClient\Resources\Account::logout + * @dataProvider logoutDataProvider + */ + public function testLogout(ResponseInterface $response, bool $expected, bool $expectException = false): void + { + $sut = new Account($this->getConnectionMock($response)); + + if ($expectException) { + $this->expectException(BaseException::class); + } + + $this->assertEquals( + $expected, + $this->callMethod( + $sut, + 'logout', + ) + ); + } + + public static function logoutDataProvider(): Generator + { + yield 'success' => [new Response(200, [], '[true]'), true]; + yield 'already logged out' => [new Response(406, [], '["Benutzer nicht eingeloggt."]'), false, true]; + } +} diff --git a/tests/integration/Resources/FieldTest.php b/tests/integration/Resources/FieldTest.php new file mode 100644 index 0000000..3a3d64f --- /dev/null +++ b/tests/integration/Resources/FieldTest.php @@ -0,0 +1,95 @@ + + * @link https://www.oxidmodule.com + */ + +namespace D3\KlicktippPhpClient\tests\integration\Resources; + +use D3\KlicktippPhpClient\Entities\FieldList; +use D3\KlicktippPhpClient\Exceptions\BaseException; +use D3\KlicktippPhpClient\Resources\Field; +use D3\KlicktippPhpClient\tests\integration\IntegrationTestCase; +use Generator; +use GuzzleHttp\Psr7\Response; +use Psr\Http\Message\ResponseInterface; +use ReflectionException; + +/** + * @coversNothing + */ +class FieldTest extends IntegrationTestCase +{ + /** + * @test + * @throws ReflectionException + * @covers \D3\KlicktippPhpClient\Resources\Field::index + * @dataProvider indexDataProvider + */ + public function testIndex(ResponseInterface $response, ?FieldList $expected, bool $expectException = false) + { + $sut = new Field($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, [], '{ + "fieldFirstName": "Vorname", + "fieldLastName": "Nachname", + "fieldCompanyName": "Firma", + "fieldStreet1": "Straße 1", + "fieldStreet2": "Straße 2", + "fieldCity": "Stadt", + "fieldState": "Bundesland", + "fieldZip": "Postleitzahl", + "fieldCountry": "Land", + "fieldPrivatePhone": "Telefon (Privat)", + "fieldMobilePhone": "Telefon (Mobil)", + "fieldPhone": "Telefon", + "fieldFax": "Fax", + "fieldWebsite": "Website", + "fieldBirthday": "Geburtstag", + "fieldLeadValue": "LeadValue" + }'), new FieldList([ + "fieldFirstName" => "Vorname", + "fieldLastName" => "Nachname", + "fieldCompanyName" => "Firma", + "fieldStreet1" => "Straße 1", + "fieldStreet2" => "Straße 2", + "fieldCity" => "Stadt", + "fieldState" => "Bundesland", + "fieldZip" => "Postleitzahl", + "fieldCountry" => "Land", + "fieldPrivatePhone" => "Telefon (Privat)", + "fieldMobilePhone" => "Telefon (Mobil)", + "fieldPhone" => "Telefon", + "fieldFax" => "Fax", + "fieldWebsite" => "Website", + "fieldBirthday" => "Geburtstag", + "fieldLeadValue" => "LeadValue", + ])]; + 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]; + } +}