Skip to content

Strengthen WLED request payload tests#2050

Open
mik-laj wants to merge 5 commits intofrenck:mainfrom
mik-laj:fix/wled-request-payload-tests
Open

Strengthen WLED request payload tests#2050
mik-laj wants to merge 5 commits intofrenck:mainfrom
mik-laj:fix/wled-request-payload-tests

Conversation

@mik-laj
Copy link
Copy Markdown
Collaborator

@mik-laj mik-laj commented Apr 30, 2026

Proposed Changes

These tests originally only verified that the request succeeded and returned the expected response, but they did not verify what was actually sent to WLED. That left room for regressions where the client could send the wrong payload, omit required fields, or serialize data incorrectly while the tests still passed. Stronger assertions make the tests check the request contract itself, so they catch breaking changes in the outgoing payload, not just in the response handling.

Additionally, the test code was refactored to make fuller use of pytest fixtures and helper functions (like prepare_wled_with_device), which significantly reduces indentation and improves readability. The tests are now easier to maintain and follow, with less boilerplate setup code.

This is also the first step toward a refactor that uses models.State to build the payloads sent to WLED. models.State is already used for deserialization today, but it can also be used for serialization. That would remove a lot of magic field names like cct, sel, sx, and similar, making the request-building code easier to maintain and less error-prone.

Related Issues

(GitHub link to related issues or pull requests)

Summary by CodeRabbit

  • Tests
    • Enhanced validation of outgoing API request payloads to assert exact structure and required flags.
    • Refactored tests to use centralized, reusable test setup helpers for device and upgrade scenarios.
    • Converted key fixtures to async patterns to improve test reliability and teardown.

Copilot AI review requested due to automatic review settings April 30, 2026 02:01
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

Warning

Rate limit exceeded

@mik-laj has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 30 minutes and 58 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 86fd42f3-cd69-467b-b202-b888b0be21f1

📥 Commits

Reviewing files that changed from the base of the PR and between cf42b5c and eafcef7.

📒 Files selected for processing (1)
  • tests/test_wled.py
📝 Walkthrough

Walkthrough

Adds a new test helper assert_post_payload() and refactors many WLED tests to use shared fixtures and helpers; centralizes JSON/presets mocking and converts session and wled fixtures to async, while asserting outgoing /json/state POST payloads include "v": True plus command-specific fields.

Changes

Cohort / File(s) Summary
Test helper & assertions
tests/test_wled.py
Adds assert_post_payload(mocked, path, expected) that normalizes POST URLs with yarl.URL, decodes request bodies with orjson, and asserts JSON payload equality. Refactors many tests to use this helper and to assert /json/state includes "v": True alongside command fields.
Fixtures & session setup
tests/conftest.py
mock_json_and_presets now accepts optional wled_data and presets_data arguments. session and wled fixtures converted to async pytest_asyncio fixtures; wled teardown now calls await wled_instance.close().
Test files (refactors)
tests/.../test_master*, tests/.../test_segment*, tests/.../test_preset*, tests/.../test_playlist*, tests/.../test_transition*, tests/.../test_live*, tests/.../test_sync*, tests/.../test_nightlight*, tests/.../test_state*
Numerous tests updated to use aioresponses and shared wled fixtures (via prepare_wled_with_device() / prepare_wled_for_upgrade() helpers), removing per-test aioresponses() contexts and manual aiohttp.ClientSession() usage. Tests now validate exact /json/state outgoing JSON payload shapes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped through mocks and fixtures bright,

With v: true I guard the POST at night.
Helpers tidy, payloads aligned—
Tests now sing, all bugs confined. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Strengthen WLED request payload tests' accurately describes the main objective of the PR: adding stronger payload assertions and validation to WLED request tests.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 30 minutes and 58 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.20%. Comparing base (3e87d76) to head (eafcef7).
⚠️ Report is 597 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2050       +/-   ##
===========================================
+ Coverage   58.61%   97.20%   +38.59%     
===========================================
  Files           6        8        +2     
  Lines         662     1075      +413     
  Branches      143      112       -31     
===========================================
+ Hits          388     1045      +657     
+ Misses        270       20      -250     
- Partials        4       10        +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/test_wled.py (1)

33-44: ⚡ Quick win

