Skip to content

Conversation

@DanilaRubleuski
Copy link
Contributor

@DanilaRubleuski DanilaRubleuski commented Aug 20, 2025

Description

As a part of Metadata pubic API changes, after successful launch of a new API with new naming we need to cleanup old display_name naming for metadataTaxonomyFetcher

Summary by CodeRabbit

  • Refactor

    • Standardized metadata label to a single naming convention across taxonomy fetching and shaping, removing legacy fallbacks so sidebar metadata is consistent.
  • Tests

    • Updated test fixtures and expectations to the new naming convention and removed deprecated legacy-key cases.
  • Bug Fixes

    • Fixed mixed-naming inconsistencies that caused missing or incorrect metadata labels; result counts and limits are now surfaced when present.

@DanilaRubleuski DanilaRubleuski requested review from a team as code owners August 20, 2025 08:42
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 20, 2025

Walkthrough

Renames Flow fields display_namedisplayName in type declarations, updates fetchers to read displayName exclusively (removing fallbacks to display_name), includes totalResultCount and limit in shaped fetcher responses when present, and updates tests/mocks to the new field names. No public API or function signature changes.

Changes

Cohort / File(s) Summary of Changes
Type field rename
src/common/types/metadata.js
Renamed fields: display_namedisplayName in MetadataOptionEntryAncestor and MetadataOptionEntry.
Fetcher logic alignment
src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts, src/elements/content-sidebar/fetchers/metadataTaxonomyNodeAncestorsFetcher.ts
Removed fallbacks to display_name; mappings now use displayName exclusively for option values, levelName/levelValue, and ancestor hydration. Fetcher response now conditionally includes totalResultCount and limit when provided.
Test updates
src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts
Updated test fixtures and expectations to use displayName; removed legacy-key convention tests; preserved expected output shapes aligned to new input naming.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Fetcher
  participant API
  Note over Fetcher,API #E8F8FF: Mapping uses only `displayName`
  Client->>Fetcher: Request taxonomy data
  Fetcher->>API: Fetch taxonomy payload
  API-->>Fetcher: Returns options with `displayName`
  alt `displayName` present
    Fetcher->>Fetcher: Map item.displayName -> levelName / levelValue / ancestors
  else missing `displayName`
    Fetcher->>Fetcher: Fields may be undefined (no fallback)
  end
  Fetcher-->>Client: Return shaped response (includes totalResultCount & limit when provided)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

ready-to-merge

Suggested reviewers

  • bkepka-box
  • tjuanitas
  • jpan-box

Poem

I pity the fool who kept the underscore,
displayName stepped up and settled the score.
Ancestors aligned, options dressed fine,
Fetchers read straight — no fallback line. 🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.1.2)
src/common/types/metadata.js

biome: error while loading shared libraries: libpthread.so.0: cannot open shared object file: No such file or directory

src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts

biome: error while loading shared libraries: libpthread.so.0: cannot open shared object file: No such file or directory

src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts

biome: error while loading shared libraries: libpthread.so.0: cannot open shared object file: No such file or directory

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

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

Copy link
Contributor

@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 (4)
src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts (2)

22-45: Add an assertion to ensure legacy display_name does not leak through ancestors

Given the fetcher’s new contract to use displayName only, it’s worth asserting that any legacy display_name fields are not present in the returned ancestors. This protects against regressions.

You can augment the first test with:

// after computing result
expect(result.options[1].ancestors?.[0]).not.toHaveProperty('display_name');

94-94: Rename test for clarity; it uses new naming

The test title says "old naming convention" but the data uses displayName. Consider renaming for clarity.

-    test('should fetch metadata options and return formatted data - old naming convention', async () => {
+    test('should fetch metadata options and return formatted data', async () => {
src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts (2)

19-33: Pagination marker likely should come from response.next_marker, not request options

Current code echoes the input marker back in the response. Typically, fetchers return the server’s next_marker so the caller can request the next page. Given MetadataOptions has next_marker (per Flow types), consider using it.

If this is the intended contract, ignore. Otherwise, here’s a proposed change:

-    const { marker = null } = options;
+    // Prefer the server-provided next marker; fall back to the request marker if needed
+    const marker = metadataOptions.next_marker ?? options.marker ?? null;
@@
         options: metadataOptions.entries.map((metadataOption: MetadataOptionEntry) => ({
             value: metadataOption.id,
             displayValue: metadataOption.displayName,
             level: metadataOption.level,
             parentId: metadataOption.parentId,
             nodePath: metadataOption.nodePath,
             deprecated: metadataOption.deprecated,
             ancestors: metadataOption.ancestors?.map(({ displayName, display_name, ...rest }) => ({
                 ...rest,
                 displayName,
             })),
             selectable: metadataOption.selectable,
         })),
         marker,

If we switch to next_marker, the tests expecting marker === options.marker will need to be updated accordingly. Let me know if you want me to adjust the tests.


60-69: Optional: add Map generics for clarity

Typing the map improves readability and avoids any accidental type drift.

Example:

const levelsMap = new Map<number, Partial<HydratedMetadataTaxonomyLevel>>();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4f89946 and 40e0b66.

📒 Files selected for processing (3)
  • src/common/types/metadata.js (1 hunks)
  • src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts (7 hunks)
  • src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts (1)
src/api/Metadata.js (1)
  • metadataTaxonomyNode (1383-1383)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
🔇 Additional comments (5)
src/common/types/metadata.js (2)

141-143: Rename to displayName aligns with new API — looks good

The field rename on MetadataOptionEntryAncestor is consistent with the PR objective and related fetcher/test updates.


147-152: Align level type with actual usage and API contract
Tests for metadataTaxonomyFetcher mock level as strings ('1', '2'), while story fixtures and other metadata APIs treat it as numbers. To prevent type drift:

• In src/common/types/metadata.js, update both declarations

// from
level: number,
// to
level: string | number,

in MetadataOptionEntry and MetadataOptionEntryAncestor.
• Optionally, normalize the value in metadataTaxonomyFetcher (e.g. level: Number(metadataOption.level)) if the API always returns numbers.
• Confirm the backend/API response shape for level and choose a single representation or keep the union type.

src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts (1)

311-351: LGTM: ancestors hydration expectations match the new naming

The test aligns with the updated fetcher logic: levelName from taxonomy.levels[i].displayName and levelValue from node/ancestor.displayName. Good coverage of the happy path.

src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts (2)

62-68: LGTM: levelName now sourced from displayName

This matches the new API naming and the updated tests. No fallback to display_name remains here.


82-88: LGTM: ancestor hydration uses displayName

Hydration updates levelValue and id from ancestors using displayName only, consistent with the new API.

Comment on lines 20 to 29
options: metadataOptions.entries.map((metadataOption: MetadataOptionEntry) => ({
value: metadataOption.id,
displayValue: metadataOption.display_name || metadataOption.displayName,
displayValue: metadataOption.displayName,
level: metadataOption.level,
parentId: metadataOption.parentId,
nodePath: metadataOption.nodePath,
deprecated: metadataOption.deprecated,
ancestors: metadataOption.ancestors?.map(({display_name, displayName, ...rest}) => ({...rest, displayName: display_name || displayName })),
ancestors: metadataOption.ancestors?.map(({displayName, ...rest}) => ({...rest, displayName })),
selectable: metadataOption.selectable,
})),
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Strip legacy display_name from ancestors to avoid leaking snake_case fields

The current mapping preserves all other fields via ...rest. If the API still sends display_name on ancestors, that key will pass through to consumers. Since this PR’s goal is to remove legacy display_name usage, we should explicitly omit it.

Apply this diff:

-            ancestors: metadataOption.ancestors?.map(({displayName, ...rest}) => ({...rest, displayName })),
+            ancestors: metadataOption.ancestors?.map(({ displayName, display_name, ...rest }) => ({
+                ...rest,
+                displayName,
+            })),
📝 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
options: metadataOptions.entries.map((metadataOption: MetadataOptionEntry) => ({
value: metadataOption.id,
displayValue: metadataOption.display_name || metadataOption.displayName,
displayValue: metadataOption.displayName,
level: metadataOption.level,
parentId: metadataOption.parentId,
nodePath: metadataOption.nodePath,
deprecated: metadataOption.deprecated,
ancestors: metadataOption.ancestors?.map(({display_name, displayName, ...rest}) => ({...rest, displayName: display_name || displayName })),
ancestors: metadataOption.ancestors?.map(({displayName, ...rest}) => ({...rest, displayName })),
selectable: metadataOption.selectable,
})),
options: metadataOptions.entries.map((metadataOption: MetadataOptionEntry) => ({
value: metadataOption.id,
displayValue: metadataOption.displayName,
level: metadataOption.level,
parentId: metadataOption.parentId,
nodePath: metadataOption.nodePath,
deprecated: metadataOption.deprecated,
ancestors: metadataOption.ancestors?.map(({ displayName, display_name, ...rest }) => ({
...rest,
displayName,
})),
selectable: metadataOption.selectable,
})),
🤖 Prompt for AI Agents
In src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts around lines
20 to 29, the ancestors mapping currently preserves any legacy snake_case
display_name field via ...rest; update the mapping to explicitly destructure and
omit display_name (and keep displayName) so the returned ancestor objects
include displayName but do not include legacy display_name — e.g., destructure
ancestors items to pull out displayName and display_name (or explicitly remove
display_name) and then return {...rest, displayName} so legacy keys are not
passed through to consumers.

@greg-in-a-box greg-in-a-box changed the title WEBAPP-33012: Clean up taxonomy fetchers in BUIE fix(content-sidebar): Clean up taxonomy fetchers Aug 20, 2025
Copy link
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts (1)

15-20: Fix API mock typing or cast it right, fool!

apiMock: jest.Mocked<API> is only partially implemented here; without a cast this will blow up TypeScript. Cast or narrow the type so the suite compiles.

Apply this diff to both beforeEach blocks:

-    apiMock = {
+    apiMock = {
         getMetadataAPI: jest.fn().mockReturnValue({
-            getMetadataOptions: jest.fn(),
+            getMetadataOptions: jest.fn(),
         }),
-    };
+    } as unknown as jest.Mocked<API>;
-    apiMock = {
+    apiMock = {
         getMetadataAPI: jest.fn().mockReturnValue({
             getMetadataTaxonomy: jest.fn(),
             getMetadataTaxonomyNode: jest.fn(),
         }),
-    };
+    } as unknown as jest.Mocked<API>;

Also applies to: 303-309

🧹 Nitpick comments (4)
src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts (4)

94-95: Say what you mean in the test title, fool.

This test validates legacy pagination fields (snake_case), not old option-name keys. Rename for clarity.

-test('should fetch metadata options and return formatted data - old naming convention', async () => {
+test('should map legacy snake_case pagination fields to camelCase (limit, total_result_count)', async () => {

199-214: Don’t assert undefined fields; verify absence, fool.

Expecting { ancestors: undefined, nodePath: undefined, ... } is brittle. Prefer matching required fields and asserting missing props explicitly.

-        expect(result).toEqual({
+        expect(result).toMatchObject({
             options: [
                 { 
                     value: 'opt1', 
                     displayValue: 'Option 1', 
                     level: '1', 
                     parentId: 'parent1',
-                    nodePath: undefined,
-                    deprecated: undefined,
-                    ancestors: undefined,
-                    selectable: undefined,
                 },
             ],
             marker: 'marker_1',
-        });
+        });
+        expect(result.options[0]).not.toHaveProperty('nodePath');
+        expect(result.options[0]).not.toHaveProperty('deprecated');
+        expect(result.options[0]).not.toHaveProperty('ancestors');
+        expect(result.options[0]).not.toHaveProperty('selectable');

If the fetcher intentionally sets undefined keys, keep as-is. Otherwise, apply the refactor for stability.


295-299: Keep IDs consistent — use fileId everywhere, fool.

fileID vs fileId is noisy. Align naming for readability.

-const fileID = '12345';
+const fileId = '12345';
...
- expect(apiMock.getMetadataAPI(false).getMetadataTaxonomy).toHaveBeenCalledWith(fileID, scope, taxonomyKey);
+ expect(apiMock.getMetadataAPI(false).getMetadataTaxonomy).toHaveBeenCalledWith(fileId, scope, taxonomyKey);
...
-        const result = await metadataTaxonomyNodeAncestorsFetcher(apiMock, fileID, scope, taxonomyKey, nodeID);
+        const result = await metadataTaxonomyNodeAncestorsFetcher(apiMock, fileId, scope, taxonomyKey, nodeID);
...
-        await expect(metadataTaxonomyNodeAncestorsFetcher(apiMock, fileID, scope, taxonomyKey, nodeID)).rejects.toThrow(
+        await expect(metadataTaxonomyNodeAncestorsFetcher(apiMock, fileId, scope, taxonomyKey, nodeID)).rejects.toThrow(

Also applies to: 354-362, 384-396, 403-416


365-372: Add a null-ancestors case too, sucka.

You cover empty array; add a test where ancestors: null to ensure identical behavior.

Example to add nearby:

test('should handle null ancestors as empty', async () => {
    const mockTaxonomy = { displayName: 'Geography', namespace: 'my_enterprise', id: 'my_id', key: 'geography', levels: [{ level: 1, displayName: 'Level 1', description: 'Description 1' }] };
    const mockTaxonomyNode = { id: 'node_abc', level: 1, displayName: 'Node ABC', ancestors: null as any };
    apiMock.getMetadataAPI(false).getMetadataTaxonomy.mockResolvedValue(mockTaxonomy);
    apiMock.getMetadataAPI(false).getMetadataTaxonomyNode.mockResolvedValue(mockTaxonomyNode);
    const result = await metadataTaxonomyNodeAncestorsFetcher(apiMock, fileId, scope, taxonomyKey, nodeID);
    expect(result).toEqual([{ level: 1, levelName: 'Level 1', description: 'Description 1', id: 'node_abc', levelValue: 'Node ABC' }]);
});

Also applies to: 377-379

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cf44f80 and bd338a2.

📒 Files selected for processing (3)
  • src/common/types/metadata.js (1 hunks)
  • src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts (7 hunks)
  • src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/common/types/metadata.js
  • src/elements/content-sidebar/fetchers/metadataTaxonomyFetcher.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint_test_build
  • GitHub Check: Summary
🔇 Additional comments (4)
src/elements/content-sidebar/__tests__/metadataTaxonomyFetcher.test.ts (4)

24-44: Nice displayName cleanup — no more snake_case, sucka!

Switch to displayName in entries and nested ancestors looks consistent and aligns with the new API.


248-279: Backward-compat test looks tight, fool.

Null ancestors handled, optional fields omitted, selectable preserved. Solid coverage.


313-321: Ancestors fetcher: displayName usage and level mapping look sharp.

Taxonomy levels map to levelName/description, node/ancestor names to levelValue. Clean and coherent.

Also applies to: 327-329


219-246: Marker passthrough logic is correct

I pity the fool who didn’t see that the fetcher destructures marker from the input options (const { marker = null } = options) and returns it unchanged, so the test’s marker: null expectation is valid.

Likely an incorrect or invalid review comment.

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