Skip to content

Commit c5fc684

Browse files
committed
tests and fixes
- unit test for Request object - fixes to bugs uncovered by uni tests
1 parent 1179073 commit c5fc684

16 files changed

+556
-61
lines changed

bin/add-endpoint.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,12 +408,12 @@ function onOtherEvent(\Webhook\Payload\Event $payload) {
408408
try {
409409
$request = \Webhook\Request::service(file_get_contents('php://input'),isset($_SERVER)?$_SERVER:[]);
410410
if ($request->getRequestMethod()!=='POST') {
411-
throw new \Webhook\InvalidRequest("requestMethod must be POST");
411+
throw new \Webhook\InvalidRequestException("requestMethod must be POST");
412412
}
413413
$callback->validateRequest($request->getHubSignature(), $request->getMessageBody(), $request->getPayload());
414-
} catch(\Webhook\InvalidRequest $e) {
414+
} catch(\Webhook\InvalidRequestException $e) {
415415
http_response_code(500);
416-
echo "Invalid Request: ".$e->getMessage();
416+
echo $e->getMessage();
417417
}
418418

419419
EOT;

coverage.txt

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11

22

3-
Code Coverage Report:
4-
2018-11-29 09:49:46
5-
6-
Summary:
7-
Classes: 57.14% (8/14)
8-
Methods: 46.15% (18/39)
9-
Lines: 30.60% (71/232)
3+
Code Coverage Report:
4+
2018-11-30 01:39:31
5+
6+
Summary:
7+
Classes: 66.67% (12/18)
8+
Methods: 72.09% (31/43)
9+
Lines: 54.21% (116/214)
1010

1111
\Webhook::PopulatorTrait
1212
Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 11/ 11)
13+
\Webhook::Webhook\EventMissingException
14+
Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 2/ 2)
15+
\Webhook::Webhook\InvalidRequestException
16+
Methods: 50.00% ( 1/ 2) Lines: 75.00% ( 3/ 4)
17+
\Webhook::Webhook\MessageBodyInvalidException
18+
Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 2/ 2)
1319
\Webhook::Webhook\Payload
1420
Methods: 100.00% ( 2/ 2) Lines: 100.00% ( 5/ 5)
21+
\Webhook::Webhook\Request
22+
Methods: 66.67% ( 8/12) Lines: 66.67% ( 34/ 51)
23+
\Webhook::Webhook\SignatureInvalidException
24+
Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 2/ 2)
25+
\Webhook::Webhook\SignatureMissingException
26+
Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 2/ 2)
1527
\Webhook\Payload::Webhook\Payload\Event
1628
Methods: 100.00% ( 4/ 4) Lines: 100.00% ( 11/ 11)
1729
\Webhook\Payload::Webhook\Payload\PingEvent

