Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,19 @@ jobs:
run: "composer dump-autoload --optimize"

- name: Run Codeception Tests
env:
XDEBUG_MODE: coverage
run: |
vendor/bin/codecept run -v
vendor/bin/codecept run -v --coverage --coverage-xml coverage.xml --coverage-html

- name: Upload coverage report
if: ${{ success() || failure() }}
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: |
tests/_output/coverage.xml
tests/_output/coverage/

- name: IP check on Failure
if: ${{ failure() }}
Expand Down
138 changes: 138 additions & 0 deletions tests/Integration/ComgateBuilderCest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?php

declare(strict_types=1);

namespace Tests\Integration;

use Codeception\Attribute\Group;
use Comgate\SDK\Client;
use Comgate\SDK\ClientTerminal;
use Comgate\SDK\Comgate;
use Comgate\SDK\Config;
use Comgate\SDK\Http\ITransport;
use Comgate\SDK\Logging\StdoutLogger;
use Tests\Support\IntegrationTester;

class ComgateBuilderCest
{
#[Group('builder')]
public function createClientTest(IntegrationTester $I): void
{
$client = Comgate::defaults()
->setMerchant($_ENV['API_MERCHANT'])
->setSecret($_ENV['API_SECRET'])
->createClient();

$I->assertInstanceOf(Client::class, $client);
}

#[Group('builder')]
public function createTerminalClientTest(IntegrationTester $I): void
{
$client = Comgate::defaults()
->setMerchant($_ENV['API_MERCHANT'])
->setSecret($_ENV['API_SECRET'])
->createTerminalClient();

$I->assertInstanceOf(ClientTerminal::class, $client);
}

#[Group('builder')]
public function customUrlIsAppliedTest(IntegrationTester $I): void
{
$customUrl = 'https://custom.example.com/v1/';

$client = Comgate::defaults()
->setMerchant($_ENV['API_MERCHANT'])
->setSecret($_ENV['API_SECRET'])
->setUrl($customUrl)
->createClient();

$I->assertInstanceOf(Client::class, $client);
$I->assertEquals($customUrl, $client->getTransport()->getConfig()->getUrl());
}

#[Group('builder')]
public function defaultUrlIsProductionTest(IntegrationTester $I): void
{
$client = Comgate::defaults()
->setMerchant($_ENV['API_MERCHANT'])
->setSecret($_ENV['API_SECRET'])
->createClient();

$config = $client->getTransport()->getConfig();
$I->assertInstanceOf(ITransport::class, $client->getTransport());
$I->assertStringStartsWith('https://', $config->getUrl());
}

#[Group('builder')]
public function merchantAndSecretAreStoredInConfigTest(IntegrationTester $I): void
{
$merchant = 'test-merchant-123';
$secret = 'test-secret-abc';

$client = Comgate::defaults()
->setMerchant($merchant)
->setSecret($secret)
->createClient();

$config = $client->getTransport()->getConfig();
$I->assertEquals($merchant, $config->getMerchant());
$I->assertEquals($secret, $config->getSecret());
}

#[Group('builder')]
public function builderWithLoggerCreatesClientTest(IntegrationTester $I): void
{
$logger = new StdoutLogger();

$client = Comgate::defaults()
->setMerchant($_ENV['API_MERCHANT'])
->setSecret($_ENV['API_SECRET'])
->setLogger($logger)
->createClient();

$I->assertInstanceOf(Client::class, $client);
}

#[Group('builder')]
public function setUrlWithoutTrailingSlashAddsOneTest(IntegrationTester $I): void
{
$client = Comgate::defaults()
->setMerchant($_ENV['API_MERCHANT'])
->setSecret($_ENV['API_SECRET'])
->setUrl('https://example.com/v1')
->createClient();

$I->assertStringEndsWith('/', $client->getTransport()->getConfig()->getUrl());
}

#[Group('builder')]
public function setUrlWithMultipleTrailingSlashesCollapsesToOneTest(IntegrationTester $I): void
{
$client = Comgate::defaults()
->setMerchant($_ENV['API_MERCHANT'])
->setSecret($_ENV['API_SECRET'])
->setUrl('https://example.com/v1///')
->createClient();

$url = $client->getTransport()->getConfig()->getUrl();

$I->assertStringEndsWith('/', $url);
$I->assertStringEndsNotWith('//', $url);
}

#[Group('builder')]
public function setUrlAlreadyWithTrailingSlashIsUnchangedTest(IntegrationTester $I): void
{
$url = 'https://example.com/v1/';

$client = Comgate::defaults()
->setMerchant($_ENV['API_MERCHANT'])
->setSecret($_ENV['API_SECRET'])
->setUrl($url)
->createClient();

$I->assertEquals($url, $client->getTransport()->getConfig()->getUrl());
}
}
111 changes: 111 additions & 0 deletions tests/Integration/Entity/PaymentNotificationCest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

