Skip to content

tests(theme): extend PHPUnit coverage to the remaining functions.php endpoints + helpers #107

Description

@JohnRDOrazio

Background

Closes the natural follow-up to #100. After that issue landed, every REST endpoint explicitly listed in #100's body was extracted to includes/handlers/ and covered (theme suite at 116 tests / 269 assertions, wordpress-theme flag at 16% on main).

functions.php is still ~3700 lines, and the bulk of what remains is REST endpoints, admin pages, and translation-pipeline helpers that weren't in #100's explicit scope. Each chunk extracted follows the same recipe and ticks the wordpress-theme flag up a couple of percentage points.

Suggested ordering (by value × ease)

Tier 1 — REST endpoints worth extracting next

These follow the same shape as the handlers already covered. Each should be a small PR with a refactor commit (move closure / function body into includes/handlers/<slug>.php) + a test class.

  • /refer-local-group + /refer-local-group/send-code — public submission flow with email verification code (~250 lines). Security-sensitive: spam scoring, IP RBL, disposable-email check, verification code lifecycle.
  • /refer-community-project + /refer-community-project/send-code — sibling pair to the above (~150 lines).
  • /submit-project + /submit-project/send-code — another sibling pair (~200 lines).
  • /deploy-translation — already sitting next to the /translate endpoint extracted in tests(theme): cover /translate enqueue handler (refs #100) #105; was deliberately deferred there.
  • /link-translations — Polylang linking helper (~40 lines).
  • /project-status — workflow status setter (~55 lines).
  • /flush-opcache — small admin utility (~10 lines).

The three "refer/submit" endpoint pairs share the verification-code + spam-check skeleton, so a shared abstract base class (the way CommunityHandlerTestBase was used for the trio in #103) probably makes sense once two of them land.

Tier 2 — Standalone security / sanitization helpers

These are pure-input/pure-output and easy to test directly without WP coupling.

  • cdcf_is_spam_content — text spam scorer (URL count, link-to-text ratio, keyword density)
  • cdcf_is_disposable_email — already uses CDCF_DISPOSABLE_DOMAINS_FILE; just needs branch tests for the file_exists guard + the domain lookup
  • cdcf_check_ip_rbl — DNS-based IP reputation check; needs gethostbyname / dns_get_record mocks

Tier 3 — Translation pipeline (the OpenAI part)

Higher value, more complex. These are the functions that actually call OpenAI from the queue worker — invisible to the REST layer covered by #105.

  • cdcf_openai_translate — the OpenAI HTTP call with bounded retries + exponential backoff. Real risk if it breaks. Needs wp_remote_post mocking + transient/permanent failure scenarios.
  • cdcf_process_translation — orchestrates the chunked translation of a single post (calls cdcf_chunk_html_content and cdcf_openai_translate for each chunk).
  • cdcf_chunk_html_content — splits long HTML into LLM-safe chunks at safe boundaries. Pure function; very testable.

Tier 4 — Skip (low value)

Mostly UI markup with little branching. Testing them would assert that strings are concatenated, which doesn't prevent regressions.

  • cdcf_ai_translate_settings_page, cdcf_ai_translate_meta_box, cdcf_bulk_translate_page, cdcf_api_docs_page — admin page renderers
  • cdcf_render_referral_submitter_meta_box, cdcf_render_pending_local_groups_widget, cdcf_render_project_submitter_meta_box — meta box renderers

These can be tested via UI smoke tests later if/when an E2E harness lands; PHPUnit isn't the right tool.

Conventions established in #100 (reuse these)

  • Extract handler bodies into includes/handlers/<slug>.php (or includes/admin/<slug>.php for admin-only hooks); add a require_once from functions.php and switch the registration to a named callback.
  • Update tests/bootstrap.php to require the new file.
  • Brain Monkey ordering: stub every WP function you need to redefine BEFORE the wholesale function_exists override (stubCommonFunctions() then allowAllFunctionsToExist() helpers in each test class). The FunctionStub constructor short-circuits if function_exists() says the target already exists, leaving the symbol undefined at call time.
  • For the wp-cron fallback branch (function_exists('cdcf_enqueue_translation') returning false), use #[RunInSeparateProcess] + #[PreserveGlobalState(false)] — see TeamMemberHandlerTest::test_falls_back_to_wp_cron_when_enqueue_helper_missing and the matching test in TranslateHandlerTest.
  • Shims for WP classes (WP_Error, WP_REST_Request, WP_REST_Response, WP_Query) live in tests/bootstrap.php. Add new shims there as needed.
  • For filesystem-touching handlers, add the relevant PHP internals to patchwork.json's redefinable-internals (see how file_put_contents + rename were added in tests(theme): cover /update-disposable-domains + fix latent fsync warning #104).

Coverage target

Each Tier 1 endpoint pair should move the wordpress-theme flag by ~1-2 percentage points. Completing Tier 1 + Tier 3 would land the theme flag around 30-35%, which is a reasonable next milestone before a deeper push.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions