Repository navigation
feat: add the client contract, fixtures and contract scenarios - #3
Merged
Merged
Conversation
Every client must give the same results and errors for the same responses of the gateway. client.md fixes them, with the map from each status to one error code that ERR-1 asks for. The calls of 2 Oct 2026 showed facts that the first interface missed: lookup has a status, suggestions have no label, an empty autocomplete query gets no answer, and a 429 carries no Retry-After. The spec moves to 0.2.0, because it adds the contract. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
A review found three gaps that would let the clients differ: an unknown lookup status became null, no rule covered a bad level, coordinate or distance, and the contract did not say that a client ignores unknown fields in a response. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
NIPOST's OpenAPI file gives no error responses, no nearby body and no rate-limit headers. The completed file adds them, and marks each response as observed, documented or assumed, so a reader knows what a call has shown. The checks reject a path that NIPOST does not document and a response with no mark. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
The mock server needs one body for each response that a client must handle, and NIPOST's terms allow only synthetic values. Every postcode here has the district Z99 and the area ZZ, and a test fails on any other full postcode. A test also checks each body against its schema in the OpenAPI file, so the two cannot drift apart without a red build. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
Every client must pass the same scenarios against the mock server. Each scenario names the calls, the responses and the outcome, with the attempts and the waits, so a TypeScript and a PHP client that pass them behave the same. The scenarios also cover the input rules, the plain form of a number, unknown fields and an unknown lookup status. A check fails when a scenario names a missing fixture or an error code that client.md does not list, and when an error code or a required rule has no scenario. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
A review found that the contract left room for clients to differ. The unknown-fields rule was too wide, the form of a number in a query was not fixed, and the contract gave no rule for a reply with a broken part, for a Retry-After on a 5xx reply, for a total deadline, for a shared request that one caller cancels, or for the wait of autocomplete. Each rule now says what a client does, and the tests check that meaning. A reply with a broken part gets the new error code unexpected_response, so that no client returns a guessed value. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
Each rule that a scenario can test now has one: the total deadline, a Retry-After on a 503, an invalid Retry-After, two spellings of one postcode, a whole number in a query, and the four replies with a missing or broken part. A test checks that every scenario that client.md names exists, and the required list covers the new ones. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
One mark on a shared response claimed more than the calls showed. The calls without a key reached lookup and autocomplete only, a 403 came back from lookup only, and no call sent an unknown key. Each operation now has its own mark for each status, and each error code has its own mark, so a reader can tell the observed code from the assumed ones. A check fails when a code claims more than its response, and when an error response or a header has no mark. The file now also describes the 5xx replies and the answer to an unknown path, both assumed, so that every reply the mock server can send has a mark. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
A fixture with a wrong status or a wrong error code passed the checks, and the mock server would then send a wrong reply. Each fixture must now have a status that a response with its schema declares, an error code of that response, and the code that its file name states. Its evidence can claim no more than the mark of that response or code, so the key that the gateway does not know and the origin error are now assumed. The scan for real postcodes now also reads the docs beside the fixtures and the scenarios, accepts only the state FC, and knows more separators. A new scan fails on text in the form of a real key. Two error messages now use Gatepost's own words. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
The checks let a deleted scenario or a false outcome pass. client.md now names the scenarios of each rule, and its error table names them for each row. The check fails when a named scenario has no file, when a scenario has no rule, and when a scenario of a row ends with another error code. With one call, the reply to the last attempt must give the outcome: the error with its status, API code and Retry-After, or the result with its level, validity and unit. A fixture of another method and too many attempts fail too. New scenarios cover the rules that had none: levels 4 and 5, a lower level, the default level, the limits of the radius, text over 11 characters, the limits of Retry-After, a shared error, the echoed postcode, and a reverse postcode that does not parse. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
The check of a scenario compared only the last outcome, so a scenario could keep a wrong count of attempts, a wrong wait, a wrong query or an error for a good reply. The check now plays the calls as client.md says: the retries and their waits, the deadline, shared requests, kept results and the limit of four requests in flight. It compares the attempts, the waits, the first request and each outcome with the scenario, and a good reply must give a result. The play lives in its own module, so the file of format checks stays short. Each rule of client.md now names its scenario or is left to each client, and a body above lookup level 1 cannot claim to be observed. A new scenario covers a reply with no data field. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
The truth check compared the code and the label of a suggestion, and not its postcode. A scenario with a wrong postcode passed, and every correct client then failed it. The check now builds the postcode from the typed segments before the active one, plus the code, and a test plants the fault. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
The deadline scenario now uses a 2 s attempt and a 7 s wait, so a slow runner cannot make it flaky while it still tests the deadline and not the 10 s limit. Five reverse and autocomplete fields get an evidence mark. Two sentences now credit NIPOST's OpenAPI file for the radius clamp, because no call of ours tested it. The contract names the null cases of radiusM, area and district, lists the negative zero and the wait between attempts as rules that no scenario tests, and gives the radius rule of the reverse fixture. The TypeScript standard says that the mock server is outside CS-2. A test uses a postcode that cannot be real. Signed-off-by: MobileMage <aidelojejoshua@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec 0.2.0 adds what an API client needs besides the grammar. client.md
is the contract that every Gatepost client follows: the calls, the
results, the error codes and the map from each HTTP status to one of
them, retries, the queue, the cache and the input rules. The completed
OpenAPI file describes the NIPOST gateway, and each response carries its
evidence: observed in our own calls, documented by NIPOST, or assumed.
The fixtures and mock keys are synthetic and hold no real postcode or
key. The contract scenarios script each case that a client must pass,
and the mock server plays them by their X-Scenario-Id header. Checks tie
each scenario to its rule in client.md and to the responses of the
OpenAPI file, so a deleted or false scenario fails.
This change is larger than the 400 lines that GIT-5 suggests, because
most of it is fixtures and scenarios, which are data.
Signed-off-by: MobileMage aidelojejoshua@gmail.com