Skip to content

Commit

Permalink
feature: create business event endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
Francois-Gomis committed Jan 20, 2025
1 parent 3dcb487 commit ff3fb92
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 1 deletion.
60 changes: 60 additions & 0 deletions src/Endpoints/Merchants.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@

namespace Alma\API\Endpoints;

use Alma\API\Entities\DTO\MerchantBusinessEvent\CartInitiatedBusinessEvent;
use Alma\API\Entities\DTO\MerchantBusinessEvent\OrderConfirmedBusinessEvent;
use Alma\API\Entities\FeePlan;
use Alma\API\Entities\Merchant;
use Alma\API\Exceptions\RequestException;
use Alma\API\RequestError;

class Merchants extends Base
Expand Down Expand Up @@ -80,4 +83,61 @@ public function feePlans($kind = FeePlan::KIND_GENERAL, $installmentsCounts = "a
return new FeePlan($val);
}, $res->json);
}

/**
* Prepare and send a business event for a cart initiated
*
* @param CartInitiatedBusinessEvent $cartEventData
* @return void
* @throws RequestException
*/
public function sendCartInitiatedBusinessEvent(CartInitiatedBusinessEvent $cartEventData)
{
$cartEventDataPayload = [
'event_type' => $cartEventData->getEventType(),
'cart_id' => $cartEventData->getCartId()
];
$this->sendBusinessEvent($cartEventDataPayload);
}

/**
* Prepare and send a business event for a cart initiated
*
* @param OrderConfirmedBusinessEvent $orderConfirmedBusinessEvent
* @return void
* @throws RequestException
*/
public function sendOrderConfirmedBusinessEvent(OrderConfirmedBusinessEvent $orderConfirmedBusinessEvent)
{
$cartEventDataPayload = [
'event_type' => $orderConfirmedBusinessEvent->getEventType(),
'is_alma_p1x' => $orderConfirmedBusinessEvent->getIsAlmaP1X(),
'is_alma_bnpl' => $orderConfirmedBusinessEvent->getIsAlmaBNPL(),
'was_bnpl_eligible' => $orderConfirmedBusinessEvent->getWasBNPLEligible(),
'order_id' => $orderConfirmedBusinessEvent->getOrderId(),
'cart_id' => $orderConfirmedBusinessEvent->getCartId(),
'alma_payment_id' => $orderConfirmedBusinessEvent->getAlmaPaymentId()
];
$this->sendBusinessEvent($cartEventDataPayload);
}

