Skip to content

Commit bf503b3

Browse files
committed
feat: update collection featured items
1 parent 3f12018 commit bf503b3

File tree

5 files changed

+162
-26
lines changed

5 files changed

+162
-26
lines changed

src/collections/infra/repositories/CollectionsRepository.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { transformCollectionFeaturedItemsPayloadToCollectionFeaturedItems } from
2222
import { CollectionFeaturedItemsDTO } from '../../domain/dtos/CollectionFeaturedItemsDTO'
2323
import { ApiConstants } from '../../../core/infra/repositories/ApiConstants'
2424

25+
// TODO:ME - Create Delete All Featured Items use case
26+
2527
export interface NewCollectionRequestPayload {
2628
alias: string
2729
name: string
@@ -261,8 +263,7 @@ export class CollectionsRepository extends ApiRepository implements ICollections
261263
collectionIdOrAlias: number | string,
262264
featuredItemsDTO: CollectionFeaturedItemsDTO
263265
): Promise<CollectionFeaturedItem[]> {
264-
const featuredItemsFormData =
265-
this.defineUpdateCollectionFeaturedItemsRequestBody(featuredItemsDTO)
266+
const featuredItemsFormData = this.toFeaturedItemsFormData(featuredItemsDTO)
266267

267268
return this.doPut(
268269
`/${this.collectionsResourceName}/${collectionIdOrAlias}/featuredItems`,
@@ -278,23 +279,24 @@ export class CollectionsRepository extends ApiRepository implements ICollections
278279
})
279280
}
280281

