Skip to content

Cover the untested core: issue TOC, status API, publication validation, and the API handler - #166

Merged
nuest merged 3 commits into
codecheckers:mainfrom
nuest:refactor/api-handler-testability
Aug 26, 2026
Merged

Cover the untested core: issue TOC, status API, publication validation, and the API handler#166
nuest merged 3 commits into
codecheckers:mainfrom
nuest:refactor/api-handler-testability

Conversation

@nuest

@nuest nuest commented Aug 26, 2026

Copy link
Copy Markdown
Member

Three commits that were pushed straight to main and one new one, brought together
as a reviewable change. main is being reset to the merge of #165 so all of it lands
here instead.

What this covers

Four parts of the plugin had no test at all. Writing the tests turned up three
production bugs, two of them silent.

Issue TOC badge and the status API (8ff1fd1)

  • IssueTOCUnitTest for the setting and opt-in gates, and issue-toc-badge.cy.js
    for what the badge actually renders — image variants, height, the text-only form
    with its configured wording and colour, and where it links. Each variant is also
    captured to a screenshot, so the settings can be looked at rather than inferred.
  • status-handler.cy.js for the status API end to end: pending until recorded,
    newest record wins, append-only history newest first, rejected payloads, and the
    automatic update that stops deciding once a person has.
  • New setting: the badge can link either to the certificate's page in the
    register or to its DOI, for both the issue TOC and the article page. Whichever
    the journal did not pick stands in when the preferred one is missing.
  • Bug found: an existing test pinned a certificate format the plugin never
    produces (CODECHECK-2025-001), which hid that every badge linked to href="".

Publication validation (f400f4d)

Bug found: the CODECHECK gate on publishing had never worked. The validator
asked the router's handler for the authorized submission, but publishing goes
through the REST API, where there is no handler. Every publish attempt threw
inside the hook, PKP logged "failed to handle the hook" and published anyway — so
the status allow-list, the YAML check and the extended repository check were all
inert. The submission now comes from the hook arguments.

Covered by unit tests for the opt-in gate and the no-handler case, plus
publication-validation.cy.js driving the endpoint OJS publishes with — including
one test that unpublishes a ready article, watches CODECHECK refuse it, then
accepts the status and publishes it for real.

API handler testability (65f45d9)

CodecheckApiHandler's constructor resolved the route, authorized and served, and
serving ends in exit, so nothing could build one without it answering a request
and killing the process. The request cycle is now execute(), and responses go
through a JsonResponseEmitter instead of a static call that echoes and exits.
emit() is declared never, because every endpoint body is written assuming that
responding ends the request; the test emitter throws where production exits.

That makes the plugin's only access control testable — it sits outside PKP's
authorization policies and checks the CSRF token and roles itself, in front of
nineteen endpoints, several of which write to the public register. The token is now
checked before the route is resolved, so an unauthorized caller cannot probe for
routes.

Bug found: setupAPIHandler() called $router->setHandler($apiHandler).
setHandler() takes a PKPHandler and this is not one — the call was unreachable
only because the constructor exited first. Serving from execute() made it live, it
raised a TypeError, PKP swallowed it, and OJS answered every plugin API call with
its own 404. Caught by the e2e suite, not by PHPUnit.

Also: a POST to reserve an identifier or update the register issue that omits a
required field now answers 400 naming the field, instead of raising "Undefined array
key" on its way to a 500.

Tests

PHPUnit 139 → 201, Cypress component 61 (unchanged), e2e 19 across 5 specs → 40
across 9. All green locally against OJS 3.5.0-5.

🤖 Generated with Claude Code

https://claude.ai/code/session_017ashvoUDYNjMq8FweMJTzn

@nuest
nuest merged commit 6344b11 into codecheckers:main Aug 26, 2026
3 checks passed
@nuest
nuest deleted the refactor/api-handler-testability branch August 26, 2026 19:35
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.

1 participant