-
Notifications
You must be signed in to change notification settings - Fork 11
Featured Items Use Cases dvObjects extension #316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ofahimIQSS
merged 17 commits into
develop
from
feat/315-featured-items-dvobjects-extension
Jun 24, 2025
Merged
Changes from 9 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
1db9726
initial work
g-saracca 8f2172f
feat: update code to work with dv objects
g-saracca 4510be5
test: functional cases
g-saracca cbc63da
test: integration cases
g-saracca 5ca72db
Merge branch 'develop' into feat/315-featured-items-dvobjects-extension
g-saracca 4d41dc5
feat: add dvObjectDisplayName property
g-saracca be0beb9
refactor: use enum for 'custom' also
g-saracca 95fe0b8
fix: missing use of enum
g-saracca daa3b79
feat: add delete single featured item use case
g-saracca f1b0cfd
refactor: remove collection from namings to avoid confusion with feat…
g-saracca 47e919d
refactor: remove collection from namings to avoid confusion with feat…
g-saracca 07d639f
feat: remove logs and spacing
g-saracca 4f24d91
test: avoid asserting complete url with origin and port
g-saracca a57696e
test: add cases about deleting and restricting a file that is featured
g-saracca 0208adf
remove comments
g-saracca 36fe79b
remove comment
g-saracca 9b27f8d
test: back to unstable image
g-saracca File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,19 @@ | ||
| export type CollectionFeaturedItemsDTO = CollectionFeaturedItemDTO[] | ||
| import { CustomFeaturedItem, DvObjectFeaturedItem } from '../models/CollectionFeaturedItem' | ||
|
|
||
| export interface CollectionFeaturedItemDTO { | ||
| export type CollectionFeaturedItemsDTO = (CustomFeaturedItemDTO | DvObjectFeaturedItemDTO)[] | ||
|
|
||
| export interface CustomFeaturedItemDTO { | ||
| id?: number | ||
| type: CustomFeaturedItem['type'] | ||
| content: string | ||
| displayOrder: number | ||
| file?: File | ||
| keepFile: boolean | ||
| } | ||
|
|
||
| export interface DvObjectFeaturedItemDTO { | ||
| id?: number | ||
| type: DvObjectFeaturedItem['type'] | ||
| dvObjectIdentifier: string | ||
| displayOrder: number | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,25 @@ | ||
| export interface CollectionFeaturedItem { | ||
| export type CollectionFeaturedItem = CustomFeaturedItem | DvObjectFeaturedItem | ||
|
|
||
| export interface CustomFeaturedItem { | ||
| id: number | ||
| type: FeaturedItemType.CUSTOM | ||
| content: string | ||
| imageFileName?: string | ||
| imageFileUrl?: string | ||
| displayOrder: number | ||
| } | ||
|
|
||
| export interface DvObjectFeaturedItem { | ||
| id: number | ||
| type: FeaturedItemType.COLLECTION | FeaturedItemType.DATASET | FeaturedItemType.FILE | ||
| dvObjectIdentifier: string | ||
| dvObjectDisplayName: string | ||
| displayOrder: number | ||
| } | ||
|
|
||
| export enum FeaturedItemType { | ||
| CUSTOM = 'custom', | ||
| COLLECTION = 'collection', | ||
| DATASET = 'dataset', | ||
| FILE = 'file' | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/collections/domain/useCases/DeleteCollectionFeaturedItem.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import { UseCase } from '../../../core/domain/useCases/UseCase' | ||
| import { ICollectionsRepository } from '../repositories/ICollectionsRepository' | ||
|
|
||
| export class DeleteCollectionFeaturedItem implements UseCase<void> { | ||
| private collectionsRepository: ICollectionsRepository | ||
|
|
||
| constructor(collectionsRepository: ICollectionsRepository) { | ||
| this.collectionsRepository = collectionsRepository | ||
| } | ||
|
|
||
| /** | ||
| * Deletes a single featured item, given a featured item id. | ||
| * | ||
| * @param {number} [featuredItemId] - The id of the featured item to delete. | ||
| * @returns {Promise<void>} - This method does not return anything upon successful completion. | ||
| * @throws {WriteError} - If there are errors while writing data. | ||
| */ | ||
| async execute(featuredItemId: number): Promise<void> { | ||
| return await this.collectionsRepository.deleteCollectionFeaturedItem(featuredItemId) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 12 additions & 1 deletion
13
src/collections/infra/repositories/transformers/CollectionFeaturedItemPayload.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,18 @@ | ||
| export interface CollectionFeaturedItemPayload { | ||
| export type CollectionFeaturedItemPayload = CustomFeaturedItemPayload | DvObjectFeaturedItemPayload | ||
|
|
||
| export interface CustomFeaturedItemPayload { | ||
| id: number | ||
| type: 'custom' | ||
| content: string | ||
| imageFileName: string | null | ||
| imageFileUrl: string | null | ||
| displayOrder: number | ||
| } | ||
|
|
||
| export interface DvObjectFeaturedItemPayload { | ||
| id: number | ||
| type: 'dataverse' | 'dataset' | 'datafile' | ||
| dvObjectIdentifier: string | ||
| dvObjectDisplayName: string | ||
| displayOrder: number | ||
| } |
72 changes: 61 additions & 11 deletions
72
src/collections/infra/repositories/transformers/collectionFeaturedItemsTransformer.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,66 @@ | ||
| import { CollectionFeaturedItem } from '../../../domain/models/CollectionFeaturedItem' | ||
| import { CollectionFeaturedItemPayload } from './CollectionFeaturedItemPayload' | ||
| import { | ||
| CollectionFeaturedItem, | ||
| CustomFeaturedItem, | ||
| DvObjectFeaturedItem, | ||
| FeaturedItemType | ||
| } from '../../../domain/models/CollectionFeaturedItem' | ||
| import { | ||
| CollectionFeaturedItemPayload, | ||
| DvObjectFeaturedItemPayload | ||
| } from './CollectionFeaturedItemPayload' | ||
|
|
||
| const apiTypeToDomainType: Record< | ||
| DvObjectFeaturedItemPayload['type'], | ||
| DvObjectFeaturedItem['type'] | ||
| > = { | ||
| dataverse: FeaturedItemType.COLLECTION, | ||
| dataset: FeaturedItemType.DATASET, | ||
| datafile: FeaturedItemType.FILE | ||
| } | ||
|
|
||
| export const domainTypeToApiType: Record< | ||
| DvObjectFeaturedItem['type'], | ||
| DvObjectFeaturedItemPayload['type'] | ||
| > = { | ||
| [FeaturedItemType.COLLECTION]: 'dataverse', | ||
| [FeaturedItemType.DATASET]: 'dataset', | ||
| [FeaturedItemType.FILE]: 'datafile' | ||
| } | ||
|
|
||
| export const transformCollectionFeaturedItemsPayloadToCollectionFeaturedItems = ( | ||
| collectionFeaturedItemsPayload: CollectionFeaturedItemPayload[] | ||
| payload: CollectionFeaturedItemPayload[] | ||
| ): CollectionFeaturedItem[] => { | ||
| return collectionFeaturedItemsPayload | ||
| .map((collectionFeaturedItemPayload) => ({ | ||
| id: collectionFeaturedItemPayload.id, | ||
| content: collectionFeaturedItemPayload.content, | ||
| imageFileUrl: collectionFeaturedItemPayload.imageFileUrl || undefined, | ||
| imageFileName: collectionFeaturedItemPayload.imageFileName || undefined, | ||
| displayOrder: collectionFeaturedItemPayload.displayOrder | ||
| })) | ||
| return payload | ||
| .map((item) => { | ||
| if (item.type === 'custom') { | ||
| const customFeaturedItem: CustomFeaturedItem = { | ||
| id: item.id, | ||
| type: FeaturedItemType.CUSTOM, | ||
| content: item.content, | ||
| imageFileUrl: item.imageFileUrl || undefined, | ||
| imageFileName: item.imageFileName || undefined, | ||
| displayOrder: item.displayOrder | ||
| } | ||
|
|
||
| return customFeaturedItem | ||
| } else { | ||
| // Map API types to domain types | ||
| const type = apiTypeToDomainType[item.type] | ||
|
|
||
| if (!type) { | ||
| throw new Error(`Unknown type: ${item.type}`) | ||
| } | ||
|
|
||
| const dvObjectFeaturedItem: DvObjectFeaturedItem = { | ||
| id: item.id, | ||
| type, | ||
| dvObjectIdentifier: item.dvObjectIdentifier, | ||
| dvObjectDisplayName: item.dvObjectDisplayName, | ||
| displayOrder: item.displayOrder | ||
| } | ||
|
|
||
| return dvObjectFeaturedItem | ||
| } | ||
| }) | ||
| .sort((a, b) => a.displayOrder - b.displayOrder) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| POSTGRES_VERSION=13 | ||
| DATAVERSE_DB_USER=dataverse | ||
| SOLR_VERSION=9.8.0 | ||
| DATAVERSE_IMAGE_REGISTRY=docker.io | ||
| DATAVERSE_IMAGE_TAG=unstable | ||
| DATAVERSE_IMAGE_REGISTRY=ghcr.io | ||
| DATAVERSE_IMAGE_TAG=11550-update-dv-object-featured-items-response | ||
|
g-saracca marked this conversation as resolved.
Outdated
|
||
| DATAVERSE_BOOTSTRAP_TIMEOUT=5m | ||
70 changes: 70 additions & 0 deletions
70
test/functional/collections/DeleteCollectionFeaturedItem.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| import { ApiConfig, deleteCollectionFeaturedItem, WriteError } from '../../../src' | ||
| import { TestConstants } from '../../testHelpers/TestConstants' | ||
| import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' | ||
| import { | ||
| createCollectionViaApi, | ||
| deleteCollectionViaApi | ||
| } from '../../testHelpers/collections/collectionHelper' | ||
| import { createCollectionCustomFeaturedItemViaApi } from '../../testHelpers/collections/collectionFeaturedItemsHelper' | ||
|
|
||
| describe('execute', () => { | ||
| const testCollectionAlias = 'deleteCollectionFeaturedItemTest' | ||
| let featuredItemTestId: number | ||
|
|
||
| beforeEach(async () => { | ||
| ApiConfig.init( | ||
| TestConstants.TEST_API_URL, | ||
| DataverseApiAuthMechanism.API_KEY, | ||
| process.env.TEST_API_KEY | ||
| ) | ||
| }) | ||
|
|
||
| beforeAll(async () => { | ||
| try { | ||
| await createCollectionViaApi(testCollectionAlias) | ||
| const featuredItem = await createCollectionCustomFeaturedItemViaApi(testCollectionAlias, { | ||
| content: '<p class="rte-paragraph">Test content</p>', | ||
| displayOrder: 1, | ||
| withFile: true, | ||
| fileName: 'featured-item-test-image.png' | ||
| }) | ||
| featuredItemTestId = featuredItem.id | ||
| } catch (error) { | ||
| throw new Error( | ||
| `Tests beforeAll(): Error while creating test collection: ${testCollectionAlias}` | ||
| ) | ||
| } | ||
| }) | ||
|
|
||
| afterAll(async () => { | ||
| try { | ||
| await deleteCollectionViaApi(testCollectionAlias) | ||
| } catch (error) { | ||
| throw new Error( | ||
| `Tests afterAll(): Error while deleting test collection: ${testCollectionAlias}` | ||
| ) | ||
| } | ||
| }) | ||
|
|
||
| test('should succesfully delete the featured item', async () => { | ||
| const actual = await deleteCollectionFeaturedItem.execute(featuredItemTestId) | ||
|
|
||
| expect(actual).toBeUndefined() | ||
| }) | ||
|
|
||
| test('should throw an error when featured item does not exist', async () => { | ||
| const invalidFeaturedItemId = 99 | ||
| let writeError: WriteError | undefined | ||
|
|
||
| try { | ||
| await deleteCollectionFeaturedItem.execute(invalidFeaturedItemId) | ||
| } catch (error) { | ||
| writeError = error as WriteError | ||
| } finally { | ||
| expect(writeError).toBeInstanceOf(WriteError) | ||
| expect((writeError as WriteError).message).toEqual( | ||
| `There was an error when writing the resource. Reason was: [404] Could not find dataverse featured item with identifier ${invalidFeaturedItemId}` | ||
| ) | ||
| } | ||
| }) | ||
| }) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.