declare(strict_types=1);

namespace Tests\Integration\Entity;

use Codeception\Attribute\Group;
use Comgate\SDK\Entity\Money;
use Comgate\SDK\Entity\PaymentNotification;
use Tests\Support\IntegrationTester;

class PaymentNotificationCest
{
#[Group('notification')]
public function createFromCompletePayloadTest(IntegrationTester $I): void
{
$data = [
'merchant' => '123456',
'test' => 'true',
'price' => '10000',
'curr' => 'CZK',
'label' => 'Test product',
'refId' => 'order-42',
'email' => 'customer@example.com',
'transId' => 'AB12-CD34-EF56',
'status' => 'PAID',
'fee' => '0.50',
'vs' => '9876543210',
'method' => 'CARD_ALL',
'secret' => 'my-secret',
];

$notification = PaymentNotification::createFrom($data);

$I->assertInstanceOf(PaymentNotification::class, $notification);
$I->assertEquals('123456', $notification->getMerchant());
$I->assertTrue($notification->isTest());
$I->assertInstanceOf(Money::class, $notification->getPrice());
$I->assertEquals(10000, $notification->getPrice()->get());
$I->assertEquals('CZK', $notification->getCurrency());
$I->assertEquals('Test product', $notification->getLabel());
$I->assertEquals('order-42', $notification->getReferenceId());
$I->assertEquals('customer@example.com', $notification->getEmail());
$I->assertEquals('AB12-CD34-EF56', $notification->getTransactionId());
$I->assertEquals('PAID', $notification->getStatus());
$I->assertEquals('0.50', $notification->getFee());
$I->assertEquals('9876543210', $notification->getVs());
$I->assertEquals('CARD_ALL', $notification->getMethod());
$I->assertEquals('my-secret', $notification->getSecret());
}

#[Group('notification')]
public function createFromMissingFieldsTest(IntegrationTester $I): void
{
$notification = PaymentNotification::createFrom([]);

$I->assertInstanceOf(PaymentNotification::class, $notification);
$I->assertNull($notification->getMerchant());
$I->assertNull($notification->getTransactionId());
$I->assertNull($notification->getStatus());
$I->assertNull($notification->getPrice());
$I->assertNull($notification->getCurrency());
$I->assertNull($notification->getEmail());
$I->assertNull($notification->getLabel());
$I->assertNull($notification->getReferenceId());
$I->assertNull($notification->getFee());
$I->assertNull($notification->getVs());
$I->assertNull($notification->getMethod());
$I->assertNull($notification->getSecret());
}

#[Group('notification')]
public function isTestBooleanConversionTest(IntegrationTester $I): void
{
$notificationTrue = PaymentNotification::createFrom(['test' => 'true']);
$I->assertTrue($notificationTrue->isTest());

$notificationFalse = PaymentNotification::createFrom(['test' => 'false']);
$I->assertFalse($notificationFalse->isTest());

$notificationOne = PaymentNotification::createFrom(['test' => '1']);
$I->assertTrue($notificationOne->isTest());

$notificationZero = PaymentNotification::createFrom(['test' => '0']);
$I->assertFalse($notificationZero->isTest());
}

#[Group('notification')]
public function createFactoryReturnsEmptyObjectTest(IntegrationTester $I): void
{
$notification = PaymentNotification::create();

$I->assertInstanceOf(PaymentNotification::class, $notification);
$I->assertNull($notification->getTransactionId());
$I->assertNull($notification->getMerchant());
}

#[Group('notification')]
public function settersWorkCorrectlyTest(IntegrationTester $I): void
{
$notification = PaymentNotification::createFrom(['vs' => '111', 'method' => 'BANK_ALL']);

$notification->setVs('999');
$notification->setMethod('CARD_ALL');
$notification->setSecret('new-secret');

$I->assertEquals('999', $notification->getVs());
$I->assertEquals('CARD_ALL', $notification->getMethod());
$I->assertEquals('new-secret', $notification->getSecret());
}
}
96 changes: 96 additions & 0 deletions tests/Integration/Entity/Request/TerminalRequestsCest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php

