Skip to content

fix: adjust payload to customized managed sponsor forms#958

Open
tomrndom wants to merge 3 commits into
masterfrom
fix/customize-sponsor-form-images
Open

fix: adjust payload to customized managed sponsor forms#958
tomrndom wants to merge 3 commits into
masterfrom
fix/customize-sponsor-form-images

Conversation

@tomrndom
Copy link
Copy Markdown

@tomrndom tomrndom commented May 27, 2026

ref: https://app.clickup.com/t/86b66n5jn

Signed-off-by: Tomás Castillo tcastilloboireau@gmail.com

Summary by CodeRabbit

  • Bug Fixes
    • Corrected sponsor customized form data handling so image file paths are normalized and missing items/images default to empty lists, improving image display and robustness.
  • Tests
    • Added tests covering image path mapping, empty/missing items or images, and reset behavior to prevent regressions.

Review Change Stack

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

📝 Walkthrough

Walkthrough

The sponsor customized form reducer now initializes items to [] and, on RECEIVE_SPONSOR_CUSTOMIZED_FORM, constructs a new entity whose items list is normalized; each image object receives file_path copied from its file_url. The items-list reducer and tests were updated to match.

Changes

Sponsor Customized Form Normalization

Layer / File(s) Summary
Default entity shape
src/reducers/sponsors/sponsor-customized-form-reducer.js
DEFAULT_ENTITY now includes items: [] to ensure a consistent entity shape.
RECEIVE payload normalization
src/reducers/sponsors/sponsor-customized-form-reducer.js
On RECEIVE_SPONSOR_CUSTOMIZED_FORM, reducer builds a new entity from payload.response, uses `payload.response.items
Item images normalization (items-list reducer)
src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js
When handling RECEIVE_SPONSOR_CUSTOMIZED_FORM_ITEM, currentItem.images is normalized with file_path derived from file_url, defaulting to [] if missing.
Tests for mapping and reset
src/reducers/sponsors/__tests__/sponsor-customized-form-reducer.test.js
Adds tests verifying file_urlfile_path mapping for item images, handling of empty/missing items and images, and that RESET returns DEFAULT_STATE.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • smarcet

Poem

🐰 A payload hopped in with URLs bright,
I nudged each image to set paths right.
Items found their empty nest,
File paths set—now all is dressed. 📸

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: adjust payload to customized managed sponsor forms' accurately summarizes the main changes: payload normalization for image file paths in sponsor form reducers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/customize-sponsor-form-images

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

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/reducers/sponsors/sponsor-customized-form-reducer.js`:
- Around line 46-52: The current construction of entity spreads payload.response
and maps payload.response.items and it.images directly, which will throw if
items or images are null/undefined; update the logic in the entity creation (the
block that builds entity from payload.response and uses
payload.response.items.map and it.images.map) to use defensive checks/optional
chaining and defaults (e.g., treat payload.response.items as an empty array and
each it.images as an empty array before mapping) so mapping never runs on
null/undefined and preserves existing behavior for present arrays.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8e2f79e4-8787-4990-841c-cafb425e32d2

📥 Commits

Reviewing files that changed from the base of the PR and between a1178de and 7ac284b.

📒 Files selected for processing (1)
  • src/reducers/sponsors/sponsor-customized-form-reducer.js

