diff --git a/src/domain/notification/getRecentAggregated/feature.ts b/src/domain/notification/getRecentAggregated/feature.ts index 87ca29c0..21770f73 100644 --- a/src/domain/notification/getRecentAggregated/feature.ts +++ b/src/domain/notification/getRecentAggregated/feature.ts @@ -2,6 +2,7 @@ import type { Requester } from '^/domain/authentication/types'; import { Range } from '^/domain/common/types'; import validateRange from '^/domain/common/validateRange/feature'; +import logger from '^/integrations/logging/module'; import aggregate from '../aggregate/feature'; import type { AggregatedData } from '../aggregate/types'; @@ -13,5 +14,21 @@ export default async function feature(requester: Requester, range: Range): Promi const data = await getRecent(requester.id, range.limit, range.offset); - return Promise.all(data.map(item => aggregate(requester, item))); + const notifications: AggregatedData[] = []; + + const promises = await Promise.allSettled(data.map(item => aggregate(requester, item))); + + promises.forEach((promise) => + { + if (promise.status === 'rejected') + { + logger.logError('Error on aggregating Notification', promise.reason); + + return; + } + + notifications.push(promise.value); + }); + + return (notifications); } diff --git a/src/domain/post/exploreAggregated/feature.ts b/src/domain/post/exploreAggregated/feature.ts index 646b259d..dc886507 100644 --- a/src/domain/post/exploreAggregated/feature.ts +++ b/src/domain/post/exploreAggregated/feature.ts @@ -2,6 +2,7 @@ import type { Requester } from '^/domain/authentication/types'; import type { Range } from '^/domain/common/types'; import validateRange from '^/domain/common/validateRange/feature'; +import logger from '^/integrations/logging/module'; import aggregate from '../aggregate/feature'; import type { AggregatedData } from '../aggregate/types'; @@ -13,5 +14,21 @@ export default async function feature(requester: Requester, range: Range): Promi const data = await explore(requester, range.limit, range.offset); - return Promise.all(data.map(item => aggregate(requester, item))); + const posts: AggregatedData[] = []; + + const promises = await Promise.allSettled(data.map(item => aggregate(requester, item))); + + promises.forEach((promise) => + { + if (promise.status === 'rejected') + { + logger.logError('Error on aggregating Post', promise.reason); + + return; + } + + posts.push(promise.value); + }); + + return posts; } diff --git a/src/domain/post/getAllAggregated/feature.ts b/src/domain/post/getAllAggregated/feature.ts index eaf828bc..b4003e4c 100644 --- a/src/domain/post/getAllAggregated/feature.ts +++ b/src/domain/post/getAllAggregated/feature.ts @@ -2,6 +2,7 @@ import type { Requester } from '^/domain/authentication/types'; import type { Range } from '^/domain/common/types'; import validateRange from '^/domain/common/validateRange/feature'; +import logger from '^/integrations/logging/module'; import aggregate from '../aggregate/feature'; import type { AggregatedData } from '../aggregate/types'; @@ -13,5 +14,21 @@ export default async function feature(requester: Requester, range: Range): Promi const data = await getAll(requester, range.limit, range.offset); - return Promise.all(data.map(item => aggregate(requester, item))); + const posts: AggregatedData[] = []; + + const promises = await Promise.allSettled(data.map(item => aggregate(requester, item))); + + promises.forEach((promise) => + { + if (promise.status === 'rejected') + { + logger.logError('Error on aggregating Post', promise.reason); + + return; + } + + posts.push(promise.value); + }); + + return posts; } diff --git a/src/domain/post/getByCreatorAggregated/feature.ts b/src/domain/post/getByCreatorAggregated/feature.ts index c07de6fb..852567f9 100644 --- a/src/domain/post/getByCreatorAggregated/feature.ts +++ b/src/domain/post/getByCreatorAggregated/feature.ts @@ -2,6 +2,7 @@ import type { Requester } from '^/domain/authentication/types'; import { Range } from '^/domain/common/types'; import validateRange from '^/domain/common/validateRange/feature'; +import logger from '^/integrations/logging/module'; import aggregate from '../aggregate/feature'; import type { AggregatedData } from '../aggregate/types'; @@ -15,5 +16,22 @@ export default async function feature(requester: Requester, creatorId: string, r const data = await getByCreator(creatorId, range.limit, range.offset); - return Promise.all(data.map(item => aggregate(requester, item))); + const posts: AggregatedData[] = []; + + const promises = Promise.allSettled(data.map(item => aggregate(requester, item))); + + (await promises).forEach((promise) => + { + if (promise.status === 'rejected') + { + logger.logError('Error on aggregating Post', promise.reason); + + return; + } + + posts.push(promise.value); + + }); + + return posts; } diff --git a/src/domain/post/getByFollowingAggregated/feature.ts b/src/domain/post/getByFollowingAggregated/feature.ts index 8085cb03..64d3aef9 100644 --- a/src/domain/post/getByFollowingAggregated/feature.ts +++ b/src/domain/post/getByFollowingAggregated/feature.ts @@ -2,6 +2,7 @@ import type { Requester } from '^/domain/authentication/types'; import type { Range } from '^/domain/common/types'; import validateRange from '^/domain/common/validateRange/feature'; +import logger from '^/integrations/logging/module'; import aggregate from '../aggregate/feature'; import type { AggregatedData } from '../aggregate/types'; @@ -13,5 +14,21 @@ export default async function feature(requester: Requester, range: Range): Promi const data = await getByFollowing(requester, range.limit, range.offset); - return Promise.all(data.map(item => aggregate(requester, item))); + const posts: AggregatedData[] = []; + + const promises = await Promise.allSettled(data.map(item => aggregate(requester, item))); + + promises.forEach((promise) => + { + if (promise.status === 'rejected') + { + logger.logError('Error aggrgating Post', promise.reason); + + return; + } + + posts.push(promise.value); + }); + + return posts; } diff --git a/src/domain/reaction/getByPostAggregated/feature.ts b/src/domain/reaction/getByPostAggregated/feature.ts index c2789d23..5223e64a 100644 --- a/src/domain/reaction/getByPostAggregated/feature.ts +++ b/src/domain/reaction/getByPostAggregated/feature.ts @@ -1,6 +1,7 @@ import type { Requester } from '^/domain/authentication/types'; import { Range } from '^/domain/common/types'; +import logger from '^/integrations/logging/module'; import aggregate from '../aggregate/feature'; import type { AggregatedData } from '../aggregate/types'; @@ -10,5 +11,21 @@ export default async function feature(requester: Requester, postId: string, rang { const data = await getByPost(postId, range.limit, range.offset); - return Promise.all(data.map(item => aggregate(requester, item))); + const reactions: AggregatedData[] = []; + + const promises = await Promise.allSettled(data.map(item => aggregate(requester, item))); + + promises.forEach((promise) => + { + if (promise.status === 'rejected') + { + logger.logError('Error on aggregating Reaction', promise.reason); + + return; + } + + reactions.push(promise.value); + }); + + return reactions; } diff --git a/test/domain/notification/fixtures/records.fixture.ts b/test/domain/notification/fixtures/records.fixture.ts index 6df17b35..b71f5eac 100644 --- a/test/domain/notification/fixtures/records.fixture.ts +++ b/test/domain/notification/fixtures/records.fixture.ts @@ -23,6 +23,7 @@ export const RECORDS: Record> = POSTS: [ { id: VALUES.IDS.POST_RATED, creatorId: REQUESTERS.CREATOR1.id, comicId: VALUES.IDS.COMIC, createdAt: new Date(), ratingCount: 10, reactionCount: 0, deleted: false }, + { id: VALUES.IDS.POST_DELETED, creatorId: REQUESTERS.CREATOR1.id, comicId: VALUES.IDS.COMIC, createdAt: new Date(), ratingCount: 5, reactionCount: 1, deleted: true }, ], REACTIONS: [ @@ -37,8 +38,9 @@ export const RECORDS: Record> = NOTIFICATIONS: [ { id: VALUES.IDS.NOTIFICATION1, createdAt: new Date(), type: Types.STARTED_FOLLOWING, senderId: VALUES.IDS.CREATOR1, receiverId: VALUES.IDS.CREATOR2, postId: undefined, reactionId: undefined }, { id: VALUES.IDS.NOTIFICATION2, createdAt: new Date(), type: Types.STARTED_FOLLOWING, senderId: VALUES.IDS.CREATOR2, receiverId: VALUES.IDS.CREATOR1, postId: undefined, reactionId: undefined }, - { id: VALUES.IDS.NOTIFICATION3, createdAt: new Date('01-05-2024'), type: Types.RATED_POST, senderId: VALUES.IDS.CREATOR3, receiverId: VALUES.IDS.CREATOR1, postId: VALUES.IDS.POST_RATED, reactionId: undefined }, - { id: VALUES.IDS.NOTIFICATION4, createdAt: new Date('01-04-2024'), type: Types.RATED_REACTION, senderId: VALUES.IDS.CREATOR2, receiverId: VALUES.IDS.CREATOR1, postId: undefined, reactionId: VALUES.IDS.REACTION_LIKED } + { id: VALUES.IDS.NOTIFICATION3, createdAt: new Date('01-05-2024'), type: Types.RATED_POST, senderId: VALUES.IDS.CREATOR3, receiverId: VALUES.IDS.CREATOR2, postId: VALUES.IDS.POST_RATED, reactionId: undefined }, + { id: VALUES.IDS.NOTIFICATION4, createdAt: new Date('01-04-2024'), type: Types.RATED_REACTION, senderId: VALUES.IDS.CREATOR2, receiverId: VALUES.IDS.CREATOR1, postId: undefined, reactionId: VALUES.IDS.REACTION_LIKED }, + { id: VALUES.IDS.NOTIFICATION5, createdAt: new Date('01-03-2024'), type: Types.RATED_POST, senderId: VALUES.IDS.CREATOR1, receiverId: VALUES.IDS.CREATOR1, postId: VALUES.IDS.POST_DELETED, reactionId: undefined }, ], }; diff --git a/test/domain/notification/fixtures/values.fixture.ts b/test/domain/notification/fixtures/values.fixture.ts index 6c8884b8..439b7037 100644 --- a/test/domain/notification/fixtures/values.fixture.ts +++ b/test/domain/notification/fixtures/values.fixture.ts @@ -5,6 +5,7 @@ export const VALUES = COMIC: 'C1', IMAGE: 'I1', POST_RATED: 'P1', + POST_DELETED: 'P2', REACTION_LIKED: 'R1', @@ -15,6 +16,7 @@ export const VALUES = NOTIFICATION2: 'N2', NOTIFICATION3: 'N3', NOTIFICATION4: 'N4', + NOTIFICATION5: 'N5', CREATOR1: 'CR1', CREATOR2: 'CR2', diff --git a/test/domain/notification/getAllAggregated.spec.ts b/test/domain/notification/getRecentAggregated.spec.ts similarity index 56% rename from test/domain/notification/getAllAggregated.spec.ts rename to test/domain/notification/getRecentAggregated.spec.ts index a765dcc2..776a9574 100644 --- a/test/domain/notification/getAllAggregated.spec.ts +++ b/test/domain/notification/getRecentAggregated.spec.ts @@ -15,29 +15,45 @@ beforeEach(async () => describe('domain/notification/getallAggregated', () => { - it('should give all posts for the requester', async () => + it('should give all notifications under normal circumstances', async () => { - const result = await getRecentAggregated(REQUESTERS.CREATOR1, { offset: 0, limit: 7 }); + const result = await getRecentAggregated(REQUESTERS.CREATOR2, { offset: 0, limit: 7 }); - expect(result).toHaveLength(3); + expect(result).toHaveLength(2); const notification1 = result[0]; const notification2 = result[1]; - const notification3 = result[2]; expect(notification1.type).toBe(Types.STARTED_FOLLOWING); expect(notification1.post).toBe(undefined); expect(notification1.reaction).toBe(undefined); - expect(notification1.relation.following.id).toBe(VALUES.IDS.CREATOR2); + expect(notification1.relation.following.id).toBe(VALUES.IDS.CREATOR1); expect(notification2.type).toBe(Types.RATED_POST); expect(notification2.post?.id).toBe(VALUES.IDS.POST_RATED); expect(notification2.reaction).toBe(undefined); expect(notification2.relation.following.id).toBe(VALUES.IDS.CREATOR3); - expect(notification3.type).toBe(Types.RATED_REACTION); - expect(notification3.post).toBe(undefined); - expect(notification3.reaction?.id).toBe(VALUES.IDS.REACTION_LIKED); - expect(notification3.relation.following.id).toBe(VALUES.IDS.CREATOR2); + }); + + it('should give only the notifications that aggregate without errors', async () => + { + const result = await getRecentAggregated(REQUESTERS.CREATOR1, { offset: 0, limit: 7 }); + + expect(result).toHaveLength(2); + + const notification1 = result[0]; + const notification2 = result[1]; + + expect(notification1.type).toBe(Types.STARTED_FOLLOWING); + expect(notification1.post).toBe(undefined); + expect(notification1.reaction).toBe(undefined); + expect(notification1.relation.following.id).toBe(VALUES.IDS.CREATOR2); + + expect(notification2.type).toBe(Types.RATED_REACTION); + expect(notification2.post).toBe(undefined); + expect(notification2.reaction?.id).toBe(VALUES.IDS.REACTION_LIKED); + expect(notification2.relation.following.id).toBe(VALUES.IDS.CREATOR2); + }); });