You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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).
/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.
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.
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.
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.
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-themeflag at 16% on main).functions.phpis 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 thewordpress-themeflag 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/translateendpoint 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
CommunityHandlerTestBasewas 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 usesCDCF_DISPOSABLE_DOMAINS_FILE; just needs branch tests for thefile_existsguard + the domain lookupcdcf_check_ip_rbl— DNS-based IP reputation check; needsgethostbyname/dns_get_recordmocksTier 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. Needswp_remote_postmocking + transient/permanent failure scenarios.cdcf_process_translation— orchestrates the chunked translation of a single post (callscdcf_chunk_html_contentandcdcf_openai_translatefor 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 rendererscdcf_render_referral_submitter_meta_box,cdcf_render_pending_local_groups_widget,cdcf_render_project_submitter_meta_box— meta box renderersThese 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)
includes/handlers/<slug>.php(orincludes/admin/<slug>.phpfor admin-only hooks); add arequire_oncefromfunctions.phpand switch the registration to a named callback.tests/bootstrap.phpto require the new file.function_existsoverride (stubCommonFunctions()thenallowAllFunctionsToExist()helpers in each test class). The FunctionStub constructor short-circuits iffunction_exists()says the target already exists, leaving the symbol undefined at call time.function_exists('cdcf_enqueue_translation')returning false), use#[RunInSeparateProcess]+#[PreserveGlobalState(false)]— seeTeamMemberHandlerTest::test_falls_back_to_wp_cron_when_enqueue_helper_missingand the matching test inTranslateHandlerTest.WP_Error,WP_REST_Request,WP_REST_Response,WP_Query) live intests/bootstrap.php. Add new shims there as needed.patchwork.json'sredefinable-internals(see howfile_put_contents+renamewere added in tests(theme): cover /update-disposable-domains + fix latent fsync warning #104).Coverage target
Each Tier 1 endpoint pair should move the
wordpress-themeflag 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