Skip to content

1187 content planner add missing unit tests for components#23209

Open
vraja-pro wants to merge 18 commits intotrunkfrom
1187-content-planner-add-missing-unit-tests-for-components
Open

1187 content planner add missing unit tests for components#23209
vraja-pro wants to merge 18 commits intotrunkfrom
1187-content-planner-add-missing-unit-tests-for-components

Conversation

@vraja-pro
Copy link
Copy Markdown
Contributor

@vraja-pro vraja-pro commented Apr 29, 2026

Context

Adds the missing unit tests for the AI content planner UI components. All components under `src/ai-content-planner/components/` except the top-level Redux orchestration entry point (`app.js`) now have dedicated test files achieving 100% branch coverage.

Summary

This PR can be summarized in the following changelog entry:

  • Adds unit tests for AI content planner UI components.

Relevant technical choices:

  • Removed dead default parameters from private components. Istanbul Classic (the Babel-transform coverage tool used by Jest) tracks each default parameter value as a separate branch. CategoryBadge and MetaDescriptionProgressBar are unexported, module-private components whose callers always pass explicit prop values, so the "use default" branches were structurally unreachable. Rather than adding artificial tests that pass undefined to trigger defaults, the defaults were removed from those private components so Istanbul no longer generates unreachable branches for them.

  • Wrapped SuggestionsModalContent in Modal.Panel in tests. headlessui's <Modal> emits a FocusTrap warning when no focusable element exists inside it. The original test helpers wrapped the component in a bare <div>, which contains no focusable children. Switching to <Modal.Panel closeButtonScreenReaderText="Close"> adds the close button that headlessui expects, silencing the warning without needing to suppress console.warn.

  • handlePanelMeasureChange exercised by capturing the useMeasuredRef callback. JSDOM does not implement ResizeObserver, so the resize callback wired up inside useMeasuredRef can never fire through a real DOM resize. The test imports the useMeasuredRef mock, uses mockImplementationOnce to capture the callback before render, then calls it inside act() after render. This avoids an infinite re-render loop that would occur if the callback were called synchronously inside the mock (calling it mid-render triggers setPanelHeight, which schedules another render, which calls the mock again, and so on).

  • app.js excluded from the coverage target. app.js is a top-level Redux container orchestration file that wires withSelect``withDispatch HOCs together. Exercising it at the unit level would require mounting a full Redux store with all slices configured, which is integration-test territory. It is intentionally excluded from the --collectCoverageFrom glob used for this PR's coverage check.

  • setupMocks() must be called before overriding individual hook mocks. In feature-modal.test.js, setupMocks() calls useFetchContentOutline.mockReturnValue(jest.fn()), which resets any prior mock. Tests that need a specific return value must call setupMocks() first and then apply their override — calling the override first and setupMocks() second silently discards it. Since beforeEach already calls setupMocks(), per-test overrides are applied in the test body after the hook has run.

Test instructions

Test instructions for the acceptance test before the PR gets merged

This PR can be acceptance tested by following these steps:

  • Smoke test the content planner feature.

For devs:

  • Check the branch coverage for all components except app.js are 100% when executing:
cd packages/js && yarn jest tests/ai-content-planner --coverage --collectCoverageFrom="src/ai-content-planner/components/**/*.js"

Relevant test scenarios

  • Changes should be tested with the browser console open
  • Changes should be tested on different posts/pages/taxonomies/custom post types/custom taxonomies
  • Changes should be tested on different editors (Default Block/Gutenberg/Classic/Elementor/other)
  • Changes should be tested on different browsers
  • Changes should be tested on multisite

Test instructions for QA when the code is in the RC

Not applicable — this PR only adds unit tests and removes dead default parameters from unexported, module-private components. There is no user-visible behaviour change.

Impact check

This PR only affects `packages/js/tests/ai-content-planner/` (new and updated test files) and two private helper components inside `packages/js/src/ai-content-planner/components/` (`CategoryBadge` and `MetaDescriptionProgressBar`). No user-facing code paths are changed.

Other environments

  • This PR also affects Shopify. I have added a changelog entry starting with `[shopify-seo]`, added test instructions for Shopify and attached the `Shopify` label to this PR.
  • This PR also affects Yoast SEO for Google Docs. I have added a changelog entry starting with `[yoast-doc-extension]`, added test instructions for Yoast SEO for Google Docs and attached the `Google Docs Add-on` label to this PR.

Documentation

  • I have written documentation for this change. For example, comments in the Relevant technical choices, comments in the code, documentation on Confluence / shared Google Drive / Yoast developer portal, or other.

Quality assurance

  • I have tested this code to the best of my abilities.
  • During testing, I had activated all plugins that Yoast SEO provides integrations for.
  • I have added unit tests to verify the code works as intended.
  • If any part of the code is behind a feature flag, my test instructions also cover cases where the feature flag is switched off.
  • I have written this PR in accordance with my team's definition of done.
  • I have checked that the base branch is correctly set.
  • I have run `grunt build:images` and committed the results, if my PR introduces or edits images or SVGs.

Innovation

  • No innovation project is applicable for this PR.
  • This PR falls under an innovation project. I have attached the `innovation` label.
  • I have added my hours to the WBSO document.

Fixes https://github.com/Yoast/reserved-tasks/issues/1187

vraja-pro and others added 4 commits April 29, 2026 12:26
…components

CategoryBadge (category-section.js) and MetaDescriptionProgressBar (outline-modal-content.js) are private components always called with explicit props by their parent. The default values for isEnabled, isLoading, date, locale, and isCornerstone were never reached, causing to flag them as uncovered branches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…components

Adds test files for CategorySection, ContentPlannerEditorItem, ContentSuggestionBlock, InlineBanner, StructureRow, and SuggestionButton, bringing each to 100% statement, branch, function, and line coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t, OutlineModalContent, and FeatureModal

SuggestionsModalContent: wrap renders in Modal.Panel to resolve the FocusTrap console warning, add loading text rotation test.

OutlineModalContent: cover closeButtonRef focus effect, focus keyphrase and title onChange callbacks, and the fallback category branch when the category toggle is switched off before applying.

FeatureModal: cover handleSuggestionClick, handlePanelMeasureChange (via captured useMeasuredRef callback), and the SparksLimitNotification render condition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vraja-pro vraja-pro added the changelog: non-user-facing Needs to be included in the 'Non-userfacing' category in the changelog label Apr 29, 2026
vraja-pro and others added 5 commits April 29, 2026 14:57
- Drop `=false` from the `isCornerstone` JSDoc in MetaDescriptionProgressBar
  to match the already-removed default parameter (JSDoc/code were inconsistent).
- Remove redundant `setupMocks()` call from the `handlePanelMeasureChange` test
  in feature-modal.test.js; `beforeEach` already calls it, so the per-test call
  was noise. Added a comment clarifying why `mockImplementationOnce` is placed
  after the `beforeEach` hook.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vraja-pro vraja-pro force-pushed the 1187-content-planner-add-missing-unit-tests-for-components branch from 45aa93c to eca6840 Compare April 29, 2026 13:05
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 29, 2026

Coverage Report for CI Build 61

Coverage increased (+0.07%) to 53.701%

Details

  • Coverage increased (+0.07%) from the base build.
  • Patch coverage: 2 of 2 lines across 2 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 66182
Covered Lines: 35377
Line Coverage: 53.45%
Relevant Branches: 16995
Covered Branches: 9290
Branch Coverage: 54.66%
Branches in Coverage %: Yes
Coverage Strength: 45452.18 hits per line

💛 - Coveralls

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

A merge conflict has been detected for the proposed code changes in this PR. Please resolve the conflict by either rebasing the PR or merging in changes from the base branch.

vraja-pro added 2 commits May 4, 2026 11:31
…ner and content-planner-editor-item

- Add isPremium=true prop verification to with-inline-banner
- Add stylesheet injection effect tests (style already present, main link absent, happy-path iframe injection) using a getter-only ref mock to  prevent React from overwriting the mock ownerDocument before effects run
- Fix missing INJECTED_STYLE_ID in the constants mock (was undefined)
- Add minPostsMet=false branch tests to content-planner-editor-item covering disabled button, aria-describedby, helper text rendering, and  its conditional flex class for sidebar vs metabox locations
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

A merge conflict has been detected for the proposed code changes in this PR. Please resolve the conflict by either rebasing the PR or merging in changes from the base branch.

Copy link
Copy Markdown
Contributor

@JorPV JorPV left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CR 🚧

And maybe pull the latest trunk into your branch.

Comment thread packages/js/tests/ai-content-planner/components/category-section.test.js Outdated
Comment thread packages/js/tests/ai-content-planner/components/outline-modal-content.test.js Outdated
- Restore `date = ""` default on `MetaDescriptionProgressBar` to prevent a TypeError in `countMetaDescriptionLength` when no date prop is passed (`undefined !== ""` is true, causing `date.length` to throw).
  - Replace CSS class selector in category-section test with a text query
    so the test is not coupled to Tailwind utility class names.
  - Replace plain focus mock in outline-modal-content test with a real DOM element and `jest.spyOn`, so the assertion targets the actual element rather than an arbitrary mock object.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog: non-user-facing Needs to be included in the 'Non-userfacing' category in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants