From 918e266dce71569c04be668cafb0e01f540b43b1 Mon Sep 17 00:00:00 2001 From: Jim Seconde Date: Thu, 30 Jan 2025 11:54:57 +0000 Subject: [PATCH] Test all client factory configurations --- phpunit.xml.dist | 12 +++ src/Account/ClientFactory.php | 1 - src/Client.php | 11 +++ src/Client/APIExceptionHandler.php | 5 + test/Account/ClientFactoryTest.php | 39 +++----- test/Application/ClientFactoryTest.php | 33 +++++++ test/Client/CallbackTest.php | 97 +++++++++++++++++++ test/ClientTest.php | 89 +++++++++++++++++ test/Conversation/ClientFactoryTest.php | 34 +++++++ test/Conversion/ClientFactoryTest.php | 32 ++++++ test/Conversion/ClientTest.php | 11 +++ test/Insights/ClientFactoryTest.php | 32 ++++++ test/Meetings/ClientFactoryTest.php | 35 +++++++ test/Messages/ClientFactoryTest.php | 38 ++++++++ test/NumberVerification/ClientFactoryTest.php | 44 +++++++++ test/Numbers/ClientFactoryTest.php | 32 ++++++ test/ProactiveConnect/ClientFactoryTest.php | 34 +++++++ test/Redact/ClientFactoryTest.php | 33 +++++++ test/SMS/ClientFactoryTest.php | 36 +++++++ test/Secrets/ClientFactoryTest.php | 58 +++++++++++ test/SimSwap/ClientFactoryTest.php | 40 ++++++++ test/Users/ClientFactoryTest.php | 32 ++++++ test/Verify/ClientFactoryTest.php | 35 +++++++ test/Verify2/ClientFactoryTest.php | 36 +++++++ .../VerifyObjects/TemplateFragmentTest.php | 61 ++++++++++++ test/Verify2/VerifyObjects/TemplateTest.php | 61 ++++++++++++ .../VerifyObjects/VerificationLocaleTest.php | 39 ++++++++ .../Verify2/VerifyObjects/VerifyEventTest.php | 62 ++++++++++++ .../VerifySilentAuthEventTest.php | 62 ++++++++++++ .../VerifyObjects/VerifyStatusUpdateTest.php | 62 ++++++++++++ .../VerifyWhatsAppInteractiveEventTest.php | 62 ++++++++++++ test/Voice/ClientFactoryTest.php | 32 ++++++ test/Webhook/FactoryTest.php | 81 ++++++++++++++++ 33 files changed, 1347 insertions(+), 24 deletions(-) create mode 100644 test/Application/ClientFactoryTest.php create mode 100644 test/Client/CallbackTest.php create mode 100644 test/Conversation/ClientFactoryTest.php create mode 100644 test/Conversion/ClientFactoryTest.php create mode 100644 test/Insights/ClientFactoryTest.php create mode 100644 test/Meetings/ClientFactoryTest.php create mode 100644 test/Messages/ClientFactoryTest.php create mode 100644 test/NumberVerification/ClientFactoryTest.php create mode 100644 test/Numbers/ClientFactoryTest.php create mode 100644 test/ProactiveConnect/ClientFactoryTest.php create mode 100644 test/Redact/ClientFactoryTest.php create mode 100644 test/SMS/ClientFactoryTest.php create mode 100644 test/Secrets/ClientFactoryTest.php create mode 100644 test/SimSwap/ClientFactoryTest.php create mode 100644 test/Users/ClientFactoryTest.php create mode 100644 test/Verify/ClientFactoryTest.php create mode 100644 test/Verify2/ClientFactoryTest.php create mode 100644 test/Verify2/VerifyObjects/TemplateFragmentTest.php create mode 100644 test/Verify2/VerifyObjects/TemplateTest.php create mode 100644 test/Verify2/VerifyObjects/VerificationLocaleTest.php create mode 100644 test/Verify2/VerifyObjects/VerifyEventTest.php create mode 100644 test/Verify2/VerifyObjects/VerifySilentAuthEventTest.php create mode 100644 test/Verify2/VerifyObjects/VerifyStatusUpdateTest.php create mode 100644 test/Verify2/VerifyObjects/VerifyWhatsAppInteractiveEventTest.php create mode 100644 test/Voice/ClientFactoryTest.php create mode 100644 test/Webhook/FactoryTest.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ff6973bd..bc3bb2f9 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -15,6 +15,9 @@ src + + + @@ -23,9 +26,15 @@ test/Verify + + test/Account + test/Application + + test/Conversion + test/Verify2 @@ -74,6 +83,9 @@ test/Users + + test/Insights + diff --git a/src/Account/ClientFactory.php b/src/Account/ClientFactory.php index 38695a7e..2f7e45e7 100644 --- a/src/Account/ClientFactory.php +++ b/src/Account/ClientFactory.php @@ -7,7 +7,6 @@ use Psr\Container\ContainerInterface; use Vonage\Client\APIResource; use Vonage\Client\Credentials\Handler\BasicHandler; -use Vonage\Client\Credentials\Handler\BasicQueryHandler; class ClientFactory { diff --git a/src/Client.php b/src/Client.php index 9a62ec28..95eb3410 100644 --- a/src/Client.php +++ b/src/Client.php @@ -544,6 +544,17 @@ public function __get($name) return $this->factory->get($name); } + public function getDebug(): mixed + { + return $this->debug; + } + + public function setDebug(mixed $debug): Client + { + $this->debug = $debug; + return $this; + } + /** * @deprecated Use the Verify Client, this shouldn't be here and will be removed. */ diff --git a/src/Client/APIExceptionHandler.php b/src/Client/APIExceptionHandler.php index 4ac58888..0581eae5 100644 --- a/src/Client/APIExceptionHandler.php +++ b/src/Client/APIExceptionHandler.php @@ -25,6 +25,11 @@ public function setRfc7807Format(string $format): void $this->rfc7807Format = $format; } + public function getRfc7807Format(): string + { + return $this->rfc7807Format; + } + /** * @throws Exception\Exception * diff --git a/test/Account/ClientFactoryTest.php b/test/Account/ClientFactoryTest.php index a2f9267f..06d94a4f 100644 --- a/test/Account/ClientFactoryTest.php +++ b/test/Account/ClientFactoryTest.php @@ -4,37 +4,30 @@ namespace VonageTest\Account; -use VonageTest\VonageTestCase; -use Vonage\Account\ClientFactory; +use PHPUnit\Framework\TestCase; use Vonage\Client; use Vonage\Client\APIResource; use Vonage\Client\Factory\MapFactory; +use Vonage\Account\ClientFactory; -class ClientFactoryTest extends VonageTestCase +class ClientFactoryTest extends TestCase { - /** - * @var MapFactory - */ - protected $mapFactory; - - protected $vonageClient; - - public function setUp(): void + public function testInvokeCreatesClientWithConfiguredApiResource(): void { - $this->vonageClient = $this->prophesize(Client::class); - $this->vonageClient->getRestUrl()->willReturn('https://rest.nexmo.com'); - $this->vonageClient->getApiUrl()->willReturn('https://api.nexmo.com'); + $mockServices = [ + 'account' => ClientFactory::class, + APIResource::class => APIResource::class, + ]; - /** @noinspection PhpParamsInspection */ - $this->mapFactory = new MapFactory([APIResource::class => APIResource::class], $this->vonageClient->reveal()); - } - - public function testURIsAreCorrect(): void - { + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); $factory = new ClientFactory(); - $client = $factory($this->mapFactory); - $this->assertSame('/account', $client->getAPIResource()->getBaseUri()); - $this->assertSame('https://rest.nexmo.com', $client->getAPIResource()->getBaseUrl()); + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Account\Client::class, $result); + $this->assertEquals('/account', $result->getAPIResource()->getBaseUri()); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertFalse($result->getAPIResource()->isHAL()); } } diff --git a/test/Application/ClientFactoryTest.php b/test/Application/ClientFactoryTest.php new file mode 100644 index 00000000..08ae2a1e --- /dev/null +++ b/test/Application/ClientFactoryTest.php @@ -0,0 +1,33 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Application\Client::class, $result); + $this->assertEquals('/v2/applications', $result->getAPIResource()->getBaseUri()); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertEquals('applications', $result->getAPIResource()->getCollectionName()); + } +} diff --git a/test/Client/CallbackTest.php b/test/Client/CallbackTest.php new file mode 100644 index 00000000..e0c42c9c --- /dev/null +++ b/test/Client/CallbackTest.php @@ -0,0 +1,97 @@ + 'value1', + 'key2' => 'value2', + ]; + + $_POST = [ + 'key3' => 'value3', + 'key4' => 'value4', + ]; + } + + public function testConstructorWithMissingKeys(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('missing expected callback keys: key1, key2'); + + $callback = new class (['key3' => 'value3']) extends Callback { + protected array $expected = ['key1', 'key2']; + }; + } + + public function testConstructorWithAllKeys(): void + { + $callback = new class ([ + 'key1' => 'value1', + 'key2' => 'value2', + ]) extends Callback { + protected array $expected = ['key1', 'key2']; + }; + + $this->assertSame([ + 'key1' => 'value1', + 'key2' => 'value2', + ], $callback->getData()); + } + + public function testFromEnvPost(): void + { + $callback = Callback::fromEnv(Callback::ENV_POST); + + $this->assertInstanceOf(Callback::class, $callback); + $this->assertSame([ + 'key3' => 'value3', + 'key4' => 'value4', + ], $callback->getData()); + } + + public function testFromEnvGet(): void + { + $callback = Callback::fromEnv(Callback::ENV_GET); + + $this->assertInstanceOf(Callback::class, $callback); + $this->assertSame([ + 'key1' => 'value1', + 'key2' => 'value2', + ], $callback->getData()); + } + + public function testFromEnvAll(): void + { + $callback = Callback::fromEnv(Callback::ENV_ALL); + + $this->assertInstanceOf(Callback::class, $callback); + $this->assertSame([ + 'key1' => 'value1', + 'key2' => 'value2', + 'key3' => 'value3', + 'key4' => 'value4', + ], $callback->getData()); + } + + public function testFromEnvInvalidSource(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('invalid source: invalid'); + + Callback::fromEnv('invalid'); + } +} diff --git a/test/ClientTest.php b/test/ClientTest.php index e99c53ac..a8a30fbe 100644 --- a/test/ClientTest.php +++ b/test/ClientTest.php @@ -4,7 +4,10 @@ namespace VonageTest; +use Lcobucci\JWT\Token\Plain; +use Psr\Http\Client\ClientInterface; use RuntimeException; +use Vonage\Client\Credentials\CredentialsInterface; use VonageTest\VonageTestCase; use Vonage\Client; use Vonage\Client\Credentials\Basic; @@ -22,4 +25,90 @@ public function testCallingVideoWithoutPackageGeneratesRuntimeError(): void $client = new Client(new Basic('abcd', '1234')); $video = $client->video(); } + + public function testConstructorWithValidClient() + { + $credentials = $this->createMock(Basic::class); + $httpClient = $this->createMock(ClientInterface::class); + $options = ['debug' => true]; + + $client = new Client($credentials, $options, $httpClient); + + $this->assertInstanceOf(Client::class, $client); + $this->assertTrue($client->getDebug()); + } + + public function testConstructorWithoutHttpClientUsesDefault() + { + $credentials = $this->createMock(Basic::class); + $options = ['debug' => true]; + + $client = new Client($credentials, $options); + + $this->assertInstanceOf(Client::class, $client); + $this->assertInstanceOf(ClientInterface::class, $client->getHttpClient()); + } + + public function testConstructorThrowsExceptionOnInvalidCredentials() + { + $invalidCredentials = $this->createMock(CredentialsInterface::class); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('unknown credentials type'); + + new Client($invalidCredentials); + } + + public function testConstructorWithCustomOptions() + { + $credentials = $this->createMock(Basic::class); + $options = [ + 'base_rest_url' => 'https://example-rest.com', + 'base_api_url' => 'https://example-api.com', + 'debug' => true + ]; + + $client = new Client($credentials, $options); + + $this->assertEquals('https://example-rest.com', $client->getRestUrl()); + $this->assertEquals('https://example-api.com', $client->getApiUrl()); + $this->assertTrue($client->getDebug()); + } + + public function testConstructorHandlesDeprecationsOption() + { + $credentials = $this->createMock(Basic::class); + $options = ['show_deprecations' => true]; + + $client = new Client($credentials, $options); + + // No specific assertion for error handler setup, but ensuring no exceptions occurred. + $this->assertInstanceOf(Client::class, $client); + } + + public function testConstructorHandlesVideoClientFactory() + { + $credentials = $this->createMock(Basic::class); + + if (class_exists('Vonage\Video\ClientFactory')) { + $this->markTestSkipped('Vonage Video ClientFactory class is available.'); + } + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Please install @vonage/video to use the Video API'); + + $client = new Client($credentials); + $client->video(); + } + + public function testWillGenerateJwt() + { + $keyPath = __DIR__ . '/Client/Credentials/test.key'; + $keyContents = file_get_contents($keyPath); + $credentials = new Client\Credentials\Keypair($keyContents, 'abc123'); + $client = new Client($credentials); + $jwt = $client->generateJwt(); + + $this->assertInstanceOf(Plain::class, $jwt); + } } diff --git a/test/Conversation/ClientFactoryTest.php b/test/Conversation/ClientFactoryTest.php new file mode 100644 index 00000000..1e791a64 --- /dev/null +++ b/test/Conversation/ClientFactoryTest.php @@ -0,0 +1,34 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Conversation\Client::class, $result); + $this->assertEquals('https://api.nexmo.com/v1/conversations', $result->getAPIResource()->getBaseUrl()); + $this->assertInstanceOf(Client\Credentials\Handler\KeypairHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertFalse($result->getAPIResource()->errorsOn200()); + $this->assertTrue($result->getAPIResource()->isHAL()); + } +} diff --git a/test/Conversion/ClientFactoryTest.php b/test/Conversion/ClientFactoryTest.php new file mode 100644 index 00000000..95a82789 --- /dev/null +++ b/test/Conversion/ClientFactoryTest.php @@ -0,0 +1,32 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Conversion\Client::class, $result); + $this->assertEquals('/conversions/', $result->getAPIResource()->getBaseUri()); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + } +} diff --git a/test/Conversion/ClientTest.php b/test/Conversion/ClientTest.php index ca1d0b9b..0fd6dbeb 100644 --- a/test/Conversion/ClientTest.php +++ b/test/Conversion/ClientTest.php @@ -137,4 +137,15 @@ public function testVoiceWithoutTimestamp(): void $this->conversionClient->voice('ABC123', true); } + + public function testExceptionHandler(): void + { + $this->expectException(Client\Exception\Request::class); + + $this->vonageClient->send(Argument::that(function (RequestInterface $request) { + return true; + }))->willReturn($this->getResponse('error', 402)); + + $this->conversionClient->sms('ABC123', true, '123456'); + } } diff --git a/test/Insights/ClientFactoryTest.php b/test/Insights/ClientFactoryTest.php new file mode 100644 index 00000000..a03eddee --- /dev/null +++ b/test/Insights/ClientFactoryTest.php @@ -0,0 +1,32 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Insights\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertFalse($result->getAPIResource()->isHAL()); + } +} diff --git a/test/Meetings/ClientFactoryTest.php b/test/Meetings/ClientFactoryTest.php new file mode 100644 index 00000000..a72be078 --- /dev/null +++ b/test/Meetings/ClientFactoryTest.php @@ -0,0 +1,35 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = @$factory($container); + $this->assertInstanceOf(\Vonage\Meetings\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\KeypairHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertEquals('https://api-eu.vonage.com/v1/meetings/', $result->getAPIResource()->getBaseUrl()); + $this->assertInstanceOf(ExceptionErrorHandler::class, $result->getAPIResource()->getExceptionErrorHandler()); + } +} diff --git a/test/Messages/ClientFactoryTest.php b/test/Messages/ClientFactoryTest.php new file mode 100644 index 00000000..f304e6b8 --- /dev/null +++ b/test/Messages/ClientFactoryTest.php @@ -0,0 +1,38 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Messages\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\KeypairHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[1]); + $this->assertEquals('/v1/messages', $result->getAPIResource()->getBaseUrl()); + $this->assertInstanceOf(ExceptionErrorHandler::class, $result->getAPIResource()->getExceptionErrorHandler()); + $this->assertFalse($result->getAPIResource()->isHAL()); + $this->assertFalse($result->getAPIResource()->errorsOn200()); + } +} diff --git a/test/NumberVerification/ClientFactoryTest.php b/test/NumberVerification/ClientFactoryTest.php new file mode 100644 index 00000000..7318ed38 --- /dev/null +++ b/test/NumberVerification/ClientFactoryTest.php @@ -0,0 +1,44 @@ +createMock(Client::class); + + $mockServices = [ + 'numberVerification' => ClientFactory::class, + APIResource::class => APIResource::class, + Client::class => fn () => $mockClient, + ]; + + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\NumberVerification\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\NumberVerificationGnpHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertFalse($result->getAPIResource()->isHAL()); + $this->assertFalse($result->getAPIResource()->errorsOn200()); + $this->assertEquals('https://api-eu.vonage.com/camara/number-verification/v031', $result->getAPIResource() + ->getBaseUrl()); + + $this->assertEquals('https://oidc.idp.vonage.com/oauth2/auth', $result->getAPIResource()->getAuthHandlers()[0]->getBaseUrl()); + $this->assertEquals('https://api-eu.vonage.com/oauth2/token', $result->getAPIResource()->getAuthHandlers() + [0]->getTokenUrl()); + $this->assertEquals('openid+dpv:FraudPreventionAndDetection#number-verification-verify-read', + $result->getAPIResource()->getAuthHandlers()[0]->getScope()); + + } +} diff --git a/test/Numbers/ClientFactoryTest.php b/test/Numbers/ClientFactoryTest.php new file mode 100644 index 00000000..480a4f7a --- /dev/null +++ b/test/Numbers/ClientFactoryTest.php @@ -0,0 +1,32 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Numbers\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertFalse($result->getAPIResource()->isHAL()); + } +} diff --git a/test/ProactiveConnect/ClientFactoryTest.php b/test/ProactiveConnect/ClientFactoryTest.php new file mode 100644 index 00000000..9bee923e --- /dev/null +++ b/test/ProactiveConnect/ClientFactoryTest.php @@ -0,0 +1,34 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\ProactiveConnect\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\KeypairHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertEquals('https://api-eu.vonage.com/v0.1/bulk/', $result->getAPIResource()->getBaseUrl()); + $this->assertFalse($result->getAPIResource()->isHAL()); + $this->assertFalse($result->getAPIResource()->errorsOn200()); + } +} diff --git a/test/Redact/ClientFactoryTest.php b/test/Redact/ClientFactoryTest.php new file mode 100644 index 00000000..97759178 --- /dev/null +++ b/test/Redact/ClientFactoryTest.php @@ -0,0 +1,33 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Redact\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertEquals('%s - %s. See %s for more information', $result->getApiResource() + ->getExceptionErrorHandler()->getRfc7807Format()); + } +} diff --git a/test/SMS/ClientFactoryTest.php b/test/SMS/ClientFactoryTest.php new file mode 100644 index 00000000..38933d7e --- /dev/null +++ b/test/SMS/ClientFactoryTest.php @@ -0,0 +1,36 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Sms\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertInstanceOf(Client\Credentials\Handler\SignatureBodyHandler::class, $result->getAPIResource() + ->getAuthHandlers()[1]); + $this->assertFalse($result->getAPIResource()->isHAL()); + $this->assertTrue($result->getAPIResource()->errorsOn200()); + $this->assertEquals('messages', $result->getAPIResource()->getCollectionName()); + } +} diff --git a/test/Secrets/ClientFactoryTest.php b/test/Secrets/ClientFactoryTest.php new file mode 100644 index 00000000..d1c5d42d --- /dev/null +++ b/test/Secrets/ClientFactoryTest.php @@ -0,0 +1,58 @@ +createMock(FactoryInterface::class); + + // Mock the APIResource + $apiResourceMock = $this->createMock(APIResource::class); + + // Configure the factory to return the mocked APIResource + $factoryMock->expects($this->once()) + ->method('make') + ->with(APIResource::class) + ->willReturn($apiResourceMock); + + // Expect the methods on APIResource to be called with specific parameters + $apiResourceMock->expects($this->once()) + ->method('setBaseUri') + ->with('/accounts') + ->willReturnSelf(); + + $apiResourceMock->expects($this->once()) + ->method('setAuthHandlers') + ->with($this->isInstanceOf(BasicHandler::class)) + ->willReturnSelf(); + + $apiResourceMock->expects($this->once()) + ->method('setCollectionName') + ->with('secrets') + ->willReturnSelf(); + + // Create an instance of the ClientFactory + $clientFactory = new ClientFactory(); + + // Call the __invoke method and retrieve the Client + $client = $clientFactory($factoryMock); + + // Assert that the result is an instance of the Client + $this->assertInstanceOf(Client::class, $client); + + // Assert that the Client has the correctly configured APIResource (optional, if Client exposes it) + $this->assertSame($apiResourceMock, $client->getApiResource()); + } +} diff --git a/test/SimSwap/ClientFactoryTest.php b/test/SimSwap/ClientFactoryTest.php new file mode 100644 index 00000000..c894f0ad --- /dev/null +++ b/test/SimSwap/ClientFactoryTest.php @@ -0,0 +1,40 @@ +createMock(Client::class); + + $mockServices = [ + 'simSwap' => ClientFactory::class, + APIResource::class => APIResource::class, + Client::class => fn () => $mockClient, + ]; + + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\SimSwap\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\SimSwapGnpHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertFalse($result->getAPIResource()->isHAL()); + $this->assertFalse($result->getAPIResource()->errorsOn200()); + $this->assertEquals('https://api-eu.vonage.com/camara/sim-swap/v040', $result->getAPIResource() + ->getBaseUrl()); + $this->assertEquals('https://api-eu.vonage.com/oauth2/bc-authorize', $result->getAPIResource()->getAuthHandlers()[0]->getBaseUrl()); + $this->assertEquals('https://api-eu.vonage.com/oauth2/token', $result->getAPIResource()->getAuthHandlers() + [0]->getTokenUrl()); + } +} diff --git a/test/Users/ClientFactoryTest.php b/test/Users/ClientFactoryTest.php new file mode 100644 index 00000000..17a61069 --- /dev/null +++ b/test/Users/ClientFactoryTest.php @@ -0,0 +1,32 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Users\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\KeypairHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertEquals('users', $result->getAPIResource()->getCollectionName()); + } +} diff --git a/test/Verify/ClientFactoryTest.php b/test/Verify/ClientFactoryTest.php new file mode 100644 index 00000000..f1b823d9 --- /dev/null +++ b/test/Verify/ClientFactoryTest.php @@ -0,0 +1,35 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Verify\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\TokenBodyHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertEquals('/verify', $result->getAPIResource()->getBaseUri()); + $this->assertTrue($result->getApiResource()->errorsOn200()); + $this->assertInstanceOf(ExceptionErrorHandler::class, $result->getAPIResource()->getExceptionErrorHandler()); + } +} diff --git a/test/Verify2/ClientFactoryTest.php b/test/Verify2/ClientFactoryTest.php new file mode 100644 index 00000000..b5e68391 --- /dev/null +++ b/test/Verify2/ClientFactoryTest.php @@ -0,0 +1,36 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\Verify2\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\KeypairHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertInstanceOf(Client\Credentials\Handler\BasicHandler::class, $result->getAPIResource() + ->getAuthHandlers()[1]); + $this->assertEquals('https://api.nexmo.com/v2/verify', $result->getAPIResource()->getBaseUrl()); + $this->assertFalse($result->getApiResource()->errorsOn200()); + $this->assertFalse($result->getApiResource()->isHAL()); + } +} diff --git a/test/Verify2/VerifyObjects/TemplateFragmentTest.php b/test/Verify2/VerifyObjects/TemplateFragmentTest.php new file mode 100644 index 00000000..0c8494d8 --- /dev/null +++ b/test/Verify2/VerifyObjects/TemplateFragmentTest.php @@ -0,0 +1,61 @@ + 'value1', 'key2' => 'value2']; + $templateFragment = new TemplateFragment($data); + + $this->assertSame($data, $templateFragment->toArray()); + } + + public function testPropertyGetAndSet() + { + $templateFragment = new TemplateFragment(); + $templateFragment->key1 = 'value1'; + + $this->assertSame('value1', $templateFragment->key1); + $this->assertNull($templateFragment->key2); + } + + public function testPropertyIsset() + { + $templateFragment = new TemplateFragment(['key1' => 'value1']); + + $this->assertTrue(isset($templateFragment->key1)); + $this->assertFalse(isset($templateFragment->key2)); + } + + public function testFromArrayHydratesData() + { + $data = ['key1' => 'value1', 'key2' => 'value2']; + $templateFragment = new TemplateFragment(); + $templateFragment->fromArray($data); + + $this->assertSame($data, $templateFragment->toArray()); + } + + public function testToArrayReturnsData() + { + $data = ['key1' => 'value1', 'key2' => 'value2']; + $templateFragment = new TemplateFragment($data); + + $this->assertSame($data, $templateFragment->toArray()); + } + + public function testChainingWhenSettingProperties() + { + $templateFragment = new TemplateFragment(); + $result = $templateFragment->__set('key1', 'value1'); + + $this->assertInstanceOf(TemplateFragment::class, $result); + } +} diff --git a/test/Verify2/VerifyObjects/TemplateTest.php b/test/Verify2/VerifyObjects/TemplateTest.php new file mode 100644 index 00000000..524a5029 --- /dev/null +++ b/test/Verify2/VerifyObjects/TemplateTest.php @@ -0,0 +1,61 @@ + 'value1', 'key2' => 'value2']; + $template = new Template($data); + + $this->assertSame($data, $template->toArray()); + } + + public function testPropertyGetAndSet() + { + $template = new Template(); + $template->key1 = 'value1'; + + $this->assertSame('value1', $template->key1); + $this->assertNull($template->key2); + } + + public function testPropertyIsset() + { + $template = new Template(['key1' => 'value1']); + + $this->assertTrue(isset($template->key1)); + $this->assertFalse(isset($template->key2)); + } + + public function testFromArrayHydratesData() + { + $data = ['key1' => 'value1', 'key2' => 'value2']; + $template = new Template(); + $template->fromArray($data); + + $this->assertSame($data, $template->toArray()); + } + + public function testToArrayReturnsData() + { + $data = ['key1' => 'value1', 'key2' => 'value2']; + $template = new Template($data); + + $this->assertSame($data, $template->toArray()); + } + + public function testChainingWhenSettingProperties() + { + $template = new Template(); + $result = $template->__set('key1', 'value1'); + + $this->assertInstanceOf(Template::class, $result); + } +} diff --git a/test/Verify2/VerifyObjects/VerificationLocaleTest.php b/test/Verify2/VerifyObjects/VerificationLocaleTest.php new file mode 100644 index 00000000..4dc8e4b8 --- /dev/null +++ b/test/Verify2/VerifyObjects/VerificationLocaleTest.php @@ -0,0 +1,39 @@ +assertSame('en-us', $locale->getCode()); + } + + public function testGetCodeReturnsCorrectValue() + { + $locale = new VerificationLocale('fr-fr'); + $this->assertSame('fr-fr', $locale->getCode()); + } + + public function testSetCodeUpdatesCode() + { + $locale = new VerificationLocale(); + $locale->setCode('es-es'); + + $this->assertSame('es-es', $locale->getCode()); + } + + public function testSetCodeReturnsSelfForChaining() + { + $locale = new VerificationLocale(); + $result = $locale->setCode('it-it'); + + $this->assertInstanceOf(VerificationLocale::class, $result); + } +} \ No newline at end of file diff --git a/test/Verify2/VerifyObjects/VerifyEventTest.php b/test/Verify2/VerifyObjects/VerifyEventTest.php new file mode 100644 index 00000000..474db6e4 --- /dev/null +++ b/test/Verify2/VerifyObjects/VerifyEventTest.php @@ -0,0 +1,62 @@ + 'completed', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyEvent($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testPropertyGetAndSet() + { + $event = new VerifyEvent(['eventType' => 'started']); + $event->timestamp = '2025-01-01T00:00:00Z'; + + $this->assertSame('started', $event->eventType); + $this->assertSame('2025-01-01T00:00:00Z', $event->timestamp); + $this->assertNull($event->unknownProperty); + } + + public function testPropertyIsset() + { + $event = new VerifyEvent(['eventType' => 'completed']); + + $this->assertTrue(isset($event->eventType)); + $this->assertFalse(isset($event->timestamp)); + } + + public function testFromArrayHydratesData() + { + $data = ['eventType' => 'completed', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyEvent([]); + $event->fromArray($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testToArrayReturnsData() + { + $data = ['eventType' => 'started', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyEvent($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testChainingWhenSettingProperties() + { + $event = new VerifyEvent([]); + $result = $event->__set('eventType', 'completed'); + + $this->assertInstanceOf(VerifyEvent::class, $result); + } +} diff --git a/test/Verify2/VerifyObjects/VerifySilentAuthEventTest.php b/test/Verify2/VerifyObjects/VerifySilentAuthEventTest.php new file mode 100644 index 00000000..80297327 --- /dev/null +++ b/test/Verify2/VerifyObjects/VerifySilentAuthEventTest.php @@ -0,0 +1,62 @@ + 'completed', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifySilentAuthEvent($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testPropertyGetAndSet() + { + $event = new VerifySilentAuthEvent(['eventType' => 'started']); + $event->timestamp = '2025-01-01T00:00:00Z'; + + $this->assertSame('started', $event->eventType); + $this->assertSame('2025-01-01T00:00:00Z', $event->timestamp); + $this->assertNull($event->unknownProperty); + } + + public function testPropertyIsset() + { + $event = new VerifySilentAuthEvent(['eventType' => 'completed']); + + $this->assertTrue(isset($event->eventType)); + $this->assertFalse(isset($event->timestamp)); + } + + public function testFromArrayHydratesData() + { + $data = ['eventType' => 'completed', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifySilentAuthEvent([]); + $event->fromArray($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testToArrayReturnsData() + { + $data = ['eventType' => 'started', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifySilentAuthEvent($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testChainingWhenSettingProperties() + { + $event = new VerifySilentAuthEvent([]); + $result = $event->__set('eventType', 'completed'); + + $this->assertInstanceOf(VerifySilentAuthEvent::class, $result); + } +} diff --git a/test/Verify2/VerifyObjects/VerifyStatusUpdateTest.php b/test/Verify2/VerifyObjects/VerifyStatusUpdateTest.php new file mode 100644 index 00000000..5913da92 --- /dev/null +++ b/test/Verify2/VerifyObjects/VerifyStatusUpdateTest.php @@ -0,0 +1,62 @@ + 'completed', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyStatusUpdate($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testPropertyGetAndSet() + { + $event = new VerifyStatusUpdate(['eventType' => 'started']); + $event->timestamp = '2025-01-01T00:00:00Z'; + + $this->assertSame('started', $event->eventType); + $this->assertSame('2025-01-01T00:00:00Z', $event->timestamp); + $this->assertNull($event->unknownProperty); + } + + public function testPropertyIsset() + { + $event = new VerifyStatusUpdate(['eventType' => 'completed']); + + $this->assertTrue(isset($event->eventType)); + $this->assertFalse(isset($event->timestamp)); + } + + public function testFromArrayHydratesData() + { + $data = ['eventType' => 'completed', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyStatusUpdate([]); + $event->fromArray($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testToArrayReturnsData() + { + $data = ['eventType' => 'started', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyStatusUpdate($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testChainingWhenSettingProperties() + { + $event = new VerifyStatusUpdate([]); + $result = $event->__set('eventType', 'completed'); + + $this->assertInstanceOf(VerifyStatusUpdate::class, $result); + } +} diff --git a/test/Verify2/VerifyObjects/VerifyWhatsAppInteractiveEventTest.php b/test/Verify2/VerifyObjects/VerifyWhatsAppInteractiveEventTest.php new file mode 100644 index 00000000..b206c1b7 --- /dev/null +++ b/test/Verify2/VerifyObjects/VerifyWhatsAppInteractiveEventTest.php @@ -0,0 +1,62 @@ + 'completed', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyWhatsAppInteractiveEvent($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testPropertyGetAndSet() + { + $event = new VerifyWhatsAppInteractiveEvent(['eventType' => 'started']); + $event->timestamp = '2025-01-01T00:00:00Z'; + + $this->assertSame('started', $event->eventType); + $this->assertSame('2025-01-01T00:00:00Z', $event->timestamp); + $this->assertNull($event->unknownProperty); + } + + public function testPropertyIsset() + { + $event = new VerifyWhatsAppInteractiveEvent(['eventType' => 'completed']); + + $this->assertTrue(isset($event->eventType)); + $this->assertFalse(isset($event->timestamp)); + } + + public function testFromArrayHydratesData() + { + $data = ['eventType' => 'completed', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyWhatsAppInteractiveEvent([]); + $event->fromArray($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testToArrayReturnsData() + { + $data = ['eventType' => 'started', 'timestamp' => '2025-01-01T00:00:00Z']; + $event = new VerifyWhatsAppInteractiveEvent($data); + + $this->assertSame($data, $event->toArray()); + } + + public function testChainingWhenSettingProperties() + { + $event = new VerifyWhatsAppInteractiveEvent([]); + $result = $event->__set('eventType', 'completed'); + + $this->assertInstanceOf(VerifyWhatsAppInteractiveEvent::class, $result); + } +} diff --git a/test/Voice/ClientFactoryTest.php b/test/Voice/ClientFactoryTest.php new file mode 100644 index 00000000..e06eafcd --- /dev/null +++ b/test/Voice/ClientFactoryTest.php @@ -0,0 +1,32 @@ + ClientFactory::class, + APIResource::class => APIResource::class, + ]; + + $mockClient = $this->createMock(Client::class); + $container = new MapFactory($mockServices, $mockClient); + $factory = new ClientFactory(); + + $result = $factory($container); + $this->assertInstanceOf(\Vonage\voice\Client::class, $result); + $this->assertInstanceOf(Client\Credentials\Handler\KeypairHandler::class, $result->getAPIResource() + ->getAuthHandlers()[0]); + $this->assertEquals('/v1/calls', $result->getAPIResource()->getBaseUri()); + $this->assertEquals('calls', $result->getAPIResource()->getCollectionName()); + } +} diff --git a/test/Webhook/FactoryTest.php b/test/Webhook/FactoryTest.php new file mode 100644 index 00000000..7c5710f5 --- /dev/null +++ b/test/Webhook/FactoryTest.php @@ -0,0 +1,81 @@ +concreteFactory = new class extends Factory { + public static function createFromArray(array $data) + { + return $data; + } + }; + } + + public function testCreateFromJsonWithValidJson(): void + { + $json = '{"key":"value"}'; + $result = $this->concreteFactory::createFromJson($json); + + $this->assertSame(['key' => 'value'], $result); + } + + public function testCreateFromJsonWithInvalidJson(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage("Invalid JSON string detected for webhook transformation"); + + $json = '{invalid_json}'; + $this->concreteFactory::createFromJson($json); + } + + public function testCreateFromRequestWithGetMethod(): void + { + $request = new ServerRequest([], [], null, 'GET', 'php://temp', [], [], ['key' => 'value']); + + $result = $this->concreteFactory::createFromRequest($request); + + $this->assertSame(['key' => 'value'], $result); + } + + public function testCreateFromRequestWithPostMethodAndJson(): void + { + $body = '{"key":"value"}'; + + // Use a writable temporary stream for the body + $stream = new Stream('php://temp', 'wb+'); + $stream->write($body); + $stream->rewind(); + + $request = new ServerRequest([], [], null, 'POST', $stream, ['Content-Type' => 'application/json'], [], []); + + $result = $this->concreteFactory::createFromRequest($request); + + $this->assertSame(['key' => 'value'], $result); + } + + public function testCreateFromRequestWithInvalidMethod(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage("Invalid method for incoming webhook"); + + $request = new ServerRequest([], [], null, 'PUT'); + $this->concreteFactory::createFromRequest($request); + } +}