Comment thread src/reducers/sponsors/sponsor-customized-form-reducer.js
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@tomrndom tomrndom requested a review from smarcet May 27, 2026 01:54
return {
...state,
entity: payload.response
const entity = {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@tomrndom
The fix addresses the bug for one data path (entity-level items from getSponsorManagedForm) but leaves the same bug active on the individual-item edit path (currentItem from getSponsorCustomizedFormItem), meaning images will still be silently dropped in the most common editing scenario. The missing regression test also means the fix is unverified.

entity: payload.response
const entity = {
...payload.response,
items: (payload.response.items || []).map((it) => ({
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@tomrndom
Add a unit test for RECEIVE_SPONSOR_CUSTOMIZED_FORM in sponsor-customized-form-reducer.js covering: items with images (file_path mapped), items with no images, and empty items array

@@ -43,10 +43,17 @@ const sponsorCustomizedFormReducer = (state = DEFAULT_STATE, action) => {
return DEFAULT_STATE;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@tomrndom
DEFAULT_ENTITY missing items field
fix: Add items: [] to DEFAULT_ENTITY

Copy link
Copy Markdown

@smarcet smarcet left a comment

Choose a reason for hiding this comment

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

@tomrndom
Incomplete fix ( same image-drop bug on the individual-item edit path)
The primary edit flow for items goes through getSponsorCustomizedFormItem → RECEIVE_SPONSOR_CUSTOMIZED_FORM_ITEM → currentItem; that reducer case stores images raw (no file_url → file_path mapping), so saveSponsorFormManagedItem → normalizeManagedItem (line 1446: filter((img) => img.file_path)) still silently drops all existing images on save
src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js, RECEIVE_SPONSOR_CUSTOMIZED_FORM_ITEM case (line 108) — currentItem stores raw API images without the mapping
Suggested fix

Apply the same images: (item.images || []).map(img => ({ ...img, file_path: img.file_url })) transform to currentItem in that case

… form item reducer

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/reducers/sponsors/__tests__/sponsor-customized-form-reducer.test.js`:
- Around line 58-93: Add a new unit test that dispatches
RECEIVE_SPONSOR_CUSTOMIZED_FORM to sponsorCustomizedFormReducer with a payload
whose response.items contains an item object that omits the images property
(e.g., { id: 10, name: "Item A" }), and assert that
result.entity.items[0].images is an empty array; use the same DEFAULT_STATE
setup and naming pattern as the existing tests to ensure the reducer's fallback
for missing images is validated.

In `@src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js`:
- Around line 113-117: The reducer reads item.meta_fields.length without
guarding for a missing meta_fields which can throw; change the meta_fields
normalization to mirror images by first defaulting meta_fields to an empty array
when falsy and then using the length check — e.g., treat (item.meta_fields ||
[]) as the source for the length test and return either the original
item.meta_fields when non-empty or an empty array otherwise so the reducer never
reads .length of undefined (refer to the item.meta_fields expression in the
sponsor-customized-form-items-list-reducer).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9d3745-3eac-4fc2-8dbf-c618dbc923ab

📥 Commits

Reviewing files that changed from the base of the PR and between ff59678 and e7daa56.

📒 Files selected for processing (3)
  • src/reducers/sponsors/__tests__/sponsor-customized-form-reducer.test.js
  • src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js
  • src/reducers/sponsors/sponsor-customized-form-reducer.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/reducers/sponsors/sponsor-customized-form-reducer.js

Comment on lines +58 to +93
it("handles items with no images", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: {
id: 1,
code: "FORM1",
items: [{ id: 10, name: "Item A", images: [] }]
}
}
});

expect(result.entity.items[0].images).toEqual([]);
});

it("handles empty items array", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: { id: 1, code: "FORM1", items: [] }
}
});

expect(result.entity.items).toEqual([]);
});

it("handles missing items field", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: { id: 1, code: "FORM1" }
}
});

expect(result.entity.items).toEqual([]);
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a test for items where images is missing (not just empty).

You already validate images: [], but the reducer also handles images being absent. A direct test for that case will lock the intended fallback contract.

Suggested test case
   it("handles items with no images", () => {
@@
     expect(result.entity.items[0].images).toEqual([]);
   });

+  it("handles items with missing images field", () => {
+    const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
+      type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
+      payload: {
+        response: {
+          id: 1,
+          code: "FORM1",
+          items: [{ id: 10, name: "Item A" }]
+        }
+      }
+    });
+
+    expect(result.entity.items[0].images).toEqual([]);
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("handles items with no images", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: {
id: 1,
code: "FORM1",
items: [{ id: 10, name: "Item A", images: [] }]
}
}
});
expect(result.entity.items[0].images).toEqual([]);
});
it("handles empty items array", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: { id: 1, code: "FORM1", items: [] }
}
});
expect(result.entity.items).toEqual([]);
});
it("handles missing items field", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: { id: 1, code: "FORM1" }
}
});
expect(result.entity.items).toEqual([]);
});
it("handles items with no images", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: {
id: 1,
code: "FORM1",
items: [{ id: 10, name: "Item A", images: [] }]
}
}
});
expect(result.entity.items[0].images).toEqual([]);
});
it("handles items with missing images field", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: {
id: 1,
code: "FORM1",
items: [{ id: 10, name: "Item A" }]
}
}
});
expect(result.entity.items[0].images).toEqual([]);
});
it("handles empty items array", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: { id: 1, code: "FORM1", items: [] }
}
});
expect(result.entity.items).toEqual([]);
});
it("handles missing items field", () => {
const result = sponsorCustomizedFormReducer(DEFAULT_STATE, {
type: RECEIVE_SPONSOR_CUSTOMIZED_FORM,
payload: {
response: { id: 1, code: "FORM1" }
}
});
expect(result.entity.items).toEqual([]);
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/reducers/sponsors/__tests__/sponsor-customized-form-reducer.test.js`
around lines 58 - 93, Add a new unit test that dispatches
RECEIVE_SPONSOR_CUSTOMIZED_FORM to sponsorCustomizedFormReducer with a payload
whose response.items contains an item object that omits the images property
(e.g., { id: 10, name: "Item A" }), and assert that
result.entity.items[0].images is an empty array; use the same DEFAULT_STATE
setup and naming pattern as the existing tests to ensure the reducer's fallback
for missing images is validated.

Comment on lines +113 to 117
images: (item.images || []).map((img) => ({
...img,
file_path: img.file_url
})),
meta_fields: item.meta_fields.length > 0 ? item.meta_fields : []
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard meta_fields before reading .length to avoid reducer crashes.

item.meta_fields.length can throw when the backend omits meta_fields. This path should be normalized the same way as images to prevent runtime TypeError.

Suggested fix
       const currentItem = {
         ...item,
         images: (item.images || []).map((img) => ({
           ...img,
           file_path: img.file_url
         })),
-        meta_fields: item.meta_fields.length > 0 ? item.meta_fields : []
+        meta_fields: Array.isArray(item.meta_fields) ? item.meta_fields : []
       };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
images: (item.images || []).map((img) => ({
...img,
file_path: img.file_url
})),
meta_fields: item.meta_fields.length > 0 ? item.meta_fields : []
images: (item.images || []).map((img) => ({
...img,
file_path: img.file_url
})),
meta_fields: Array.isArray(item.meta_fields) ? item.meta_fields : []
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js` around
lines 113 - 117, The reducer reads item.meta_fields.length without guarding for
a missing meta_fields which can throw; change the meta_fields normalization to
mirror images by first defaulting meta_fields to an empty array when falsy and
then using the length check — e.g., treat (item.meta_fields || []) as the source
for the length test and return either the original item.meta_fields when
non-empty or an empty array otherwise so the reducer never reads .length of
undefined (refer to the item.meta_fields expression in the
sponsor-customized-form-items-list-reducer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants