Skip to content

Commit c6ac8f4

Browse files
authored
Merge pull request #15 from ingenerator/0.5-feat-custom-handler-url
Support specifying a custom_handler_url for a task despatch
2 parents 63f47df + 00e72cf commit c6ac8f4

File tree

5 files changed

+77
-4
lines changed

5 files changed

+77
-4
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## Unreleased
22

3+
## v0.5.1 (2023-03-30)
4+
5+
* Allow clients to specify a custom_handler_url when creating a task, to override the default handler_url provided
6+
by the configuration for the task type. Useful when the handler url is dependent on something that can only be
7+
determined at runtime (e.g. routing to a subdomain).
8+
39
* Support a `custom_token_audience` in the TaskType options, to allow specifying a non-default `audience` in the JWT
410
that Cloud Tasks issues to authorise the request.
511

src/Client/CloudTaskCreator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function create(string $task_type_name, ?CreateTaskOptions $options = NUL
4040
$task_type = $this->task_config->getConfig($task_type_name);
4141
$options ??= new CreateTaskOptions([]);
4242

43-
$handler_url = $task_type->getHandlerUrl();
43+
$handler_url = $options->getCustomHandlerUrl() ?? $task_type->getHandlerUrl();
4444
if ($options->hasQuery()) {
4545
$handler_url .= '?'.\http_build_query($options->getQuery());
4646
}

src/Client/CreateTaskOptions.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Ingenerator\PHPUtils\DateTime\DateTimeImmutableFactory;
88
use Ingenerator\PHPUtils\Object\ObjectPropertyPopulator;
99
use Ingenerator\PHPUtils\StringEncoding\JSON;
10+
use function str_contains;
1011

1112
class CreateTaskOptions
1213
{
@@ -41,6 +42,11 @@ class CreateTaskOptions
4142
*/
4243
private array $headers = [];
4344

45+
/**
46+
* Optionally specify a complete URL the task should be sent to, otherwise this will come from the TaskTypeConfig
47+
*/
48+
private ?string $custom_handler_url = NULL;
49+
4450
/**
4551
* Optionally add GET parameters to the handler URL.
4652
*
@@ -150,6 +156,12 @@ public function __construct(array $options)
150156
throw new \InvalidArgumentException('Cannot set both task_id and task_id_hash_options');
151157
}
152158

159+
if (str_contains($this->custom_handler_url ?? '', '?') and ! empty($this->query)) {
160+
throw new \InvalidArgumentException(
161+
'Cannot set a query if your custom_handler_url already includes a querystring'
162+
);
163+
}
164+
153165
if (isset($options['throttle_delay_secs']) and ! $this->throttle_interval) {
154166
// Only matters if they set it explicitly so we check $options not the property which has a default
155167
throw new \InvalidArgumentException('Cannot use throttle_delay_secs without throttle_interval');
@@ -277,6 +289,11 @@ public function getHeaders(): array
277289
return $this->headers;
278290
}
279291

292+
public function getCustomHandlerUrl(): ?string
293+
{
294+
return $this->custom_handler_url;
295+
}
296+
280297
/**
281298
* @return array|null
282299
*/

test/unit/Client/CloudTaskCreatorTest.php

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,39 @@ public function test_it_configures_custom_audience_for_authenticated_task_if_con
9393
$this->assertSame($expect, $task->getHttpRequest()->getOidcToken()->getAudience());
9494
}
9595

96+
public function provider_task_url()
97+
{
98+
return [
99+
'just from config, no query' => [
100+
[],
101+
"https://my.handler.foo/something",
102+
],
103+
'from config, with CreateTaskOptions.query' => [
104+
['query' => ['id' => 15, 'scope' => 'any']],
105+
"https://my.handler.foo/something?id=15&scope=any",
106+
],
107+
'with CreateTaskOptions.custom_handler_url and no query' => [
108+
['custom_handler_url' => 'https://my-handler.com/whatever'],
109+
"https://my-handler.com/whatever",
110+
],
111+
'with CreateTaskOptions.custom_handler_url including own query and no query' => [
112+
['custom_handler_url' => 'https://my-handler.com/whatever?foo=bar'],
113+
"https://my-handler.com/whatever?foo=bar",
114+
],
115+
'with CreateTaskOptions.custom_handler_url and CreateTaskOptions.query' => [
116+
[
117+
'custom_handler_url' => 'https://my-handler.com/whatever',
118+
'query' => ['id' => 15, 'scope' => 'any'],
119+
],
120+
"https://my-handler.com/whatever?id=15&scope=any",
121+
],
122+
];
123+
}
124+
96125
/**
97-
* @testWith [[], "https://my.handler.foo/something"]
98-
* [{"query": {"id": 15, "scope": "any"}}, "https://my.handler.foo/something?id=15&scope=any"]
126+
* @dataProvider provider_task_url
99127
*/
100-
public function test_it_sets_task_to_post_to_provided_url_optionally_adding_query_params($opts, $expect)
128+
public function test_it_sets_task_to_post_to_custom_or_config_url_optionally_adding_query_params($opts, $expect)
101129
{
102130
$this->task_config = TaskTypeConfigStub::withTaskType(
103131
'do-something',

test/unit/Client/CreateTaskOptionsTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Ingenerator\CloudTasksWrapper\Client\CreateTaskOptions;
88
use Ingenerator\PHPUtils\Object\ObjectPropertyRipper;
9+
use InvalidArgumentException;
910
use PHPUnit\Framework\TestCase;
1011

1112
class CreateTaskOptionsTest extends TestCase
@@ -89,6 +90,27 @@ public function test_it_can_have_query($opts, $expect)
8990
}
9091
}
9192

93+
/**
94+
* @testWith [{"query": {"foo": "bar"}, "custom_handler_url": "http://some.service/wherever"}, true]
95+
* [{"custom_handler_url": "http://some.service/wherever?hardcoded=query"}, true]
96+
* [{"query": {"foo": "bar"}, "custom_handler_url": "http://some.service/wherever?hardcoded=query"}, false]
97+
*/
98+
public function test_it_only_allows_query_with_custom_url_if_url_does_not_contain_a_query($opts, $is_valid)
99+
{
100+
$e = NULL;
101+
try {
102+
$subject = new CreateTaskOptions($opts);
103+
} catch (\InvalidArgumentException $e) {
104+
}
105+
106+
if ($is_valid) {
107+
$this->assertNull($e, (string ) $e);
108+
} else {
109+
$this->assertInstanceOf(InvalidArgumentException::class, $e);
110+
$this->assertStringContainsString('querystring', $e->getMessage());
111+
}
112+
}
113+
92114
public function provider_body_encoding()
93115
{
94116
return [

0 commit comments

Comments
 (0)