Skip to content

Commit 35d77f6

Browse files
authored
fix: return 200 with null when item is not published instead of error (#819)
* fix: return 200 with `null` when item is not published instead of error * fix: add tests * fix: sonar issues
1 parent 2f33472 commit 35d77f6

3 files changed

Lines changed: 48 additions & 9 deletions

File tree

src/services/item/plugins/published/schemas.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,10 @@ export const getInformations = {
181181
},
182182

183183
response: {
184-
200: publishEntryWithViews,
184+
200: {
185+
...publishEntryWithViews,
186+
nullable: true,
187+
},
185188
},
186189
};
187190

src/services/item/plugins/published/service.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { Actor, Member } from '../../../member/entities/member';
1313
import { Item } from '../../entities/Item';
1414
import ItemService from '../../service';
1515
import { buildPublishedItemLink } from './constants';
16+
import { ItemPublishedNotFound } from './errors';
1617

1718
interface ActionCount {
1819
actionCount: number;
@@ -67,12 +68,24 @@ export class ItemPublishedService {
6768

6869
// item should be public first
6970
await itemTagRepository.getType(item, ItemTagType.Public, { shouldThrow: true });
70-
const totalViews = await actionRepository.getAggregationForItem(item.path, {
71-
view: 'library',
72-
types: ['collection-view'],
73-
});
74-
const publishedItem = await itemPublishedRepository.getForItem(item);
75-
return { totalViews: (totalViews?.[0] as ActionCount)?.actionCount, ...publishedItem };
71+
72+
try {
73+
// get item published entry
74+
const publishedItem = await itemPublishedRepository.getForItem(item);
75+
// get views from the actions table
76+
const totalViews = await actionRepository.getAggregationForItem(item.path, {
77+
view: 'library',
78+
types: ['collection-view'],
79+
});
80+
return { totalViews: (totalViews?.[0] as ActionCount)?.actionCount, ...publishedItem };
81+
} catch (err) {
82+
// when the item is found but it is not published we simply return `null`
83+
if (err instanceof ItemPublishedNotFound) {
84+
return null;
85+
}
86+
// if the error was not expecte we throw it back
87+
throw err;
88+
}
7689
}
7790

7891
async getMany(actor: Actor, repositories: Repositories, itemIds: string[]) {

src/services/item/plugins/published/test/index.test.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,11 @@ describe('Item Published', () => {
142142
category: selectedCategories[1],
143143
});
144144

145+
const categoryId = selectedCategories.map(({ id }) => id);
145146
const res = await app.inject({
146147
method: HttpMethod.GET,
147148
url: `${ITEMS_ROUTE_PREFIX}/collections${qs.stringify(
148-
{ categoryId: selectedCategories.map(({ id }) => id) },
149+
{ categoryId },
149150
{ addQueryPrefix: true, arrayFormat: 'repeat' },
150151
)}`,
151152
});
@@ -167,10 +168,11 @@ describe('Item Published', () => {
167168
// one random item category
168169
await ItemCategoryRepository.save({ item: collections[2], category: categories[2] });
169170

171+
const categoryId = selectedCategories.map(({ id }) => id).join(',');
170172
const res = await app.inject({
171173
method: HttpMethod.GET,
172174
url: `${ITEMS_ROUTE_PREFIX}/collections${qs.stringify(
173-
{ categoryId: selectedCategories.map(({ id }) => id).join(',') },
175+
{ categoryId },
174176
{ addQueryPrefix: true, arrayFormat: 'repeat' },
175177
)}`,
176178
});
@@ -233,6 +235,27 @@ describe('Item Published', () => {
233235
const items = Object.values(result).map((i) => i.item);
234236
expectManyItems(items as Item[], [otherParentItem, parentItem]);
235237
});
238+
it('Get publish info of non public item returns forbidden', async () => {
239+
// simple item not public and not published
240+
const { item } = await saveItemAndMembership({ member });
241+
const res = await app.inject({
242+
method: HttpMethod.GET,
243+
url: `${ITEMS_ROUTE_PREFIX}/collections/${item.id}/informations`,
244+
});
245+
expect(res.statusCode).toBe(StatusCodes.FORBIDDEN);
246+
});
247+
it('Get publish info of public item that is not published yet returns null', async () => {
248+
const { item } = await saveItemAndMembership({ member });
249+
// make item public
250+
await ItemTagRepository.post(member, item, ItemTagType.Public);
251+
252+
const res = await app.inject({
253+
method: HttpMethod.GET,
254+
url: `${ITEMS_ROUTE_PREFIX}/collections/${item.id}/informations`,
255+
});
256+
expect(res.statusCode).toBe(StatusCodes.OK);
257+
expect(res.json()).toBe(null);
258+
});
236259
it('Throw if category id is invalid', async () => {
237260
const res = await app.inject({
238261
method: HttpMethod.GET,

0 commit comments

Comments
 (0)