Scope this helper to payload semantics, not transport defaults.

assert_post_payload() also locks header values and allow_redirects, which can cause unrelated failures when HTTP defaults evolve. Since this PR is about payload regression checks, keep this helper focused on URL/method/body and validate transport defaults in dedicated request tests.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_wled.py` around lines 33 - 44, The helper assert_post_payload
currently asserts transport details (headers and allow_redirects) which couples
payload tests to HTTP defaults; update assert_post_payload(mocked, path,
expected) to only assert the URL, method ("POST") and serialized body
(orjson.dumps(expected)) on the mocked call and remove the headers and
allow_redirects checks, so payload semantics remain scoped to URL/method/body;
keep transport/header assertions to separate, dedicated request-level tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/test_wled.py`:
- Around line 33-44: The helper assert_post_payload currently asserts transport
details (headers and allow_redirects) which couples payload tests to HTTP
defaults; update assert_post_payload(mocked, path, expected) to only assert the
URL, method ("POST") and serialized body (orjson.dumps(expected)) on the mocked
call and remove the headers and allow_redirects checks, so payload semantics
remain scoped to URL/method/body; keep transport/header assertions to separate,
dedicated request-level tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f3e669d-3bfc-4554-b6a8-cad592235b59

📥 Commits

Reviewing files that changed from the base of the PR and between ea7e0e2 and f7487dd.

📒 Files selected for processing (1)
  • tests/test_wled.py

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR strengthens the WLED client request tests by asserting the actual serialized POST payloads sent to /json/state, reducing the chance of regressions that still return “valid” responses but send incorrect data.

Changes:

  • Added a shared assert_post_payload helper for POST request assertions.
  • Updated request-focused tests (master/segment/preset/playlist/transition/live/sync/nightlight) to verify the exact outgoing request payload.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/test_wled.py Outdated
Comment thread tests/test_wled.py Outdated
Comment thread tests/test_wled.py Outdated
Comment on lines +918 to +920
assert_post_payload(
mocked, "http://example.com/json/state", {"ps": 2, "v": True}
)
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

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

The playlist tests assert the outgoing payload uses {"ps": ...}. Elsewhere in the codebase the playlist field is consistently aliased as pl (e.g., State.playlist_id uses alias "pl" while presets use "ps"), so these assertions may be locking in an incorrect request contract. Please double-check the correct WLED API field for activating a playlist and update the expected payloads (and client code if needed) to match.

Copilot uses AI. Check for mistakes.
Comment thread tests/test_wled.py Outdated
Comment on lines +935 to +937
assert_post_payload(
mocked, "http://example.com/json/state", {"ps": 2, "v": True}
)
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

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

The playlist tests assert the outgoing payload uses {"ps": ...}. Elsewhere in the codebase the playlist field is consistently aliased as pl (e.g., State.playlist_id uses alias "pl" while presets use "ps"), so these assertions may be locking in an incorrect request contract. Please double-check the correct WLED API field for activating a playlist and update the expected payloads (and client code if needed) to match.

Copilot uses AI. Check for mistakes.
Comment thread tests/test_wled.py Outdated
Comment on lines +954 to +956
assert_post_payload(
mocked, "http://example.com/json/state", {"ps": 2, "v": True}
)
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

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

The playlist tests assert the outgoing payload uses {"ps": ...}. Elsewhere in the codebase the playlist field is consistently aliased as pl (e.g., State.playlist_id uses alias "pl" while presets use "ps"), so these assertions may be locking in an incorrect request contract. Please double-check the correct WLED API field for activating a playlist and update the expected payloads (and client code if needed) to match.

Copilot uses AI. Check for mistakes.
@mik-laj mik-laj requested a review from joostlek April 30, 2026 02:19
@mik-laj mik-laj marked this pull request as draft April 30, 2026 02:42
@mik-laj mik-laj marked this pull request as ready for review April 30, 2026 21:43
@mik-laj mik-laj force-pushed the fix/wled-request-payload-tests branch from cf42b5c to 5bd612b Compare April 30, 2026 21:48
@mik-laj mik-laj added the maintenance Generic maintenance tasks. label Apr 30, 2026
@mik-laj mik-laj requested a review from Copilot May 1, 2026 16:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/test_wled.py Outdated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance Generic maintenance tasks.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants