Cover the untested core: issue TOC, status API, publication validation, and the API handler - #166
Merged
Conversation
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.
Three commits that were pushed straight to
mainand one new one, brought togetheras a reviewable change.
mainis being reset to the merge of #165 so all of it landshere 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)
IssueTOCUnitTestfor the setting and opt-in gates, andissue-toc-badge.cy.jsfor 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.jsfor 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.
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.
produces (
CODECHECK-2025-001), which hid that every badge linked tohref="".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.jsdriving the endpoint OJS publishes with — includingone 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, andserving ends in
exit, so nothing could build one without it answering a requestand killing the process. The request cycle is now
execute(), and responses gothrough a
JsonResponseEmitterinstead of a static call that echoes and exits.emit()is declarednever, because every endpoint body is written assuming thatresponding 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 aPKPHandlerand this is not one — the call was unreachableonly because the constructor exited first. Serving from
execute()made it live, itraised 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