diff --git a/CHANGELOG.md b/CHANGELOG.md index ecbbd8c..143dc05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.5.1 + +- Corrected the write-permission wording on `TaskClient::publish()`/`unpublish()`: the OpenAPI spec + states that both `isPublic` and `publicConfig` require write permission to the task's Actor, not + (as `unpublish()`'s docblock previously claimed) permission to the task alone. `publish()`'s + docblock now also states the Actor's fewer-than-50-published-tasks limit. +- `docs/tasks.md` updated to match. + ## 0.5.0 Breaking: `RequestQueueClient` methods that previously returned a raw `array` (or, for diff --git a/docs/tasks.md b/docs/tasks.md index cf7f54a..61444a2 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -25,8 +25,9 @@ foreach ($client->tasks()->iterate(new ListOptions(), 50) as $t) { - `get(): ?Task`, `update(mixed $newFields): Task`, `delete(): void` - `publish(): Task`, `unpublish(): Task` — publish/unpublish the task's public landing page, by - setting `isPublic` through `update()`. Publishing requires the task's Actor to be public and the - task to already have its `publicConfig` set up. + setting `isPublic` through `update()`. Both require write permission to the task's Actor; + publishing additionally requires the Actor to be public, to have fewer than 50 already-published + tasks, and the task's `publicConfig.inputSchemaFields`/`publicConfig.datasetView` to be set. - `start(mixed $input = null, ?TaskStartOptions $options = null): ActorRun` - `call(mixed $input = null, ?TaskStartOptions $options = null, ?int $waitSecs = null): ActorRun` - `getInput(): mixed`, `updateInput(mixed $input): mixed` diff --git a/src/Resource/TaskClient.php b/src/Resource/TaskClient.php index 1a76746..d04f814 100644 --- a/src/Resource/TaskClient.php +++ b/src/Resource/TaskClient.php @@ -59,11 +59,12 @@ public function delete(): void /** * Publishes the task on its public landing page, by setting {@code isPublic} through - * {@see update()}. + * {@see update()}. Requires write permission to the task's Actor. * - * The task's Actor must be public and the task must have its public display configuration - * ({@code publicConfig}) set up first. Requires write permission to both the task and its - * Actor. Publishing an already published task does nothing. + * To publish, the task's Actor must be public, its {@code publicConfig.inputSchemaFields} and + * {@code publicConfig.datasetView} must be set, and the Actor must have fewer than 50 + * published tasks; if any of these are not met, the request fails and nothing is changed. + * Publishing an already published task does nothing. */ public function publish(): Task { @@ -72,12 +73,12 @@ public function publish(): Task /** * Unpublishes the task from its public landing page, by setting {@code isPublic} through - * {@see update()}. + * {@see update()}. Like {@see publish()}, this requires write permission to the task's Actor: + * the API requires Actor write permission for both {@code isPublic} and {@code publicConfig}. * * The public display configuration ({@code publicConfig}) is preserved, so the task can be - * published again without re-entering it. Unlike {@see publish()}, this only requires write - * permission to the task itself (not its Actor), since it does not need to validate the - * Actor's public/display eligibility. Unpublishing a task that is not published does nothing. + * published again without re-entering it. Unpublishing a task that is not published does + * nothing. */ public function unpublish(): Task { diff --git a/src/Version.php b/src/Version.php index cf4211a..efde3e8 100644 --- a/src/Version.php +++ b/src/Version.php @@ -17,7 +17,7 @@ final class Version * The semantic version of this client library (see https://semver.org/). * Changes to the public interface other than additive ones are considered breaking changes. */ - public const CLIENT_VERSION = '0.5.0'; + public const CLIENT_VERSION = '0.5.1'; /** * The version of the Apify OpenAPI specification this client was generated and verified diff --git a/tests/Unit/TaskPublishUnpublishTest.php b/tests/Unit/TaskPublishUnpublishTest.php new file mode 100644 index 0000000..f3069df --- /dev/null +++ b/tests/Unit/TaskPublishUnpublishTest.php @@ -0,0 +1,56 @@ +queueResponse(200, Json::encode(['data' => [ + 'id' => 'task1', + 'isPublic' => true, + ]])); + + $task = $this->client($transport)->task('task1')->publish(); + + self::assertTrue($task->isPublic()); + $request = $transport->lastRequest(); + self::assertSame('PUT', $request->getMethod()); + self::assertStringContainsString('/actor-tasks/task1', (string) $request->getUri()); + self::assertSame(['isPublic' => true], Json::decode(MockTransport::readBody($request))); + } + + public function testUnpublishSendsIsPublicFalse(): void + { + $transport = (new MockTransport())->queueResponse(200, Json::encode(['data' => [ + 'id' => 'task1', + 'isPublic' => false, + ]])); + + $task = $this->client($transport)->task('task1')->unpublish(); + + self::assertNotTrue($task->isPublic()); + $request = $transport->lastRequest(); + self::assertSame('PUT', $request->getMethod()); + self::assertStringContainsString('/actor-tasks/task1', (string) $request->getUri()); + self::assertSame(['isPublic' => false], Json::decode(MockTransport::readBody($request))); + } +}