declare(strict_types=1);

namespace Tests\Integration\Entity\Request;

use Codeception\Attribute\DataProvider;
use Codeception\Attribute\Group;
use Codeception\Example;
use Comgate\SDK\Entity\Codes\CurrencyCode;
use Comgate\SDK\Entity\Money;
use Comgate\SDK\Entity\Request\TerminalPaymentCreateRequest;
use Comgate\SDK\Entity\Request\TerminalRefundCreateRequest;
use Comgate\SDK\Entity\TerminalPayment;
use Comgate\SDK\Entity\TerminalRefund;
use Tests\Support\IntegrationTester;

class TerminalRequestsCest
{
#[Group('terminal-request')]
#[DataProvider('getTerminalPaymentScenarios')]
public function testTerminalPaymentCreateRequestParams(IntegrationTester $I, Example $example): void
{
$request = new TerminalPaymentCreateRequest($example['payment']);
$I->assertEquals($example['result'], $request->toArray());
}

protected function getTerminalPaymentScenarios(): array
{
return [
'minimal payment — only required fields' => [
'payment' => (new TerminalPayment())
->setPrice(Money::ofInt(100))
->setCurr(CurrencyCode::CZK),
'result' => [
'price' => 10000,
'curr' => CurrencyCode::CZK,
],
],
'payment with refId' => [
'payment' => (new TerminalPayment())
->setPrice(Money::ofInt(50))
->setCurr(CurrencyCode::EUR)
->setRefId('order-9999'),
'result' => [
'price' => 5000,
'curr' => CurrencyCode::EUR,
'refId' => 'order-9999',
],
],
'price in cents' => [
'payment' => (new TerminalPayment())
->setPrice(Money::ofCents(150))
->setCurr(CurrencyCode::CZK),
'result' => [
'price' => 150,
'curr' => CurrencyCode::CZK,
],
],
];
}

#[Group('terminal-request')]
#[DataProvider('getTerminalRefundScenarios')]
public function testTerminalRefundCreateRequestParams(IntegrationTester $I, Example $example): void
{
$request = new TerminalRefundCreateRequest($example['refund']);
$I->assertEquals($example['result'], $request->toArray());
}

protected function getTerminalRefundScenarios(): array
{
return [
'minimal refund — only required fields' => [
'refund' => (new TerminalRefund())
->setPrice(Money::ofInt(50))
->setCurr(CurrencyCode::CZK),
'result' => [
'price' => 5000,
'curr' => CurrencyCode::CZK,
],
],
'refund with refId' => [
'refund' => (new TerminalRefund())
->setPrice(Money::ofInt(25))
->setCurr(CurrencyCode::EUR)
->setRefId('refund-order-42'),
'result' => [
'price' => 2500,
'curr' => CurrencyCode::EUR,
'refId' => 'refund-order-42',
],
],
];
}
}
Loading
Loading