src/Callback.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ class Callback {
1212
* @param \Webhook\Payload $payload Payload object.
1313
*
1414
* @return void
15-
* @throws \Webhook\InvalidRequest
15+
* @throws \Webhook\InvalidRequestException
1616
* @deprecated
1717
* @see \Webhook\Callback::validatePayload()
1818
*/
1919
public function validateRequest(string $hubSignature,string $rawPayload, Payload $payload) {
2020
if (!Request::isValidSignature($this->_hubSecret, $hubSignature, $rawPayload)) {
21-
throw new InvalidRequest("secret validation failed");
21+
throw new InvalidRequestException("secret validation failed");
2222
}
2323
return $this->validatePayload($payload);
2424
}
@@ -31,7 +31,7 @@ public function validateRequest(string $hubSignature,string $rawPayload, Payload
3131
* @param \Webhook\Payload $payload Payload object.
3232
*
3333
* @return void
34-
* @throws \Webhook\InvalidRequest
34+
* @throws \Webhook\InvalidRequestException
3535
*/
3636
public function validatePayload(Payload $payload) {
3737

@@ -65,7 +65,7 @@ public function validatePayload(Payload $payload) {
6565

6666
}
6767
unset($url);
68-
if (!$found_urlRule_match) throw new InvalidRequest("failed to find a match for the payload's repository URL; expected one of '".implode(", ",$this->_urlRule)."', got instead {$payload->repository->url}");
68+
if (!$found_urlRule_match) throw new InvalidRequestException("failed to find a match for the payload's repository URL; expected one of '".implode(", ",$this->_urlRule)."', got instead {$payload->repository->url}");
6969
}
7070

7171
if (count($this->_eventRule)) {
@@ -76,7 +76,7 @@ public function validatePayload(Payload $payload) {
7676
break 1;
7777
}
7878
}
79-
if (!$found_eventRule_match) throw new InvalidRequest("failed to find a match for the payload's GitHub-Event type");
79+
if (!$found_eventRule_match) throw new InvalidRequestException("failed to find a match for the payload's GitHub-Event type");
8080
}
8181

8282

src/EventMissingException.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
namespace Webhook;
3+
4+
class EventMissingException extends InvalidRequestException {
5+
const REASON_TEXT = "missing gitHubEvent";
6+
public function __construct() {
7+
parent::__construct(static::REASON_TEXT,static::REASON_CODE_MISSING_EVENT);
8+
}
9+
}

src/InvalidRequest.php

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,8 @@
11
<?php
22
namespace Webhook;
33

4-
class InvalidRequest extends \Exception {
5-
/**
6-
* Provides the reason the request was invalid.
7-
* @return string reason
8-
*/
9-
public function getReason(): string {
10-
return $this->_reason;
11-
}
12-
/**
13-
* @var string reason the request was invalid
14-
* @private
15-
*/
16-
private $_reason;
17-
/**
18-
* @param string reason the request was invalid
19-
*/
20-
public function __construct(string $reason) {
21-
$this->_reason = $reason;
22-
parent::__construct($reason);
23-
}
24-
}
4+
/**
5+
* Kept for legacy purposes.
6+
* @deprecated
7+
*/
8+
class InvalidRequest extends InvalidRequestException{}

src/InvalidRequestException.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
namespace Webhook;
3+
4+
class InvalidRequestException extends \Exception {
5+
6+
const REASON_CODE_SIGNATURE_INVALID = 100;
7+
const REASON_CODE_MISSING_EVENT = 101;
8+
const REASON_CODE_MISSING_SIGNATURE = 102;
9+
const REASON_CODE_MESSAGE_BODY_INVALID = 103;
10+
11+
/**
12+
* Provides the reason the request was invalid.
13+
* @return string reason
14+
*/
15+
public function getReason(): string {
16+
return $this->_reason;
17+
}
18+
/**
19+
* @var string reason the request was invalid
20+
* @private
21+
*/
22+
private $_reason;
23+
/**
24+
* @param string $reason reason the request was invalid
25+
* @param int $reason_code reason code
26+
*/
27+
public function __construct(string $reason="unknown error",int $reason_code=0) {
28+
$this->_reason = $reason;
29+
parent::__construct("Invalid Request: $reason",$reason_code);
30+
}
31+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
namespace Webhook;
3+
4+
class MessageBodyInvalidException extends InvalidRequestException {
5+
const REASON_TEXT = "messageBody is invalid: must be a JSON object or urlencoded string";
6+
public function __construct() {
7+
parent::__construct(static::REASON_TEXT,static::REASON_CODE_MESSAGE_BODY_INVALID);
8+
}
9+
}

src/Request.php

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -119,24 +119,25 @@ final public static function isValidSignature(string $hub_secret, string $hub_si
119119
* @param string $hub_secret Secret string known by the webhoook provider.
120120
*
121121
* @return void
122-
* @throws \Webhook\InvalidRequest
122+
* @throws \Webhook\SignatureInvalidException
123123
*/
124124
public function validateSignature(string $hub_secret) {
125125
if (!self::isValidSignature($hub_secret, $this->_hubSignature, $this->_messageBody)) {
126-
throw new InvalidRequest("secret validation failed");
126+
throw new SignatureInvalidException;
127127
}
128128
}
129129

130130
/**
131-
* @param string $messageBody
132-
* @param string $hubSignature
133-
* @param string $gitHubEvent
134-
* @param string $contentType Optional.
135-
* @param string $gitHubDelivery Optional.
136-
* @param string $requestMethod Optional.
137-
* @param string $userAgent Optional.
131+
* @param string $messageBody request body; the string value of the payload
132+
* @param string $hubSignature value of the 'X-Hub-Signature' header
133+
* @param string $gitHubEvent github event that triggered this request (i.e. "push" or "ping")
134+
* @param string $contentType Optionally specify mime type of the request body (i.e. "application/json")
135+
* @param string $gitHubDelivery Optionally specify value of the 'X-GitHub-Delivery' header
136+
* @param string $requestMethod Optionally specify request method (i.e. "POST")
137+
* @param string $userAgent Optionally specify value of the 'User-Agent' header
138138
*
139-
* @throws \Webhook\InvalidRequest if invalid value specified for hubSignature, or gitHubEvent;
139+
* @throws \Webhook\SignatureMissingException
140+
* @throws \Webhook\EventMissingException
140141
*/
141142
public function __construct(
142143
string $messageBody,string $hubSignature,string $gitHubEvent,
@@ -150,25 +151,33 @@ public function __construct(
150151
$this->_hubSignature = $hubSignature;
151152
$this->_gitHubDelivery = $gitHubDelivery;
152153
$this->_requestMethod = $requestMethod;
154+
$this->_userAgent = $userAgent;
155+
156+
$bodyObject = null;
153157

154158
if (empty($this->_contentType)) {
155-
$this->_contentType = (new \finfo(\FILEINFO_MIME_TYPE))->buffer($this->_messageBody);
159+
if ((null!==($bodyObject = json_decode($this->_messageBody))) && is_object($bodyObject)) {
160+
$this->_contentType = 'application/json';
161+
}
156162
}
157163

158-
$bodyObject = null;
159-
if ($this->_contentType == 'application/json') {
160-
$bodyObject = json_decode($this->_messageBody);
161-
} elseif ($this->_contentType == 'application/x-www-form-urlencoded') {
162-
parse_str($this->_messageBody,$bodyObject);
164+
if ($bodyObject===null) {
165+
if ($this->_contentType === 'application/json') {
166+
$bodyObject = json_decode($this->_messageBody);
167+
}
168+
}
169+
170+
if (empty($bodyObject) || !is_object($bodyObject)) {
171+
throw new MessageBodyInvalidException;
163172
}
164173

165174
if (empty($this->_hubSignature)) {
166-
throw new InvalidRequest("missing hubSignature");
175+
throw new SignatureMissingException;
167176
}
168177

169178
$payload = null;
170179
$eventSubns = "";
171-
if (!empty($this->_gitHubEvent) && !empty($bodyObject)) {
180+
if (!empty($this->_gitHubEvent)) {
172181
$eventSubns = str_replace(" ","",ucwords(str_replace("_"," ",$this->_gitHubEvent)))."Event";
173182
$payload = __NAMESPACE__ . '\Payload\\'.$eventSubns;
174183
if (class_exists($payload)) {
@@ -177,7 +186,7 @@ public function __construct(
177186
$this->_payload = new Payload\Event($bodyObject, $this->_gitHubEvent);
178187
}
179188
} else {
180-
throw new InvalidRequest("missing gitHubEvent");
189+
throw new EventMissingException;
181190
}
182191
}
183192

src/SignatureInvalidException.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
namespace Webhook;
3+
4+
class SignatureInvalidException extends InvalidRequestException {
5+
const REASON_TEXT = "invalid hubSignature";
6+
public function __construct() {
7+
parent::__construct(static::REASON_TEXT,static::REASON_CODE_SIGNATURE_INVALID);
8+
}
9+
}

src/SignatureMissingException.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
namespace Webhook;
3+
4+
class SignatureMissingException extends InvalidRequestException {
5+
const REASON_TEXT = "missing hubSignature";
6+
public function __construct() {
7+
parent::__construct(static::REASON_TEXT,static::REASON_CODE_MISSING_SIGNATURE);
8+
}
9+
}

0 commit comments

Comments
 (0)