Skip to content

Commit 4ae6f7d

Browse files
committed
Added unit testing for webhooks
1 parent 0a45536 commit 4ae6f7d

File tree

4 files changed

+133
-35
lines changed

4 files changed

+133
-35
lines changed

src/Bluem.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,12 +588,13 @@ public function CreateIdentityTransactionID(string $debtorReference): string
588588
* Returns null if the webhook failed to be parsed
589589
* @returns null|PaymentStatusBluemResponse|MandateStatusBluemResponse|IdentityStatusBluemResponse
590590
*/
591-
public function Webhook()
591+
public function Webhook($data = '')
592592
{
593593
try {
594594
$webhook = new Webhook(
595595
$this->configuration->senderID,
596-
$this->configuration->environment
596+
$this->configuration->environment,
597+
$data
597598
);
598599
} catch (Exception $e) {
599600
return $e->getMessage();

src/Webhook.php

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,46 +22,53 @@ class Webhook implements WebhookInterface
2222
private const XML_UTF8_CONTENT_TYPE = "text/xml; charset=UTF-8";
2323
private const STATUSCODE_BAD_REQUEST = 400;
2424

25-
public string $service;
26-
public ?SimpleXMLElement $xmlObject;
25+
public string $service = '';
2726

28-
private string $xmlInterface;
29-
private string $xmlPayloadKey;
27+
public ?SimpleXMLElement $xmlObject = null;
28+
29+
private string $xmlInterface = '';
30+
31+
private string $xmlPayloadKey = '';
3032

3133
public function __construct(
3234
private $senderID,
33-
private $environment = BLUEM_ENVIRONMENT_TESTING
35+
private $environment = BLUEM_ENVIRONMENT_TESTING,
36+
private $webhookData = ''
3437
) {
35-
$this->parse();
38+
$this->parse($this->webhookData);
3639
}
3740

38-
private function parse(): void
41+
private function parse($xmlData = ''): void
3942
{
40-
if (!$this->isHttpsRequest()) {
41-
$this->exitWithError('Not HTTPS');
42-
return;
43-
}
43+
if (empty($xmlData))
44+
{
45+
if (!$this->isHttpsRequest()) {
46+
$this->exitWithError('Not HTTPS');
47+
return;
48+
}
4449

45-
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
46-
$this->exitWithError('Not POST');
47-
return;
48-
}
50+
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
51+
$this->exitWithError('Not POST');
52+
return;
53+
}
4954

50-
// Check: An empty POST to the URL (normal HTTP request) always has to respond with HTTP 200 OK.
51-
$postData = file_get_contents('php://input');
55+
// Check: content type: XML with utf-8 encoding
56+
if ($_SERVER["CONTENT_TYPE"] !== self::XML_UTF8_CONTENT_TYPE) {
57+
$this->exitWithError('Wrong Content-Type given: should be XML with UTF-8 encoding');
58+
return;
59+
}
5260

53-
if (empty($postData)) {
54-
$this->exitWithError('No data body given');
55-
return;
56-
}
61+
// Check: An empty POST to the URL (normal HTTP request) always has to respond with HTTP 200 OK.
62+
$xmlData = file_get_contents('php://input');
5763

58-
// Check: content type: XML with utf-8 encoding
59-
if ($_SERVER["CONTENT_TYPE"] !== self::XML_UTF8_CONTENT_TYPE) {
60-
$this->exitWithError('Wrong Content-Type given: should be XML with UTF-8 encoding');
61-
return;
64+
if (empty($xmlData)) {
65+
$this->exitWithError('No data body given');
66+
return;
67+
}
6268
}
6369

64-
$xmlObject = $this->parseRawXML($postData);
70+
$xmlObject = $this->parseRawXML($xmlData);
71+
6572
if (! $xmlObject instanceof \SimpleXMLElement) {
6673
$this->exitWithError('Could not parse XML');
6774
return;
@@ -73,7 +80,7 @@ private function parse(): void
7380
return;
7481
}
7582

76-
$signatureValidation = (new WebhookSignatureValidation($this->environment))->validate($postData);
83+
$signatureValidation = (new WebhookSignatureValidation($this->environment))->validate($xmlData);
7784
if (! $signatureValidation::$isValid) {
7885
$this->exitWithError($signatureValidation->errorMessage());
7986
return;
@@ -137,9 +144,9 @@ private function getPayloadValue(string $key): SimpleXMLElement|string|null
137144
if ((is_countable($payload->children()) ? count($payload->children()) : 0) > 0) {
138145
return $payload;
139146
}
140-
141-
return $payload->$key . '' ?? '';
147+
return $payload->$key ?? '';
142148
}
149+
143150
private function getPayload(): SimpleXMLElement
144151
{
145152
if ($this->isEmandates()) {
@@ -197,7 +204,11 @@ public function getPurchaseID(): ?string
197204
public function getStatus(): ?string
198205
{
199206
if ($this->isPayments()) {
200-
return $this->getPayloadValue('Status');
207+
$value = $this->getPayloadValue('Status');
208+
209+
if (!empty($value)) {
210+
return $value;
211+
}
201212
}
202213
return $this->getPayload()->Status . "";
203214
}

tests/Integration/BluemGenericTestCase.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ protected function setUp() : void
6363
}
6464
}
6565

66-
6766
// test that we can set the configuration
6867
public function testSetConfiguration(): void
6968
{
@@ -94,7 +93,6 @@ public function testGetConfiguration(): void
9493
*/
9594
protected function _finalizeBluemRequestAssertion(BluemRequestInterface $request) :void
9695
{
97-
9896
try {
9997
// $this->assertEquals($request->getStatus(), "success");
10098
$response = $this->bluem->PerformRequest($request);

tests/Integration/WebhookTest.php

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,96 @@
1414

1515
class WebhookTest extends BluemGenericTestCase
1616
{
17-
public function testCanPerformWebhook()
17+
/**
18+
* Test webhook for payments.
19+
*
20+
* @return void
21+
*/
22+
public function testCanPerformWebhookPayment()
1823
{
1924
$this->markTestSkipped("To be implemented");
25+
26+
$dirPath = dirname(dirname(__DIR__)) . '/validation/webhooks';
27+
28+
$fileName = 'webhook_payment.xml';
29+
30+
$filePath = $dirPath . '/' . $fileName;
31+
32+
$status = '';
33+
34+
if (is_file($filePath)) {
35+
$xmlData = file_get_contents($filePath);
36+
37+
$webhook = $this->bluem->Webhook($xmlData);
38+
39+
if ($webhook !== null) {
40+
if (method_exists($webhook, 'getStatus')) {
41+
$status = $webhook->getStatus();
42+
}
43+
}
44+
}
45+
$this->assertEquals('Success', $status, $fileName . ': Status not success: ' . $status);
46+
}
47+
48+
/**
49+
* Test webhook for mandates.
50+
*
51+
* @return void
52+
*/
53+
public function testCanPerformWebhookMandate()
54+
{
55+
$this->markTestSkipped("To be implemented");
56+
57+
$dirPath = dirname(dirname(__DIR__)) . '/validation/webhooks';
58+
59+
$fileName = 'webhook_mandate.xml';
60+
61+
$filePath = $dirPath . '/' . $fileName;
62+
63+
$status = '';
64+
65+
if (is_file($filePath)) {
66+
$xmlData = file_get_contents($filePath);
67+
68+
$webhook = $this->bluem->Webhook($xmlData);
69+
70+
if ($webhook !== null) {
71+
if (method_exists($webhook, 'getStatus')) {
72+
$status = $webhook->getStatus();
73+
}
74+
}
75+
}
76+
$this->assertEquals('Success', $status, $fileName . ': Status not success: ' . $status);
77+
}
78+
79+
/**
80+
* Test webhook for identity.
81+
*
82+
* @return void
83+
*/
84+
public function testCanPerformWebhookIdentity()
85+
{
86+
$this->markTestSkipped("To be implemented");
87+
88+
$dirPath = dirname(dirname(__DIR__)) . '/validation/webhooks';
89+
90+
$fileName = 'webhook_identity.xml';
91+
92+
$filePath = $dirPath . '/' . $fileName;
93+
94+
$status = '';
95+
96+
if (is_file($filePath)) {
97+
$xmlData = file_get_contents($filePath);
98+
99+
$webhook = $this->bluem->Webhook($xmlData);
100+
101+
if ($webhook !== null) {
102+
if (method_exists($webhook, 'getStatus')) {
103+
$status = $webhook->getStatus();
104+
}
105+
}
106+
}
107+
$this->assertEquals('Success', $status, $fileName . ': Status not success: ' . $status);
20108
}
21109
}

0 commit comments

Comments
 (0)