Skip to content

refactor(tests): build the e2e client on utopia-php/client - #261

Merged
ChiragAgg5k merged 2 commits into
mainfrom
refactor/test-client-on-client
Oct 8, 2026
Merged

ChiragAgg5k merged 2 commits into
mainfrom
refactor/test-client-on-client

Conversation

@ChiragAgg5k

@ChiragAgg5k ChiragAgg5k commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

utopia-php/fetch is archived. The executor's own code already uses utopia-php/client ^0.6, and fetch was left only as a dev dependency for tests/e2e/Client.php. That class extends Utopia\Fetch\Client, and appwrite-labs/edge reuses it (through vendor/open-runtimes/executor/tests/e2e) for its executor E2E suite. Edge has to keep fetch too until this changes.

This rewrites the test client on utopia-php/client (cURL adapter) and drops utopia-php/fetch from require-dev. The lock loses only utopia-php/fetch 1.1.2.

The public surface is unchanged, because Edge's K8sExecutorClient extends this class and uses self::METHOD_POST:

  • __construct(string $endpoint, array $baseHeaders = []), setKey().
  • call(...) with the same signature and return shape (headers with lowercased names plus status-code, body).
  • METHOD_GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS constants. They are now declared here instead of inherited, and the values are the same strings.
  • It no longer extends a client class. Nothing in this repository or in Edge calls an inherited fetch method on it.

fetch's request semantics are kept on purpose, since several tests depend on them:

  • No Accept header is added. The accept-header tests send their own, and psr7's json() helper would have added application/json, so the body is built with json_encode directly.
  • GET parameters use http_build_query's default encoding (+ for spaces), as fetch did, not psr7's RFC 3986 query().
  • Bodies are JSON, form-encoded or multipart by the request's content type. Multipart params are flattened to parent[child] fields with null as an empty field, as fetch handed them to curl, and the request carries the factory's multipart/form-data; boundary=… content type, which libcurl used to add. An unknown content type with a non-empty body throws instead of guessing.
  • Up to 5 redirects are followed, the connect timeout is 5s, and the $timeout argument stays in milliseconds.
  • Response headers are lowercased, and the last value of a repeated header wins, as fetch's header callback did.
  • With a $callback, chunks are streamed through Client::stream() and body is null.

One wire difference: the client asks for compressed responses (Accept-Encoding) and decodes them. fetch sent no Accept-Encoding. Bodies come back identical. On a compressed response, content-encoding and content-length are dropped from the returned headers. No test here or in Edge asserts on them, and the executor doesn't compress its responses.

Part of appwrite/appwrite#13828. Once this is released, Edge bumps to it and drops fetch entirely.

Tests

  • composer format:check, composer analyze, composer refactor:check and composer test:unit (37 tests) all pass.
  • A smoke run against a local PHP echo server matched fetch's behaviour on these cases:
    • GET query encoding;
    • the JSON POST body;
    • a DELETE with an empty params array sending [];
    • a multipart request with flattened nested fields, true as 1 and null as an empty field;
    • Accept: */* (curl's default) left untouched;
    • the bearer token;
    • repeated-header handling;
    • streamed chunks.
  • The E2E suite (82 call() sites, including multipart responses and log streaming) runs in CI.

utopia-php/fetch is archived and was only kept as a dev dependency for this
client, which Edge also reuses for its executor E2E suite. The client keeps
its public surface (call(), setKey() and the METHOD_* constants) and fetch's
request semantics: no Accept header added, http_build_query encoding for GET
parameters, JSON or form bodies by content type, up to 5 redirects followed,
a 5s connect timeout, lowercased response headers with the last value of a
repeated header winning.
Two scenarios post their params as multipart/form-data. fetch handed the
flattened params to curl, which built the form and added the boundary to
the content type; the client now builds the same form with the psr7
factory and keeps its boundary-carrying content type.
@ChiragAgg5k
ChiragAgg5k merged commit 0c46220 into main Oct 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants