Skip to content

Commit c0faceb

Browse files
fix: normalize parent.related in flattenRelated recursively (#660)
Co-authored-by: Mateusz Ziarko <mziarko@virtuslab.com>
1 parent 9b9f763 commit c0faceb

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

server/src/repositories/navigation-item.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ export const removeSensitiveFields = ({
135135
: undefined,
136136
});
137137

138-
export const flattenRelated = ({ related, ...item }: any) => ({
138+
export const flattenRelated = ({ related, parent, ...item }: any): NavigationItemDBSchema => ({
139139
...item,
140+
parent: parent ? flattenRelated(parent) : parent,
140141
related: related?.[0],
141142
});

server/tests/repositories/navigation.test.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { faker } from '@faker-js/faker';
22
import { Core } from '@strapi/strapi';
3-
import { asProxy } from '../utils';
43
import { getNavigationRepository } from '../../src/repositories';
54
import { getPluginModels } from '../../src/utils';
5+
import { asProxy } from '../utils';
66

77
jest.mock('../../src/utils', () => ({
88
...jest.requireActual('../../src/utils'),
@@ -159,6 +159,60 @@ describe('Navigation', () => {
159159
expect(mockCreate).not.toHaveBeenCalled();
160160
expect(result).toBeDefined();
161161
});
162+
it('should handle parent.related as array (bug reproduction)', async () => {
163+
// Given - Strapi returns parent.related as an array (morphToMany behavior)
164+
const mockData = [
165+
getMockNavigationData({
166+
items: [
167+
{
168+
id: 1,
169+
documentId: 'item-1',
170+
title: 'Parent Item',
171+
type: 'INTERNAL',
172+
path: '/parent',
173+
uiRouterKey: 'parent',
174+
menuAttached: false,
175+
order: 0,
176+
collapsed: false,
177+
related: [{ documentId: 'rel-1', __type: 'api::author.author' }],
178+
parent: null,
179+
},
180+
{
181+
id: 2,
182+
documentId: 'item-2',
183+
title: 'Child Item',
184+
type: 'INTERNAL',
185+
path: '/child',
186+
uiRouterKey: 'child',
187+
menuAttached: false,
188+
order: 0,
189+
collapsed: false,
190+
related: [{ documentId: 'rel-2', __type: 'api::author.author' }],
191+
parent: {
192+
id: 1,
193+
documentId: 'item-1',
194+
title: 'Parent Item',
195+
type: 'INTERNAL',
196+
path: '/parent',
197+
uiRouterKey: 'parent',
198+
menuAttached: false,
199+
order: 0,
200+
collapsed: false,
201+
// related as an array
202+
related: [{ documentId: 'rel-1', __type: 'api::author.author' }],
203+
},
204+
},
205+
],
206+
}),
207+
];
208+
mockFindMany.mockResolvedValue(mockData);
209+
210+
const repository = getNavigationRepository({ strapi: mockStrapi });
211+
212+
// When & Then - This should NOT throw, but currently does with:
213+
// "Expected object, received array" at items[1].parent.related
214+
await expect(repository.find({ filters: {}, locale: 'en' })).resolves.toBeDefined();
215+
});
162216
});
163217
describe('remove()', () => {
164218
it('should delete navigation with documentId and locale', async () => {

0 commit comments

Comments
 (0)