281-
private defineUpdateCollectionFeaturedItemsRequestBody(
282-
featuredItemsDTO: CollectionFeaturedItemsDTO
283-
): FormData {
282+
private toFeaturedItemsFormData(featuredItemsDTO: CollectionFeaturedItemsDTO): FormData {
283+
// This is not really necessary because we are sending displayOrder property anyways, but I wanted to keep the order of the items in the form data
284+
const orderedFeaturedItemsDTO = featuredItemsDTO.sort((a, b) => a.displayOrder - b.displayOrder)
285+
284286
const formData = new FormData()
285287

286-
featuredItemsDTO.forEach((item) => {
288+
orderedFeaturedItemsDTO.forEach((item) => {
287289
const { id, content, displayOrder, file, keepFile } = item
288-
289-
// TODO: We need to configure this project to use strict typescript rules or at least strictNullChecks: true
290-
// id is inferred here as number but it should be a number | undefined, same for file
291-
// This config change should be done in a separate issue because it will require changes in some other ts files
292-
293-
formData.append(`items[${item.displayOrder}][id]`, id ? id.toString() : '0')
294-
formData.append(`items[${item.displayOrder}][displayOrder]`, displayOrder.toString())
295-
formData.append(`items[${item.displayOrder}][content]`, content)
296-
formData.append(`items[${item.displayOrder}][file]`, file ? file : 'false')
297-
formData.append(`items[${item.displayOrder}][keepFile]`, keepFile.toString())
290+
const fileName = file ? file.name : ''
291+
292+
formData.append('id', id ? id.toString() : '0')
293+
formData.append('content', content)
294+
formData.append('displayOrder', displayOrder.toString())
295+
formData.append('keepFile', keepFile.toString())
296+
formData.append('fileName', fileName)
297+
if (file) {
298+
formData.append('file', file)
299+
}
298300
})
299301

300302
return formData

src/collections/infra/repositories/transformers/collectionFeaturedItemsTransformer.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import { CollectionFeaturedItemPayload } from './CollectionFeaturedItemPayload'
44
export const transformCollectionFeaturedItemsPayloadToCollectionFeaturedItems = (
55
collectionFeaturedItemsPayload: CollectionFeaturedItemPayload[]
66
): CollectionFeaturedItem[] => {
7-
return collectionFeaturedItemsPayload.map((collectionFeaturedItemPayload) => ({
8-
id: collectionFeaturedItemPayload.id,
9-
content: collectionFeaturedItemPayload.content,
10-
imageFileUrl: collectionFeaturedItemPayload.imageFileUrl,
11-
imageFileName: collectionFeaturedItemPayload.imageFileName,
12-
displayOrder: collectionFeaturedItemPayload.displayOrder
13-
}))
7+
return collectionFeaturedItemsPayload
8+
.map((collectionFeaturedItemPayload) => ({
9+
id: collectionFeaturedItemPayload.id,
10+
content: collectionFeaturedItemPayload.content,
11+
imageFileUrl: collectionFeaturedItemPayload.imageFileUrl,
12+
imageFileName: collectionFeaturedItemPayload.imageFileName,
13+
displayOrder: collectionFeaturedItemPayload.displayOrder
14+
}))
15+
.sort((a, b) => a.displayOrder - b.displayOrder)
1416
}

src/core/infra/repositories/apiConfigBuilders.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ export const buildRequestConfig = (
1616
...(abortSignal && { signal: abortSignal })
1717
}
1818

19+
// When using multipart/form-data for axios to work properly its better to avoid setting the content-type and let the browser manage it
20+
if (contentType === ApiConstants.CONTENT_TYPE_MULTIPART_FORM_DATA) {
21+
requestConfig.headers['Content-Type'] = undefined
22+
}
23+
1924
if (!authRequired) {
2025
return requestConfig
2126
}

test/integration/collections/CollectionsRepository.test.ts

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { CollectionsRepository } from '../../../src/collections/infra/repositories/CollectionsRepository'
22
import { TestConstants } from '../../testHelpers/TestConstants'
33
import {
4+
CollectionFeaturedItemsDTO,
45
CollectionItemType,
56
CollectionPreview,
67
CollectionSearchCriteria,
@@ -31,6 +32,8 @@ import {
3132
import { ROOT_COLLECTION_ID } from '../../../src/collections/domain/models/Collection'
3233
import {
3334
createCollectionFeaturedItemViaApi,
35+
createImageFile,
36+
deleteAllCollectionFeaturedItemsViaApi,
3437
deleteCollectionFeaturedItemViaApi
3538
} from '../../testHelpers/collections/collectionFeaturedItemsHelper'
3639

@@ -762,7 +765,6 @@ describe('CollectionsRepository', () => {
762765

763766
test('should return featured items array given a valid collection alias when collection has featured items', async () => {
764767
const featuredItemsResponse = await sut.getCollectionFeaturedItems(testCollectionAlias)
765-
console.log({ featuredItemsResponse })
766768

767769
expect(featuredItemsResponse.length).toBe(1)
768770
expect(featuredItemsResponse[0].id).toBe(testFeaturedItemId)
@@ -785,4 +787,106 @@ describe('CollectionsRepository', () => {
785787
)
786788
})
787789
})
790+
791+
describe('updateCollectionFeaturedItems', () => {
792+
afterAll(async () => {
793+
try {
794+
await deleteAllCollectionFeaturedItemsViaApi(testCollectionAlias)
795+
} catch (error) {
796+
throw new Error(
797+
`Tests afterAll(): Error while deleting all featured items from collection: ${testCollectionAlias}`
798+
)
799+
}
800+
})
801+
802+
it('should update collection featured items sending all new items', async () => {
803+
const newFeaturedItems: CollectionFeaturedItemsDTO = [
804+
{
805+
content: '<p class="rte-paragraph">Test content 1</p>',
806+
displayOrder: 0,
807+
file: undefined,
808+
keepFile: false
809+
},
810+
{
811+
content: '<p class="rte-paragraph">Test content 2</p>',
812+
displayOrder: 1,
813+
file: undefined,
814+
keepFile: false
815+
},
816+
{
817+
content: '<p class="rte-paragraph">Test content 3</p>',
818+
displayOrder: 2,
819+
file: createImageFile('featured-item-test-image-3.png'),
820+
keepFile: false
821+
}
822+
]
823+
824+
const response = await sut.updateCollectionFeaturedItems(
825+
testCollectionAlias,
826+
newFeaturedItems
827+
)
828+
829+
expect(response).toHaveLength(3)
830+
831+
expect(response[0].content).toEqual(newFeaturedItems[0].content)
832+
expect(response[0].displayOrder).toEqual(newFeaturedItems[0].displayOrder)
833+
expect(response[0].imageFileName).toEqual(undefined)
834+
expect(response[0].imageFileUrl).toEqual(undefined)
835+
836+
expect(response[1].content).toEqual(newFeaturedItems[1].content)
837+
expect(response[1].displayOrder).toEqual(newFeaturedItems[1].displayOrder)
838+
expect(response[1].imageFileName).toEqual(undefined)
839+
expect(response[1].imageFileUrl).toEqual(undefined)
840+
841+
expect(response[2].content).toEqual(newFeaturedItems[2].content)
842+
expect(response[2].displayOrder).toEqual(newFeaturedItems[2].displayOrder)
843+
expect(response[2].imageFileName).toEqual('featured-item-test-image-3.png')
844+
expect(response[2].imageFileUrl).toContain(
845+
'http://localhost:8080/api/access/dataverseFeatureItemImage/'
846+
)
847+
})
848+
})
849+
850+
// describe('deleteAllCollectionFeaturedItems', () => {
851+
852+
// beforeAll(async () => {
853+
// try {
854+
// await createCollectionFeaturedItemViaApi(testCollectionAlias, {
855+
// content: '<p class="rte-paragraph">Test content</p>',
856+
// displayOrder: 1,
857+
// withFile: true,
858+
// fileName: 'featured-item-test-image.png'
859+
// })
860+
// await createCollectionFeaturedItemViaApi(testCollectionAlias, {
861+
// content: '<p class="rte-paragraph">Test content 2</p>',
862+
// displayOrder: 2,
863+
// withFile: false
864+
// })
865+
// await createCollectionFeaturedItemViaApi(testCollectionAlias, {
866+
// content: '<p class="rte-paragraph">Test content 3</p>',
867+
// displayOrder: 3,
868+
// withFile: false
869+
// })
870+
871+
// } catch (error) {
872+
// throw new Error(
873+
// `Tests afterAll(): Error while deleting all featured items from collection: ${testCollectionAlias}`
874+
// )
875+
// }
876+
// })
877+
878+
// it('should delete all collection featured items', async () => {
879+
// const featuredItemsResponseFirst = await sut.getCollectionFeaturedItems(testCollectionAlias)
880+
881+
// console.log({ featuredItemsResponseFirst })
882+
883+
// await deleteAllCollectionFeaturedItemsViaApi(testCollectionAlias)
884+
885+
// const featuredItemsResponse = await sut.getCollectionFeaturedItems(testCollectionAlias)
886+
887+
// console.log({ featuredItemsResponse })
888+
889+
// expect(featuredItemsResponse).toStrictEqual([])
890+
// })
891+
// })
788892
})

test/testHelpers/collections/collectionFeaturedItemsHelper.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ export async function createCollectionFeaturedItemViaApi(
4343
'X-Dataverse-Key': process.env.TEST_API_KEY
4444
}
4545
})
46-
.then((response) => response.data.data)
46+
.then((response) => {
47+
// console.log({ singleFeatItemCreated: JSON.stringify(response.data.data) })
48+
return response.data.data
49+
})
4750
} catch (error) {
4851
console.log(error)
4952
throw new Error(`Error while creating collection featured item in ${collectionAlias}`)
@@ -53,16 +56,36 @@ export async function createCollectionFeaturedItemViaApi(
5356
export async function deleteCollectionFeaturedItemViaApi(featuredItemId: number): Promise<void> {
5457
try {
5558
return await axios.delete(
56-
`${TestConstants.TEST_API_URL}/dataverseFeaturedItems/${featuredItemId}`,
59+
`${TestConstants.TEST_API_URL}/dataverseFeaturedItems/${featuredItemId.toString()}`,
5760
{
5861
headers: { 'Content-Type': 'application/json', 'X-Dataverse-Key': process.env.TEST_API_KEY }
5962
}
6063
)
64+
// .then((resp) => {
65+
// console.log({ deletedResp: JSON.stringify(resp.data) })
66+
// })
6167
} catch (error) {
6268
throw new Error(`Error while deleting collection featured item with id ${featuredItemId}`)
6369
}
6470
}
6571

72+
export async function deleteAllCollectionFeaturedItemsViaApi(collectionAlias: string) {
73+
try {
74+
return await axios.delete(
75+
`${TestConstants.TEST_API_URL}/dataverses/${collectionAlias}/featuredItems`,
76+
{
77+
headers: { 'Content-Type': 'application/json', 'X-Dataverse-Key': process.env.TEST_API_KEY }
78+
}
79+
)
80+
// .then((resp) => {
81+
// console.log({ deletedAllResp: JSON.stringify(resp.data) })
82+
// })
83+
} catch (error) {
84+
console.log(error)
85+
throw new Error(`Error while deleting all featured items from collection: ${collectionAlias}`)
86+
}
87+
}
88+
6689
export const createCollectionFeaturedItemsModel = (): CollectionFeaturedItem[] => {
6790
return [
6891
{

0 commit comments

Comments
 (0)