Skip to content

Commit 825c084

Browse files
committed
Added tests
1 parent c8cc060 commit 825c084

15 files changed

+420
-8
lines changed

composer.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
"Stackkit\\LaravelGoogleCloudTasksQueue\\": "src/"
2222
}
2323
},
24+
"autoload-dev": {
25+
"psr-4": {
26+
"Tests\\": "tests/"
27+
}
28+
},
2429
"extra": {
2530
"laravel": {
2631
"providers": [

phpunit.xml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false">
11+
12+
<testsuites>
13+
<testsuite name="Orchestra\Testbench Test Suite">
14+
<directory suffix="Test.php">./tests/</directory>
15+
</testsuite>
16+
</testsuites>
17+
<php>
18+
<env name="APP_DEBUG" value="1"/>
19+
<env name="APP_ENV" value="testing"/>
20+
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
21+
<env name="CACHE_DRIVER" value="array"/>
22+
<env name="SESSION_DRIVER" value="array"/>
23+
<env name="MAIL_DRIVER" value="log"/>
24+
<env name="QUEUE_DRIVER" value="cloudtasks"/>
25+
</php>
26+
27+
<filter>
28+
<whitelist addUncoveredFilesFromWhitelist="false">
29+
<directory suffix=".php">src/</directory>
30+
</whitelist>
31+
</filter>
32+
</phpunit>

src/CloudTasksConnector.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ class CloudTasksConnector implements ConnectorInterface
99
{
1010
public function connect(array $config)
1111
{
12-
return new CloudTasksQueue(
13-
$config,
14-
new CloudTasksClient($this->buildConfig())
15-
);
12+
Config::validate($config);
13+
14+
// @todo - clean this up
15+
if (app()->has(CloudTasksClient::class)) {
16+
$client = app(CloudTasksClient::class);
17+
} else {
18+
$client = new CloudTasksClient($this->buildConfig());
19+
}
20+
21+
return new CloudTasksQueue($config, $client);
1622
}
1723

1824
private function buildConfig()

src/CloudTasksQueue.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ protected function pushToCloudTasks($queue, $payload, $delay = 0, $attempts = 0)
5555
$queueName = $this->client->queueName(Config::project(), Config::location(), $queue);
5656
$availableAt = $this->availableAt($delay);
5757

58-
$httpRequest = new HttpRequest();
58+
$httpRequest = app(HttpRequest::class);
5959
$httpRequest->setUrl(Config::handler());
6060
$httpRequest->setHttpMethod(HttpMethod::POST);
6161
$httpRequest->setBody($payload);
6262

63-
$task = new Task;
63+
$task = app(Task::class);
6464
$task->setHttpRequest($httpRequest);
6565

6666
if ($availableAt > time()) {

src/Config.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Stackkit\LaravelGoogleCloudTasksQueue;
44

5+
use Error;
6+
57
class Config
68
{
79
public static function credentials()
@@ -23,4 +25,27 @@ public static function handler()
2325
{
2426
return config('queue.connections.cloudtasks.handler');
2527
}
28+
29+
public static function validate(array $config)
30+
{
31+
if (empty($config['credentials'])) {
32+
throw new Error(Errors::invalidCredentials());
33+
}
34+
35+
if (!file_exists($config['credentials'])) {
36+
throw new Error(Errors::credentialsFileDoesNotExist());
37+
}
38+
39+
if (empty($config['project'])) {
40+
throw new Error(Errors::invalidProject());
41+
}
42+
43+
if (empty($config['location'])) {
44+
throw new Error(Errors::invalidLocation());
45+
}
46+
47+
if (empty($config['handler'])) {
48+
throw new Error(Errors::invalidHandler());
49+
}
50+
}
2651
}

src/Errors.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Stackkit\LaravelGoogleCloudTasksQueue;
4+
5+
class Errors
6+
{
7+
public static function invalidCredentials()
8+
{
9+
return 'Google Cloud credentials not provided. To fix this, in config/queue.php, connections.cloudtasks.credentials, provide the path to your credentials JSON file';
10+
}
11+
12+
public static function credentialsFileDoesNotExist()
13+
{
14+
return 'Google Cloud credentials JSON file does not exist';
15+
}
16+
17+
public static function invalidProject()
18+
{
19+
return 'Google Cloud project not provided. To fix this, set the STACKKIT_CLOUD_TASKS_PROJECT environment variable';
20+
}
21+
22+
public static function invalidLocation()
23+
{
24+
return 'Google Cloud Tasks location not provided. To fix this, set the STACKKIT_CLOUD_TASKS_LOCATION environment variable';
25+
}
26+
27+
public static function invalidHandler()
28+
{
29+
return 'Google Cloud Tasks handler not provided. To fix this, set the STACKKIT_CLOUD_TASKS_HANDLER environment variable';
30+
}
31+
}

src/TaskHandler.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
class TaskHandler
1010
{
1111
/**
12+
* @param $task
1213
* @throws CloudTasksException
1314
*/
14-
public function handle()
15+
public function handle($task = null)
1516
{
16-
$task = $this->captureTask();
17+
$task = $task ?: $this->captureTask();
1718

1819
$this->handleTask($task);
1920
}

tests/ConfigTest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
use Error;
6+
use Stackkit\LaravelGoogleCloudTasksQueue\Errors;
7+
use Tests\Support\SimpleJob;
8+
9+
class ConfigTest extends TestCase
10+
{
11+
/** @test */
12+
public function credentials_are_required()
13+
{
14+
$this->setConfigValue('credentials', '');
15+
16+
$this->expectException(Error::class);
17+
$this->expectExceptionMessage(Errors::invalidCredentials());
18+
19+
SimpleJob::dispatch();
20+
}
21+
22+
/** @test */
23+
public function credentials_file_must_exist()
24+
{
25+
$this->setConfigValue('credentials', 'doesnotexist.json');
26+
27+
$this->expectException(Error::class);
28+
$this->expectExceptionMessage(Errors::credentialsFileDoesNotExist());
29+
30+
SimpleJob::dispatch();
31+
}
32+
33+
/** @test */
34+
public function project_is_required()
35+
{
36+
$this->setConfigValue('project', '');
37+
38+
$this->expectException(Error::class);
39+
$this->expectExceptionMessage(Errors::invalidProject());
40+
41+
SimpleJob::dispatch();
42+
}
43+
44+
/** @test */
45+
public function location_is_required()
46+
{
47+
$this->setConfigValue('location', '');
48+
49+
$this->expectException(Error::class);
50+
$this->expectExceptionMessage(Errors::invalidLocation());
51+
52+
SimpleJob::dispatch();
53+
}
54+
55+
/** @test */
56+
public function handler_is_required()
57+
{
58+
$this->setConfigValue('handler', '');
59+
60+
$this->expectException(Error::class);
61+
$this->expectExceptionMessage(Errors::invalidHandler());
62+
63+
SimpleJob::dispatch();
64+
}
65+
}

tests/QueueTest.php

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
use Carbon\Carbon;
6+
use Google\Cloud\Tasks\V2\CloudTasksClient;
7+
use Google\Cloud\Tasks\V2\HttpMethod;
8+
use Google\Cloud\Tasks\V2\HttpRequest;
9+
use Google\Cloud\Tasks\V2\Task;
10+
use Google\Protobuf\Timestamp;
11+
use Mockery;
12+
use Tests\Support\SimpleJob;
13+
14+
class QueueTest extends TestCase
15+
{
16+
private $client;
17+
private $http;
18+
private $task;
19+
20+
protected function setUp(): void
21+
{
22+
parent::setUp();
23+
24+
$this->client = Mockery::mock(CloudTasksClient::class)->makePartial();
25+
$this->http = Mockery::mock(HttpRequest::class)->makePartial();
26+
$this->task = Mockery::mock(new Task);
27+
28+
$this->app->instance(CloudTasksClient::class, $this->client);
29+
$this->app->instance(HttpRequest::class, $this->http);
30+
$this->app->instance(Task::class, $this->task);
31+
32+
// ensure we don't actually call the Google API
33+
$this->client->shouldReceive('createTask')->andReturnNull();
34+
}
35+
36+
/** @test */
37+
public function a_http_request_with_the_handler_url_is_made()
38+
{
39+
SimpleJob::dispatch();
40+
41+
$this->http
42+
->shouldHaveReceived('setUrl')
43+
->with('https://localhost/my-handler')
44+
->once();
45+
}
46+
47+
/** @test */
48+
public function it_posts_to_the_handler()
49+
{
50+
SimpleJob::dispatch();
51+
52+
$this->http->shouldHaveReceived('setHttpMethod')->with(HttpMethod::POST)->once();
53+
}
54+
55+
/** @test */
56+
public function it_posts_the_serialized_job_payload_to_the_handler()
57+
{
58+
$job = new SimpleJob();
59+
$job->dispatch();
60+
61+
$this->http->shouldHaveReceived('setBody')->with(Mockery::on(function ($payload) use ($job) {
62+
$decoded = json_decode($payload, true);
63+
64+
if ($decoded['displayName'] != 'Tests\Support\SimpleJob') {
65+
return false;
66+
}
67+
68+
if ($decoded['job'] != 'Illuminate\Queue\CallQueuedHandler@call') {
69+
return false;
70+
}
71+
72+
if ($decoded['data']['commandName'] != 'Tests\Support\SimpleJob') {
73+
return false;
74+
}
75+
76+
if ($decoded['data']['command'] != serialize($job)) {
77+
return false;
78+
}
79+
80+
return true;
81+
}));
82+
}
83+
84+
/** @test */
85+
public function it_creates_a_task_containing_the_http_request()
86+
{
87+
$this->task->shouldReceive('setHttpRequest')->once()->with($this->http);
88+
89+
SimpleJob::dispatch();
90+
}
91+
92+
/** @test */
93+
public function it_will_set_the_scheduled_time_when_dispatching_later()
94+
{
95+
$inFiveMinutes = Carbon::now()->addMinutes(5);
96+
97+
SimpleJob::dispatch()->delay($inFiveMinutes);
98+
99+
$this->task->shouldHaveReceived('setScheduleTime')->once()->with(Mockery::on(function (Timestamp $timestamp) use ($inFiveMinutes) {
100+
return $timestamp->getSeconds() === $inFiveMinutes->timestamp;
101+
}));
102+
}
103+
104+
/** @test */
105+
public function it_posts_the_task_the_correct_queue()
106+
{
107+
SimpleJob::dispatch();
108+
109+
$this->client
110+
->shouldHaveReceived('createTask')
111+
->withArgs(function ($queueName) {
112+
return $queueName === 'projects/test-project/locations/europe-west6/queues/test-queue';
113+
});
114+
}
115+
116+
/** @test */
117+
public function it_posts_the_correct_task_the_queue()
118+
{
119+
SimpleJob::dispatch();
120+
121+
$this->client
122+
->shouldHaveReceived('createTask')
123+
->withArgs(function ($queueName, $task) {
124+
return $task === $this->task;
125+
});
126+
}
127+
}

tests/Support/SimpleJob.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Tests\Support;
4+
5+
use Illuminate\Bus\Queueable;
6+
use Illuminate\Contracts\Queue\ShouldQueue;
7+
use Illuminate\Foundation\Bus\Dispatchable;
8+
use Illuminate\Queue\InteractsWithQueue;
9+
use Illuminate\Queue\SerializesModels;
10+
use Illuminate\Support\Facades\Mail;
11+
12+
class SimpleJob implements ShouldQueue
13+
{
14+
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
15+
16+
/**
17+
* Create a new job instance.
18+
*
19+
* @return void
20+
*/
21+
public function __construct()
22+
{
23+
//
24+
}
25+
26+
/**
27+
* Execute the job.
28+
*
29+
* @return void
30+
*/
31+
public function handle()
32+
{
33+
Mail::to('johndoe@example.com')->send(new TestMailable());
34+
}
35+
}

0 commit comments

Comments
 (0)