Skip to content

fix: denormalize module data when a show page is recieved, unit test#862

Open
tomrndom wants to merge 4 commits intomasterfrom
fix/show-pages-denormalize-reducer
Open

fix: denormalize module data when a show page is recieved, unit test#862
tomrndom wants to merge 4 commits intomasterfrom
fix/show-pages-denormalize-reducer

Conversation

@tomrndom
Copy link
Copy Markdown

@tomrndom tomrndom commented Apr 7, 2026

ref:

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

Summary by CodeRabbit

  • Tests

    • Added comprehensive tests for sponsor pages state: request/receive flows, reset, archive/unarchive, delete, pagination, and module handling.
  • Bug Fixes

    • Consistent document/media module shapes and timezone-aware upload-deadline handling; correct module type selection when files are absent; pagination metadata fixes.
  • Refactor

    • Centralized page-module normalization/denormalization into a shared utility and removed duplicated inline transformations.

…ests

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

coderabbitai bot commented Apr 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 69cc851e-6d26-4e51-8ebf-9634a444f946

📥 Commits

Reviewing files that changed from the base of the PR and between c8ec641 and cd0c5e7.

📒 Files selected for processing (1)
  • src/utils/page-template.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utils/page-template.js

📝 Walkthrough

Walkthrough

Centralized page-module normalization/denormalization into src/utils/page-template.js; updated actions and reducers to use these utilities (removing inline per-kind and moment-timezone logic); added comprehensive Jest tests for showPagesListReducer.

Changes

Cohort / File(s) Summary
Tests
src/reducers/sponsors/__tests__/show-pages-list-reducer.test.js
Added a 469-line Jest suite exercising reducer flows: reset, request/receive pages, archive/unarchive/delete, receive single page, reset form, and global sponsorships; verifies module/timezone/file-shape handling.
New utilities
src/utils/page-template.js
Added denormalizePageModules(modules, timeZone) and normalizePageTemplateModules(modules, timeZone) to centralize conversions (upload_deadline timezone handling, DOCUMENT file array ↔ single object, file_path/public_url mapping, _tempId removal, file_type_id unwrapping, INPUT/file distinctions).
Reducers
src/reducers/sponsors/show-pages-list-reducer.js, src/reducers/sponsors_inventory/page-template-reducer.js
Replaced inline per-module normalization with calls to denormalizePageModules; removed direct moment-timezone and per-kind transformation logic.
Actions — page templates & show pages
src/actions/page-template-actions.js, src/actions/show-pages-actions.js
Removed inline module normalization and moment-timezone usage; delegate normalization to normalizePageTemplateModules and updated imports.
Actions — sponsor pages
src/actions/sponsor-pages-actions.js
Replaced inline normalization with normalizePageTemplateModules(entity.modules, summitTZ) and flattened async thunk shapes for sponsor pages fetchers; removed old per-kind logic and unused imports.
Misc / minor
...
Whitespace/import cleanup and removal of unused constants related to previous per-kind logic; no public API signature changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • romanetar
  • smarcet
  • gcutrini

Poem

🐰 I hopped through modules, tidy and neat,

Moved deadlines and files so each shape would meet.
Tests nibbled bugs, assertions bright and clear,
Utilities hummed — organized and dear.
A rabbit's patch, quick paws and a cheer. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: fixing denormalization of module data when a show page is received and adding unit tests for validation.

✏️ 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/show-pages-denormalize-reducer

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.

🧹 Nitpick comments (1)
src/reducers/sponsors/show-pages-list-reducer.js (1)

152-165: Extract the DOCUMENT denormalization into a shared helper.

This branch now mirrors src/reducers/sponsors_inventory/page-template-reducer.js:60-85, so the next document-shape change will have to land in two reducers. A small shared helper for the file/type rewrite would keep the receive flows from drifting.

♻️ Refactor sketch
-        if (module.kind === PAGES_MODULE_KINDS.DOCUMENT) {
-          if (module.file) {
-            tmpModule.file = [
-              {
-                ...module.file,
-                file_path: module.file.storage_key,
-                public_url: module.file.file_url
-              }
-            ];
-            tmpModule.type = PAGE_MODULES_DOWNLOAD.FILE;
-          } else {
-            tmpModule.type = PAGE_MODULES_DOWNLOAD.URL;
-          }
-        }
+        Object.assign(tmpModule, denormalizeDocumentModule(module));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/reducers/sponsors/show-pages-list-reducer.js` around lines 152 - 165,
Extract the DOCUMENT denormalization logic into a shared helper to avoid
duplication: move the block that checks module.kind ===
PAGES_MODULE_KINDS.DOCUMENT and rewrites module.file -> tmpModule.file
(including file_path: module.file.storage_key and public_url:
module.file.file_url) and sets tmpModule.type to PAGE_MODULES_DOWNLOAD.FILE or
PAGE_MODULES_DOWNLOAD.URL into a new utility function (e.g.,
normalizeDocumentModule(module) or denormalizeDocumentFile(module, tmpModule));
replace the inlined logic in show-pages-list-reducer (and mirror change in
sponsors_inventory/page-template-reducer) to call that helper so future
document-shape changes are implemented once.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/reducers/sponsors/show-pages-list-reducer.js`:
- Around line 152-165: Extract the DOCUMENT denormalization logic into a shared
helper to avoid duplication: move the block that checks module.kind ===
PAGES_MODULE_KINDS.DOCUMENT and rewrites module.file -> tmpModule.file
(including file_path: module.file.storage_key and public_url:
module.file.file_url) and sets tmpModule.type to PAGE_MODULES_DOWNLOAD.FILE or
PAGE_MODULES_DOWNLOAD.URL into a new utility function (e.g.,
normalizeDocumentModule(module) or denormalizeDocumentFile(module, tmpModule));
replace the inlined logic in show-pages-list-reducer (and mirror change in
sponsors_inventory/page-template-reducer) to call that helper so future
document-shape changes are implemented once.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6728e2ce-4a59-4cb2-8326-61268074ce99

📥 Commits

Reviewing files that changed from the base of the PR and between 033cf84 and eee5557.

📒 Files selected for processing (2)
  • src/reducers/sponsors/__tests__/show-pages-list-reducer.test.js
  • src/reducers/sponsors/show-pages-list-reducer.js

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

🧹 Nitpick comments (2)
src/utils/page-template.js (1)

14-21: Consider validating epochToMomentTimeZone return value.

Based on usage patterns elsewhere in the codebase (e.g., src/utils/methods.js:315-325), epochToMomentTimeZone may return invalid values when conversion fails. The existing pattern uses moment.isMoment() to validate before proceeding. Here, no such validation occurs, which could result in an invalid moment object being assigned to upload_deadline.

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

In `@src/utils/page-template.js` around lines 14 - 21, The assignment to
upload_deadline should validate epochToMomentTimeZone's return like other
usages: when timeZone is provided call
epochToMomentTimeZone(module.upload_deadline, timeZone) and check with
moment.isMoment() (or fall back to moment(module.upload_deadline *
MILLISECONDS_IN_SECOND) or omit the field) so that an invalid moment is never
assigned; update the ternary/conditional creating upload_deadline to perform
this validation and fallback logic referencing epochToMomentTimeZone,
moment.isMoment, timeZone, module.upload_deadline and MILLISECONDS_IN_SECOND.
src/actions/show-pages-actions.js (1)

129-142: Consider passing summit timezone for consistency.

normalizePageTemplateModules is called without the timeZone parameter, causing it to use moment.utc().unix() for deadline conversion. While moment.unix() returns the same epoch regardless of timezone display, passing the summit timezone would maintain consistency with how denormalizePageModules is called in the reducer (with state.summitTZ).

♻️ Optional fix for consistency
-const normalizeShowPage = (entity) => {
+const normalizeShowPage = (entity, timeZone) => {
   const normalizedEntity = { ...entity };

   normalizedEntity.apply_to_all_types = false;

   if (entity.sponsorship_types?.includes("all")) {
     normalizedEntity.apply_to_all_types = true;
     delete normalizedEntity.sponsorship_types;
   }

-  normalizedEntity.modules = normalizePageTemplateModules(entity.modules);
+  normalizedEntity.modules = normalizePageTemplateModules(entity.modules, timeZone);

   return normalizedEntity;
 };

Then update the call site in saveShowPage:

-  const normalizedShowPage = normalizeShowPage(entity);
+  const summitTZ = currentSummit.time_zone?.name;
+  const normalizedShowPage = normalizeShowPage(entity, summitTZ);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/actions/show-pages-actions.js` around lines 129 - 142, The
normalizeShowPage function calls normalizePageTemplateModules without a
timezone, causing inconsistent deadline handling; update normalizeShowPage to
accept and forward the summit timezone into normalizePageTemplateModules (e.g.,
add a timeZone parameter and call normalizePageTemplateModules(entity.modules,
timeZone)); also ensure saveShowPage (where normalizeShowPage is invoked) passes
state.summitTZ through to normalizeShowPage so the same summitTZ used by
denormalizePageModules in the reducer is used here as well.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/utils/page-template.js`:
- Around line 10-11: denormalizePageModules and normalizePageTemplateModules
call .map() on the modules parameter without guarding against null/undefined;
update both functions (denormalizePageModules and normalizePageTemplateModules)
to defensively handle falsy modules by treating modules as an empty array (e.g.,
defaulting modules to [] before mapping or returning [] when modules is falsy)
so the .map() call never throws; preserve existing parameters (like timeZone)
and behavior for non-empty arrays.

---

Nitpick comments:
In `@src/actions/show-pages-actions.js`:
- Around line 129-142: The normalizeShowPage function calls
normalizePageTemplateModules without a timezone, causing inconsistent deadline
handling; update normalizeShowPage to accept and forward the summit timezone
into normalizePageTemplateModules (e.g., add a timeZone parameter and call
normalizePageTemplateModules(entity.modules, timeZone)); also ensure
saveShowPage (where normalizeShowPage is invoked) passes state.summitTZ through
to normalizeShowPage so the same summitTZ used by denormalizePageModules in the
reducer is used here as well.

In `@src/utils/page-template.js`:
- Around line 14-21: The assignment to upload_deadline should validate
epochToMomentTimeZone's return like other usages: when timeZone is provided call
epochToMomentTimeZone(module.upload_deadline, timeZone) and check with
moment.isMoment() (or fall back to moment(module.upload_deadline *
MILLISECONDS_IN_SECOND) or omit the field) so that an invalid moment is never
assigned; update the ternary/conditional creating upload_deadline to perform
this validation and fallback logic referencing epochToMomentTimeZone,
moment.isMoment, timeZone, module.upload_deadline and MILLISECONDS_IN_SECOND.
🪄 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: 24657e69-6cf7-45e4-96c3-9d2379950506

📥 Commits

Reviewing files that changed from the base of the PR and between eee5557 and c8ec641.

📒 Files selected for processing (6)
  • src/actions/page-template-actions.js
  • src/actions/show-pages-actions.js
  • src/actions/sponsor-pages-actions.js
  • src/reducers/sponsors/show-pages-list-reducer.js
  • src/reducers/sponsors_inventory/page-template-reducer.js
  • src/utils/page-template.js
✅ Files skipped from review due to trivial changes (1)
  • src/actions/sponsor-pages-actions.js

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@tomrndom tomrndom requested a review from smarcet April 10, 2026 18:06
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.

1 participant