Skip to content

Commit 1e9f27e

Browse files
author
bryanadamloh97
committed
Add initial test case
1 parent 2fa2d5b commit 1e9f27e

File tree

7 files changed

+228
-1
lines changed

7 files changed

+228
-1
lines changed

LICENSE renamed to LICENSE.md

File renamed without changes.

composer.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,21 @@
3232
},
3333
"require-dev": {
3434
"illuminate/routing": "^5.1 || ^6.0 || ^7.0",
35-
"phpunit/phpunit": "^7.0"
35+
"phpunit/phpunit": "^8.2"
3636
},
3737
"autoload": {
3838
"psr-4": {
3939
"CodeOfDigital\\LaravelUrlShortener\\": "src/"
4040
}
4141
},
42+
"autoload-dev": {
43+
"psr-4": {
44+
"CodeOfDigital\\LaravelUrlShortener\\Tests\\": "tests/"
45+
}
46+
},
47+
"scripts": {
48+
"tests": "./vendor/bin/phpunit --colors=always"
49+
},
4250
"extra": {
4351
"laravel": {
4452
"providers": [

tests/Responses/bit_ly/http-200.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
use GuzzleHttp\Psr7\Message;
4+
5+
return Message::parseResponse(trim('
6+
HTTP/1.1 200 OK
7+
Server: nginx
8+
Date: Mon, 14 Jun 2021 16:55:09 GMT
9+
Content-Type: application/json
10+
Content-Length: 263
11+
Connection: keep-alive
12+
Strict-Transport-Security: max-age=31536000; includeSubDomains
13+
X-XSS-Protection: 1; mode=blockFilter
14+
X-Content-Type-Options: nosniff
15+
X-Frame-Options: DENY
16+
Content-Security-Policy: default-src \'none
17+
18+
{"created_at":"2021-06-14T13:46:33+0000","id":"bit.ly/3iSAOvF","link":"https://bit.ly/3iSAOvF","custom_bitlinks":[],"long_url":"https://laravel.com/","archived":false,"tags":[],"deeplinks":[],"references":{"group":"https://api-ssl.bitly.com/v4/groups/Bl6a5s21gp1"}}
19+
'));

tests/Responses/bit_ly/http-403.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
use GuzzleHttp\Psr7\Message;
4+
5+
return Message::parseResponse(trim('
6+
HTTP/1.1 403 Forbidden
7+
Server: nginx
8+
Date: Mon, 14 Jun 2021 16:55:09 GMT
9+
Content-Type: application/json
10+
Content-Length: 23
11+
Connection: keep-alive
12+
Strict-Transport-Security: max-age=31536000; includeSubDomains
13+
X-XSS-Protection: 1; mode=blockFilter
14+
X-Content-Type-Options: nosniff
15+
X-Frame-Options: DENY
16+
Content-Security-Policy: default-src \'none
17+
18+
{"message":"FORBIDDEN"}
19+
'));

tests/Unit/BitLyShortenerTest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace CodeOfDigital\LaravelUrlShortener\Tests\Unit;
4+
5+
use CodeOfDigital\LaravelUrlShortener\Drivers\BitLyDriverShortener;
6+
use CodeOfDigital\LaravelUrlShortener\Exceptions\InvalidApiTokenException;
7+
use CodeOfDigital\LaravelUrlShortener\Exceptions\ShortUrlException;
8+
9+
class BitLyShortenerTest extends TestCase
10+
{
11+
protected $shortener;
12+
13+
protected function setUp(): void
14+
{
15+
parent::setUp();
16+
$this->shortener = new BitLyDriverShortener($this->client, 'API_TOKEN', false);
17+
}
18+
19+
/**
20+
* Test the URL Shortening through Bit.ly
21+
*
22+
* @throws \CodeOfDigital\LaravelUrlShortener\Exceptions\ShortUrlException
23+
*/
24+
public function testUrlShortening()
25+
{
26+
$this->client->queue(require __DIR__ . '/../Responses/bit_ly/http-200.php');
27+
28+
$shortUrl = $this->shortener->shorten('https://laravel.com');
29+
$request = $this->client->getRequest(0);
30+
31+
$this->assertNotNull($request);
32+
$this->assertEquals('POST', $request->getMethod());
33+
$this->assertEquals('api-ssl.bitly.com', $request->getUri()->getHost());
34+
$this->assertEquals('/v4/shorten', $request->getRequestTarget());
35+
$this->assertEquals('Bearer API_TOKEN', $request->getHeader('Authorization')[0]);
36+
$this->assertEquals('application/json', $request->getHeader('Content-Type')[0]);
37+
38+
$this->assertEquals('https://bit.ly/3iSAOvF', $shortUrl);
39+
}
40+
41+
/**
42+
* Test failure to authenticate with Bit.ly
43+
*
44+
* @throws \CodeOfDigital\LaravelUrlShortener\Exceptions\ShortUrlException
45+
*/
46+
public function testUnauthorized()
47+
{
48+
$this->client->queue(require __DIR__ . '/../Responses/bit_ly/http-403.php');
49+
$this->expectException(InvalidApiTokenException::class);
50+
$this->shortener->shorten('https://laravel.com');
51+
}
52+
53+
/**
54+
* Test failure if parsed URL is invalid or incorrect format
55+
*
56+
* @throws ShortUrlException
57+
*/
58+
public function testInvalidUrl()
59+
{
60+
$this->expectException(ShortUrlException::class);
61+
$this->shortener->shorten('some-string.com');
62+
}
63+
}

tests/Unit/MockClient.php

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
namespace CodeOfDigital\LaravelUrlShortener\Tests\Unit;
4+
5+
use GuzzleHttp\Client;
6+
use GuzzleHttp\Handler\MockHandler;
7+
use GuzzleHttp\HandlerStack;
8+
use GuzzleHttp\Middleware;
9+
use GuzzleHttp\Utils;
10+
use Psr\Http\Message\ResponseInterface;
11+
12+
class MockClient extends Client
13+
{
14+
protected $handler;
15+
protected $history;
16+
17+
public function __construct(array $config = [])
18+
{
19+
$this->handler = new MockHandler();
20+
$this->history = [];
21+
22+
parent::__construct($config + ['handler' => $this->newHandlerStack($this->handler)]);
23+
}
24+
25+
/**
26+
* Get the client history
27+
*
28+
* @param int|null $at
29+
* @return array|mixed|null
30+
*/
31+
public function getHistory(int $at = null)
32+
{
33+
if (is_null($at)) {
34+
return $this->history;
35+
}
36+
37+
return $this->history[$at] ?? null;
38+
}
39+
40+
/**
41+
* Get a previously made request
42+
*
43+
* @param int $at
44+
* @return mixed|null
45+
*/
46+
public function getRequest(int $at)
47+
{
48+
return $this->getHistory($at)['request'] ?? null;
49+
}
50+
51+
/**
52+
* Get the amount of messages waiting in the queue.
53+
*
54+
* @return int
55+
*/
56+
public function getQueueSize()
57+
{
58+
return $this->handler->count();
59+
}
60+
61+
/**
62+
* Determine if there are queued messages.
63+
*
64+
* @return bool
65+
*/
66+
public function hasQueuedMessages()
67+
{
68+
return $this->getQueueSize() > 0;
69+
}
70+
71+
/**
72+
* Get a fresh handler stack
73+
*
74+
* @param null $handler
75+
* @return HandlerStack
76+
*/
77+
protected function newHandlerStack($handler = null)
78+
{
79+
$stack = new HandlerStack($handler ?: Utils::chooseHandler());
80+
$stack->push(Middleware::history($this->history));
81+
$stack->push(Middleware::httpErrors());
82+
return $stack;
83+
}
84+
85+
/**
86+
* Queue the given response
87+
*
88+
* @param ResponseInterface ...$responses
89+
* @return $this
90+
*/
91+
public function queue(ResponseInterface ...$responses)
92+
{
93+
$this->handler->append(...$responses);
94+
95+
return $this;
96+
}
97+
}

tests/Unit/TestCase.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace CodeOfDigital\LaravelUrlShortener\Tests\Unit;
4+
5+
use PHPUnit\Framework\TestCase as PHPTestCase;
6+
7+
abstract class TestCase extends PHPTestCase
8+
{
9+
protected $client;
10+
11+
protected function setUp(): void
12+
{
13+
$this->client = new MockClient();
14+
}
15+
16+
protected function tearDown(): void
17+
{
18+
if ($this->client->hasQueuedMessages())
19+
$this->fail(sprintf('HTTP Client contains %d unused message(s)', $this->client->getQueueSize()));
20+
}
21+
}

0 commit comments

Comments
 (0)