/**
* Send merchant_business_event and return 204 no content
*
* @param array $eventData
* @return void
* @throws RequestException
*/
private function sendBusinessEvent($eventData)
{
try {
$res = $this->request(self::ME_PATH . "/business-events")->setRequestBody($eventData)->post();
} catch (RequestError $e) {
throw new RequestException($e->getErrorMessage(), null);
}
if ($res->isError()) {
throw new RequestException($res->errorMessage, null, $res);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public function getCartId()
}

/**
* @return string
* @return string | null
*/
public function getAlmaPaymentId()
{
Expand Down
178 changes: 178 additions & 0 deletions tests/Unit/Endpoints/MerchantsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<?php

namespace Alma\API\Tests\Unit\Endpoints;

use Alma\API\ClientContext;
use Alma\API\Endpoints\Merchants;
use Alma\API\Entities\DTO\MerchantBusinessEvent\CartInitiatedBusinessEvent;
use Alma\API\Entities\DTO\MerchantBusinessEvent\OrderConfirmedBusinessEvent;
use Alma\API\Exceptions\ParametersException;
use Alma\API\Exceptions\RequestException;
use Alma\API\Request;
use Alma\API\RequestError;
use Alma\API\Response;
use Mockery;
use PHPUnit\Framework\TestCase;

class MerchantsTest extends TestCase
{

/**
* @var ClientContext
*/
private $clientContext;
/**
* @var Merchants
*/
private $merchantEndpoint;
/**
* @var Request
*/
private $requestObject;
/**
* @var Response
*/
private $responseMock;

public function setUp(): void
{
$this->clientContext = Mockery::mock(ClientContext::class);
$this->merchantEndpoint = Mockery::mock(Merchants::class)->makePartial();
$loggerMock = Mockery::mock(LoggerInterface::class);
$loggerMock->shouldReceive('error');
$this->requestObject = Mockery::mock(Request::class);
$this->responseMock = Mockery::mock(Response::class);
$this->clientContext->logger = $loggerMock;
$this->merchantEndpoint->setClientContext($this->clientContext);
}
public function tearDown(): void
{
$this->merchantEndpoint = null;
$this->responseMock = null;
$this->requestObject = null;
$this->clientContext = null;
Mockery::close();
}

public function testSendBusinessEventPostThrowRequestErrorThrowRequestException()
{
$this->merchantEndpoint->shouldReceive('request')
->with('/v1/me/business-events')
->once()
->andReturn($this->requestObject);
$this->requestObject->shouldReceive('setRequestBody')
->once()
->andReturn($this->requestObject);
$this->requestObject->shouldReceive('post')
->once()
->andThrow(new RequestError('Error in post', null, null));
$this->expectException(RequestException::class);
$this->merchantEndpoint->sendCartInitiatedBusinessEvent(new CartInitiatedBusinessEvent('42'));
}
public function testSendBusinessEventBadResponseRequestException()
{
$this->merchantEndpoint->shouldReceive('request')
->with('/v1/me/business-events')
->once()
->andReturn($this->requestObject);
$this->requestObject->shouldReceive('setRequestBody')
->once()
->andReturn($this->requestObject);
$this->responseMock->errorMessage = 'Error in response';
$this->responseMock->shouldReceive('isError')
->once()
->andReturn(true);
$this->requestObject->shouldReceive('post')
->once()
->andReturn($this->responseMock);
$this->expectException(RequestException::class);
$this->merchantEndpoint->sendCartInitiatedBusinessEvent(new CartInitiatedBusinessEvent('42'));
}
/**
*
* @return void
*/
public function testSendCartInitiatedEvent()
{
$cartInitiatedEvent = new CartInitiatedBusinessEvent('42');
$this->merchantEndpoint->shouldReceive('request')
->with('/v1/me/business-events')
->once()
->andReturn($this->requestObject);
$this->requestObject->shouldReceive('setRequestBody')
->with(['event_type' => $cartInitiatedEvent->getEventType(), 'cart_id' => $cartInitiatedEvent->getCartId()])
->once()
->andReturn($this->requestObject);
$this->responseMock->shouldReceive('isError')->once()->andReturn(false);
$this->requestObject->shouldReceive('post')->once()->andReturn($this->responseMock);
$this->assertNull($this->merchantEndpoint->sendCartInitiatedBusinessEvent($cartInitiatedEvent));
}
/**
*
* @return void
*/
public function testSendOrderConfirmedBusinessEventForNonAlmaPayment()
{
$orderConfirmedBusinessEvent = new OrderConfirmedBusinessEvent(
false,
false,
true,
'42',
'54'
);
$this->merchantEndpoint->shouldReceive('request')
->with('/v1/me/business-events')
->once()
->andReturn($this->requestObject);
$this->requestObject->shouldReceive('setRequestBody')
->with(
[
'event_type' => 'order_confirmed',
'is_alma_p1x' => false,
'is_alma_bnpl' => false,
'was_bnpl_eligible' => true,
'order_id' => '42',
'cart_id' => '54',
'alma_payment_id' => NULL
]
)
->once()
->andReturn($this->requestObject);
$this->responseMock->shouldReceive('isError')->once()->andReturn(false);
$this->requestObject->shouldReceive('post')->once()->andReturn($this->responseMock);
$this->assertNull($this->merchantEndpoint->sendOrderConfirmedBusinessEvent($orderConfirmedBusinessEvent));
}
public function testSendOrderConfirmedBusinessEventForAlmaPayment()
{
$orderConfirmedBusinessEvent = new OrderConfirmedBusinessEvent(
true,
false,
true,
'42',
'54',
'alma_payment_id'
);
$this->merchantEndpoint->shouldReceive('request')
->with('/v1/me/business-events')
->once()
->andReturn($this->requestObject);
$this->requestObject->shouldReceive('setRequestBody')
->with(
[
'event_type' => 'order_confirmed',
'is_alma_p1x' => true,
'is_alma_bnpl' => false,
'was_bnpl_eligible' => true,
'order_id' => '42',
'cart_id' => '54',
'alma_payment_id' => 'alma_payment_id'
]
)
->once()
->andReturn($this->requestObject);
$this->responseMock->shouldReceive('isError')->once()->andReturn(false);
$this->requestObject->shouldReceive('post')->once()->andReturn($this->responseMock);
$this->assertNull($this->merchantEndpoint->sendOrderConfirmedBusinessEvent($orderConfirmedBusinessEvent));
}

}

0 comments on commit ff3fb92

Please sign in to comment.