Compare commits
12 Commits
feat/serve
...
feat/colle
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d8d55b3fd | ||
|
|
3e3bab28d2 | ||
|
|
55c70159ed | ||
|
|
c1fdb04130 | ||
|
|
337c79447e | ||
|
|
1f2aaf528a | ||
|
|
a67ecaa922 | ||
|
|
289cd06995 | ||
|
|
990d500333 | ||
|
|
e712d1e3ae | ||
|
|
f13d00465d | ||
|
|
85c42da31c |
@@ -0,0 +1,5 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "TeamCollection" ADD COLUMN "data" JSONB;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "UserCollection" ADD COLUMN "data" JSONB;
|
||||||
@@ -43,6 +43,7 @@ model TeamInvitation {
|
|||||||
model TeamCollection {
|
model TeamCollection {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
parentID String?
|
parentID String?
|
||||||
|
data Json?
|
||||||
parent TeamCollection? @relation("TeamCollectionChildParent", fields: [parentID], references: [id])
|
parent TeamCollection? @relation("TeamCollectionChildParent", fields: [parentID], references: [id])
|
||||||
children TeamCollection[] @relation("TeamCollectionChildParent")
|
children TeamCollection[] @relation("TeamCollectionChildParent")
|
||||||
requests TeamRequest[]
|
requests TeamRequest[]
|
||||||
@@ -74,7 +75,8 @@ model Shortcode {
|
|||||||
creatorUid String?
|
creatorUid String?
|
||||||
User User? @relation(fields: [creatorUid], references: [uid])
|
User User? @relation(fields: [creatorUid], references: [uid])
|
||||||
createdOn DateTime @default(now())
|
createdOn DateTime @default(now())
|
||||||
updatedOn DateTime @updatedAt @default(now())
|
updatedOn DateTime @default(now()) @updatedAt
|
||||||
|
|
||||||
@@unique(fields: [id, creatorUid], name: "creator_uid_shortcode_unique")
|
@@unique(fields: [id, creatorUid], name: "creator_uid_shortcode_unique")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,6 +197,7 @@ model UserCollection {
|
|||||||
userUid String
|
userUid String
|
||||||
user User @relation(fields: [userUid], references: [uid], onDelete: Cascade)
|
user User @relation(fields: [userUid], references: [uid], onDelete: Cascade)
|
||||||
title String
|
title String
|
||||||
|
data Json?
|
||||||
orderIndex Int
|
orderIndex Int
|
||||||
type ReqType
|
type ReqType
|
||||||
createdOn DateTime @default(now()) @db.Timestamp(3)
|
createdOn DateTime @default(now()) @db.Timestamp(3)
|
||||||
|
|||||||
@@ -254,6 +254,13 @@ export const TEAM_COLL_INVALID_JSON = 'team_coll/invalid_json';
|
|||||||
*/
|
*/
|
||||||
export const TEAM_NOT_OWNER = 'team_coll/team_not_owner' as const;
|
export const TEAM_NOT_OWNER = 'team_coll/team_not_owner' as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Team Collection data is not valid
|
||||||
|
* (TeamCollectionService)
|
||||||
|
*/
|
||||||
|
export const TEAM_COLL_DATA_INVALID =
|
||||||
|
'team_coll/team_coll_data_invalid' as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tried to perform an action on a request that doesn't accept their member role level
|
* Tried to perform an action on a request that doesn't accept their member role level
|
||||||
* (GqlRequestTeamMemberGuard)
|
* (GqlRequestTeamMemberGuard)
|
||||||
@@ -585,6 +592,13 @@ export const USER_COLL_REORDERING_FAILED =
|
|||||||
export const USER_COLL_SAME_NEXT_COLL =
|
export const USER_COLL_SAME_NEXT_COLL =
|
||||||
'user_coll/user_collection_and_next_user_collection_are_same' as const;
|
'user_coll/user_collection_and_next_user_collection_are_same' as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The User Collection data is not valid
|
||||||
|
* (UserCollectionService)
|
||||||
|
*/
|
||||||
|
export const USER_COLL_DATA_INVALID =
|
||||||
|
'user_coll/user_coll_data_invalid' as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The User Collection does not belong to the logged-in user
|
* The User Collection does not belong to the logged-in user
|
||||||
* (UserCollectionService)
|
* (UserCollectionService)
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ import {
|
|||||||
} from 'src/team-request/team-request.model';
|
} from 'src/team-request/team-request.model';
|
||||||
import { TeamInvitation } from 'src/team-invitation/team-invitation.model';
|
import { TeamInvitation } from 'src/team-invitation/team-invitation.model';
|
||||||
import { InvitedUser } from '../admin/invited-user.model';
|
import { InvitedUser } from '../admin/invited-user.model';
|
||||||
import { UserCollection } from '@prisma/client';
|
|
||||||
import {
|
import {
|
||||||
|
UserCollection,
|
||||||
UserCollectionRemovedData,
|
UserCollectionRemovedData,
|
||||||
UserCollectionReorderData,
|
UserCollectionReorderData,
|
||||||
} from 'src/user-collection/user-collections.model';
|
} from 'src/user-collection/user-collections.model';
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ export class CreateRootTeamCollectionArgs {
|
|||||||
|
|
||||||
@Field({ name: 'title', description: 'Title of the new collection' })
|
@Field({ name: 'title', description: 'Title of the new collection' })
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
name: 'data',
|
||||||
|
description: 'JSON string representing the collection data',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
data: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ArgsType()
|
@ArgsType()
|
||||||
@@ -26,6 +33,13 @@ export class CreateChildTeamCollectionArgs {
|
|||||||
|
|
||||||
@Field({ name: 'childTitle', description: 'Title of the new collection' })
|
@Field({ name: 'childTitle', description: 'Title of the new collection' })
|
||||||
childTitle: string;
|
childTitle: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
name: 'data',
|
||||||
|
description: 'JSON string representing the collection data',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
data: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ArgsType()
|
@ArgsType()
|
||||||
@@ -33,12 +47,14 @@ export class RenameTeamCollectionArgs {
|
|||||||
@Field(() => ID, {
|
@Field(() => ID, {
|
||||||
name: 'collectionID',
|
name: 'collectionID',
|
||||||
description: 'ID of the collection',
|
description: 'ID of the collection',
|
||||||
|
deprecationReason: 'Switch to updateTeamCollection mutation instead',
|
||||||
})
|
})
|
||||||
collectionID: string;
|
collectionID: string;
|
||||||
|
|
||||||
@Field({
|
@Field({
|
||||||
name: 'newTitle',
|
name: 'newTitle',
|
||||||
description: 'The updated title of the collection',
|
description: 'The updated title of the collection',
|
||||||
|
deprecationReason: 'Switch to updateTeamCollection mutation instead',
|
||||||
})
|
})
|
||||||
newTitle: string;
|
newTitle: string;
|
||||||
}
|
}
|
||||||
@@ -98,3 +114,26 @@ export class ReplaceTeamCollectionArgs {
|
|||||||
})
|
})
|
||||||
parentCollectionID?: string;
|
parentCollectionID?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ArgsType()
|
||||||
|
export class UpdateTeamCollectionArgs {
|
||||||
|
@Field(() => ID, {
|
||||||
|
name: 'collectionID',
|
||||||
|
description: 'ID of the collection',
|
||||||
|
})
|
||||||
|
collectionID: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
name: 'newTitle',
|
||||||
|
description: 'The updated title of the collection',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
newTitle: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
name: 'data',
|
||||||
|
description: 'JSON string representing the collection data',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
data: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,12 +12,17 @@ export class TeamCollection {
|
|||||||
})
|
})
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
description: 'JSON string representing the collection data',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
data: string;
|
||||||
|
|
||||||
@Field(() => ID, {
|
@Field(() => ID, {
|
||||||
description: 'ID of the collection',
|
description: 'ID of the collection',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
parentID: string;
|
parentID: string;
|
||||||
teamID: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
MoveTeamCollectionArgs,
|
MoveTeamCollectionArgs,
|
||||||
RenameTeamCollectionArgs,
|
RenameTeamCollectionArgs,
|
||||||
ReplaceTeamCollectionArgs,
|
ReplaceTeamCollectionArgs,
|
||||||
|
UpdateTeamCollectionArgs,
|
||||||
UpdateTeamCollectionOrderArgs,
|
UpdateTeamCollectionOrderArgs,
|
||||||
} from './input-type.args';
|
} from './input-type.args';
|
||||||
import * as E from 'fp-ts/Either';
|
import * as E from 'fp-ts/Either';
|
||||||
@@ -141,7 +142,14 @@ export class TeamCollectionResolver {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (E.isLeft(teamCollections)) throwErr(teamCollections.left);
|
if (E.isLeft(teamCollections)) throwErr(teamCollections.left);
|
||||||
return teamCollections.right;
|
return <TeamCollection>{
|
||||||
|
id: teamCollections.right.id,
|
||||||
|
title: teamCollections.right.title,
|
||||||
|
parentID: teamCollections.right.parentID,
|
||||||
|
data: !teamCollections.right.data
|
||||||
|
? null
|
||||||
|
: JSON.stringify(teamCollections.right.data),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mutations
|
// Mutations
|
||||||
@@ -155,6 +163,7 @@ export class TeamCollectionResolver {
|
|||||||
const teamCollection = await this.teamCollectionService.createCollection(
|
const teamCollection = await this.teamCollectionService.createCollection(
|
||||||
args.teamID,
|
args.teamID,
|
||||||
args.title,
|
args.title,
|
||||||
|
args.data,
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -230,6 +239,7 @@ export class TeamCollectionResolver {
|
|||||||
const teamCollection = await this.teamCollectionService.createCollection(
|
const teamCollection = await this.teamCollectionService.createCollection(
|
||||||
team.right.id,
|
team.right.id,
|
||||||
args.childTitle,
|
args.childTitle,
|
||||||
|
args.data,
|
||||||
args.collectionID,
|
args.collectionID,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -239,6 +249,7 @@ export class TeamCollectionResolver {
|
|||||||
|
|
||||||
@Mutation(() => TeamCollection, {
|
@Mutation(() => TeamCollection, {
|
||||||
description: 'Rename a collection',
|
description: 'Rename a collection',
|
||||||
|
deprecationReason: 'Switch to updateTeamCollection mutation instead',
|
||||||
})
|
})
|
||||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||||
@@ -303,6 +314,23 @@ export class TeamCollectionResolver {
|
|||||||
return request.right;
|
return request.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mutation(() => TeamCollection, {
|
||||||
|
description: 'Update Team Collection details',
|
||||||
|
})
|
||||||
|
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||||
|
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||||
|
async updateTeamCollection(@Args() args: UpdateTeamCollectionArgs) {
|
||||||
|
const updatedTeamCollection =
|
||||||
|
await this.teamCollectionService.updateTeamCollection(
|
||||||
|
args.collectionID,
|
||||||
|
args.data,
|
||||||
|
args.newTitle,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (E.isLeft(updatedTeamCollection)) throwErr(updatedTeamCollection.left);
|
||||||
|
return updatedTeamCollection.right;
|
||||||
|
}
|
||||||
|
|
||||||
// Subscriptions
|
// Subscriptions
|
||||||
|
|
||||||
@Subscription(() => TeamCollection, {
|
@Subscription(() => TeamCollection, {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Team, TeamCollection as DBTeamCollection } from '@prisma/client';
|
import { Team, TeamCollection as DBTeamCollection } from '@prisma/client';
|
||||||
import { mockDeep, mockReset } from 'jest-mock-extended';
|
import { mockDeep, mockReset } from 'jest-mock-extended';
|
||||||
import {
|
import {
|
||||||
|
TEAM_COLL_DATA_INVALID,
|
||||||
TEAM_COLL_DEST_SAME,
|
TEAM_COLL_DEST_SAME,
|
||||||
TEAM_COLL_INVALID_JSON,
|
TEAM_COLL_INVALID_JSON,
|
||||||
TEAM_COLL_IS_PARENT_COLL,
|
TEAM_COLL_IS_PARENT_COLL,
|
||||||
@@ -17,6 +18,7 @@ import { PrismaService } from 'src/prisma/prisma.service';
|
|||||||
import { PubSubService } from 'src/pubsub/pubsub.service';
|
import { PubSubService } from 'src/pubsub/pubsub.service';
|
||||||
import { AuthUser } from 'src/types/AuthUser';
|
import { AuthUser } from 'src/types/AuthUser';
|
||||||
import { TeamCollectionService } from './team-collection.service';
|
import { TeamCollectionService } from './team-collection.service';
|
||||||
|
import { TeamCollection } from './team-collection.model';
|
||||||
|
|
||||||
const mockPrisma = mockDeep<PrismaService>();
|
const mockPrisma = mockDeep<PrismaService>();
|
||||||
const mockPubSub = mockDeep<PubSubService>();
|
const mockPubSub = mockDeep<PubSubService>();
|
||||||
@@ -51,35 +53,60 @@ const rootTeamCollection: DBTeamCollection = {
|
|||||||
id: '123',
|
id: '123',
|
||||||
orderIndex: 1,
|
orderIndex: 1,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
|
data: {},
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rootTeamCollectionsCasted: TeamCollection = {
|
||||||
|
id: rootTeamCollection.id,
|
||||||
|
title: rootTeamCollection.title,
|
||||||
|
parentID: rootTeamCollection.parentID,
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
};
|
||||||
|
|
||||||
const rootTeamCollection_2: DBTeamCollection = {
|
const rootTeamCollection_2: DBTeamCollection = {
|
||||||
id: 'erv',
|
id: 'erv',
|
||||||
orderIndex: 2,
|
orderIndex: 2,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
|
data: {},
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rootTeamCollection_2Casted: TeamCollection = {
|
||||||
|
id: 'erv',
|
||||||
|
parentID: null,
|
||||||
|
data: JSON.stringify(rootTeamCollection_2.data),
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
};
|
||||||
|
|
||||||
const childTeamCollection: DBTeamCollection = {
|
const childTeamCollection: DBTeamCollection = {
|
||||||
id: 'rfe',
|
id: 'rfe',
|
||||||
orderIndex: 1,
|
orderIndex: 1,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
|
data: {},
|
||||||
title: 'Child Collection 1',
|
title: 'Child Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const childTeamCollectionCasted: TeamCollection = {
|
||||||
|
id: 'rfe',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
data: JSON.stringify(childTeamCollection.data),
|
||||||
|
title: 'Child Collection 1',
|
||||||
|
};
|
||||||
|
|
||||||
const childTeamCollection_2: DBTeamCollection = {
|
const childTeamCollection_2: DBTeamCollection = {
|
||||||
id: 'bgdz',
|
id: 'bgdz',
|
||||||
orderIndex: 1,
|
orderIndex: 1,
|
||||||
|
data: {},
|
||||||
parentID: rootTeamCollection_2.id,
|
parentID: rootTeamCollection_2.id,
|
||||||
title: 'Child Collection 1',
|
title: 'Child Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
@@ -87,11 +114,20 @@ const childTeamCollection_2: DBTeamCollection = {
|
|||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const childTeamCollection_2Casted: TeamCollection = {
|
||||||
|
id: 'bgdz',
|
||||||
|
data: JSON.stringify(childTeamCollection_2.data),
|
||||||
|
parentID: rootTeamCollection_2.id,
|
||||||
|
title: 'Child Collection 1',
|
||||||
|
};
|
||||||
|
|
||||||
const rootTeamCollectionList: DBTeamCollection[] = [
|
const rootTeamCollectionList: DBTeamCollection[] = [
|
||||||
{
|
{
|
||||||
id: 'fdv',
|
id: 'fdv',
|
||||||
orderIndex: 1,
|
orderIndex: 1,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
|
data: {},
|
||||||
|
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -102,6 +138,8 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
orderIndex: 2,
|
orderIndex: 2,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
|
data: {},
|
||||||
|
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
@@ -111,6 +149,8 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
orderIndex: 3,
|
orderIndex: 3,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
|
data: {},
|
||||||
|
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
@@ -119,6 +159,8 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
id: 'bre3',
|
id: 'bre3',
|
||||||
orderIndex: 4,
|
orderIndex: 4,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
|
data: {},
|
||||||
|
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -129,6 +171,8 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
orderIndex: 5,
|
orderIndex: 5,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
|
data: {},
|
||||||
|
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
@@ -139,6 +183,8 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
parentID: null,
|
parentID: null,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
|
data: {},
|
||||||
|
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
},
|
},
|
||||||
@@ -148,6 +194,8 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
parentID: null,
|
parentID: null,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
|
data: {},
|
||||||
|
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
},
|
},
|
||||||
@@ -156,6 +204,7 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
orderIndex: 8,
|
orderIndex: 8,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
|
data: {},
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
@@ -165,6 +214,7 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
orderIndex: 9,
|
orderIndex: 9,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
|
data: {},
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
@@ -175,17 +225,83 @@ const rootTeamCollectionList: DBTeamCollection[] = [
|
|||||||
parentID: null,
|
parentID: null,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
|
data: {},
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const rootTeamCollectionListCasted: TeamCollection[] = [
|
||||||
|
{
|
||||||
|
id: 'fdv',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'fbbg',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'fgbfg',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'bre3',
|
||||||
|
parentID: null,
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'hghgf',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '123',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '54tyh',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '234re',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '34rtg',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '45tgh',
|
||||||
|
parentID: null,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify(rootTeamCollection.data),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const childTeamCollectionList: DBTeamCollection[] = [
|
const childTeamCollectionList: DBTeamCollection[] = [
|
||||||
{
|
{
|
||||||
id: '123',
|
id: '123',
|
||||||
orderIndex: 1,
|
orderIndex: 1,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
|
data: {},
|
||||||
|
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
@@ -195,6 +311,8 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
orderIndex: 2,
|
orderIndex: 2,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
|
data: {},
|
||||||
|
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
@@ -204,6 +322,8 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
orderIndex: 3,
|
orderIndex: 3,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
|
data: {},
|
||||||
|
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
updatedOn: currentTime,
|
updatedOn: currentTime,
|
||||||
@@ -212,6 +332,8 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
id: '567',
|
id: '567',
|
||||||
orderIndex: 4,
|
orderIndex: 4,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
|
data: {},
|
||||||
|
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -221,6 +343,8 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
id: '123',
|
id: '123',
|
||||||
orderIndex: 5,
|
orderIndex: 5,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
|
data: {},
|
||||||
|
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -230,6 +354,8 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
id: '678',
|
id: '678',
|
||||||
orderIndex: 6,
|
orderIndex: 6,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
|
data: {},
|
||||||
|
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -239,6 +365,8 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
id: '789',
|
id: '789',
|
||||||
orderIndex: 7,
|
orderIndex: 7,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
|
data: {},
|
||||||
|
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -248,6 +376,8 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
id: '890',
|
id: '890',
|
||||||
orderIndex: 8,
|
orderIndex: 8,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
|
data: {},
|
||||||
|
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -257,6 +387,7 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
id: '012',
|
id: '012',
|
||||||
orderIndex: 9,
|
orderIndex: 9,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
|
data: {},
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -266,6 +397,8 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
id: '0bhu',
|
id: '0bhu',
|
||||||
orderIndex: 10,
|
orderIndex: 10,
|
||||||
parentID: rootTeamCollection.id,
|
parentID: rootTeamCollection.id,
|
||||||
|
data: {},
|
||||||
|
|
||||||
title: 'Root Collection 1',
|
title: 'Root Collection 1',
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
createdOn: currentTime,
|
createdOn: currentTime,
|
||||||
@@ -273,6 +406,75 @@ const childTeamCollectionList: DBTeamCollection[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const childTeamCollectionListCasted: TeamCollection[] = [
|
||||||
|
{
|
||||||
|
id: '123',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '345',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '456',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '567',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '123',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '678',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '789',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '890',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '012',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '0bhu',
|
||||||
|
parentID: rootTeamCollection.id,
|
||||||
|
data: JSON.stringify({}),
|
||||||
|
|
||||||
|
title: 'Root Collection 1',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockReset(mockPrisma);
|
mockReset(mockPrisma);
|
||||||
mockPubSub.publish.mockClear();
|
mockPubSub.publish.mockClear();
|
||||||
@@ -311,7 +513,7 @@ describe('getParentOfCollection', () => {
|
|||||||
const result = await teamCollectionService.getParentOfCollection(
|
const result = await teamCollectionService.getParentOfCollection(
|
||||||
childTeamCollection.id,
|
childTeamCollection.id,
|
||||||
);
|
);
|
||||||
expect(result).toEqual(rootTeamCollection);
|
expect(result).toEqual(rootTeamCollectionsCasted);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return null successfully for a root collection with valid collectionID', async () => {
|
test('should return null successfully for a root collection with valid collectionID', async () => {
|
||||||
@@ -347,7 +549,7 @@ describe('getChildrenOfCollection', () => {
|
|||||||
null,
|
null,
|
||||||
10,
|
10,
|
||||||
);
|
);
|
||||||
expect(result).toEqual(childTeamCollectionList);
|
expect(result).toEqual(childTeamCollectionListCasted);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return a list of 3 child collections successfully with cursor being equal to the 7th item in the list', async () => {
|
test('should return a list of 3 child collections successfully with cursor being equal to the 7th item in the list', async () => {
|
||||||
@@ -363,9 +565,9 @@ describe('getChildrenOfCollection', () => {
|
|||||||
10,
|
10,
|
||||||
);
|
);
|
||||||
expect(result).toEqual([
|
expect(result).toEqual([
|
||||||
{ ...childTeamCollectionList[7] },
|
{ ...childTeamCollectionListCasted[7] },
|
||||||
{ ...childTeamCollectionList[8] },
|
{ ...childTeamCollectionListCasted[8] },
|
||||||
{ ...childTeamCollectionList[9] },
|
{ ...childTeamCollectionListCasted[9] },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -392,7 +594,7 @@ describe('getTeamRootCollections', () => {
|
|||||||
null,
|
null,
|
||||||
10,
|
10,
|
||||||
);
|
);
|
||||||
expect(result).toEqual(rootTeamCollectionList);
|
expect(result).toEqual(rootTeamCollectionListCasted);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return a list of 3 root collections successfully with cursor being equal to the 7th item in the list', async () => {
|
test('should return a list of 3 root collections successfully with cursor being equal to the 7th item in the list', async () => {
|
||||||
@@ -408,9 +610,9 @@ describe('getTeamRootCollections', () => {
|
|||||||
10,
|
10,
|
||||||
);
|
);
|
||||||
expect(result).toEqual([
|
expect(result).toEqual([
|
||||||
{ ...rootTeamCollectionList[7] },
|
{ ...rootTeamCollectionListCasted[7] },
|
||||||
{ ...rootTeamCollectionList[8] },
|
{ ...rootTeamCollectionListCasted[8] },
|
||||||
{ ...rootTeamCollectionList[9] },
|
{ ...rootTeamCollectionListCasted[9] },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -464,6 +666,7 @@ describe('createCollection', () => {
|
|||||||
const result = await teamCollectionService.createCollection(
|
const result = await teamCollectionService.createCollection(
|
||||||
rootTeamCollection.teamID,
|
rootTeamCollection.teamID,
|
||||||
'ab',
|
'ab',
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
rootTeamCollection.id,
|
rootTeamCollection.id,
|
||||||
);
|
);
|
||||||
expect(result).toEqualLeft(TEAM_COLL_SHORT_TITLE);
|
expect(result).toEqualLeft(TEAM_COLL_SHORT_TITLE);
|
||||||
@@ -478,11 +681,27 @@ describe('createCollection', () => {
|
|||||||
const result = await teamCollectionService.createCollection(
|
const result = await teamCollectionService.createCollection(
|
||||||
rootTeamCollection.teamID,
|
rootTeamCollection.teamID,
|
||||||
'abcd',
|
'abcd',
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
rootTeamCollection.id,
|
rootTeamCollection.id,
|
||||||
);
|
);
|
||||||
expect(result).toEqualLeft(TEAM_NOT_OWNER);
|
expect(result).toEqualLeft(TEAM_NOT_OWNER);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should throw TEAM_COLL_DATA_INVALID when parent TeamCollection does not belong to the team', async () => {
|
||||||
|
// isOwnerCheck
|
||||||
|
mockPrisma.teamCollection.findFirstOrThrow.mockResolvedValueOnce(
|
||||||
|
rootTeamCollection,
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await teamCollectionService.createCollection(
|
||||||
|
rootTeamCollection.teamID,
|
||||||
|
'abcd',
|
||||||
|
'{',
|
||||||
|
rootTeamCollection.id,
|
||||||
|
);
|
||||||
|
expect(result).toEqualLeft(TEAM_COLL_DATA_INVALID);
|
||||||
|
});
|
||||||
|
|
||||||
test('should successfully create a new root TeamCollection with valid inputs', async () => {
|
test('should successfully create a new root TeamCollection with valid inputs', async () => {
|
||||||
// isOwnerCheck
|
// isOwnerCheck
|
||||||
mockPrisma.teamCollection.findFirstOrThrow.mockResolvedValueOnce(
|
mockPrisma.teamCollection.findFirstOrThrow.mockResolvedValueOnce(
|
||||||
@@ -496,9 +715,10 @@ describe('createCollection', () => {
|
|||||||
const result = await teamCollectionService.createCollection(
|
const result = await teamCollectionService.createCollection(
|
||||||
rootTeamCollection.teamID,
|
rootTeamCollection.teamID,
|
||||||
'abcdefg',
|
'abcdefg',
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
rootTeamCollection.id,
|
rootTeamCollection.id,
|
||||||
);
|
);
|
||||||
expect(result).toEqualRight(rootTeamCollection);
|
expect(result).toEqualRight(rootTeamCollectionsCasted);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully create a new child TeamCollection with valid inputs', async () => {
|
test('should successfully create a new child TeamCollection with valid inputs', async () => {
|
||||||
@@ -514,9 +734,10 @@ describe('createCollection', () => {
|
|||||||
const result = await teamCollectionService.createCollection(
|
const result = await teamCollectionService.createCollection(
|
||||||
childTeamCollection.teamID,
|
childTeamCollection.teamID,
|
||||||
childTeamCollection.title,
|
childTeamCollection.title,
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
rootTeamCollection.id,
|
rootTeamCollection.id,
|
||||||
);
|
);
|
||||||
expect(result).toEqualRight(childTeamCollection);
|
expect(result).toEqualRight(childTeamCollectionCasted);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should send pubsub message to "team_coll/<teamID>/coll_added" if child TeamCollection is created successfully', async () => {
|
test('should send pubsub message to "team_coll/<teamID>/coll_added" if child TeamCollection is created successfully', async () => {
|
||||||
@@ -532,11 +753,13 @@ describe('createCollection', () => {
|
|||||||
const result = await teamCollectionService.createCollection(
|
const result = await teamCollectionService.createCollection(
|
||||||
childTeamCollection.teamID,
|
childTeamCollection.teamID,
|
||||||
childTeamCollection.title,
|
childTeamCollection.title,
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
|
|
||||||
rootTeamCollection.id,
|
rootTeamCollection.id,
|
||||||
);
|
);
|
||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${childTeamCollection.teamID}/coll_added`,
|
`team_coll/${childTeamCollection.teamID}/coll_added`,
|
||||||
childTeamCollection,
|
childTeamCollectionCasted,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -553,11 +776,13 @@ describe('createCollection', () => {
|
|||||||
const result = await teamCollectionService.createCollection(
|
const result = await teamCollectionService.createCollection(
|
||||||
rootTeamCollection.teamID,
|
rootTeamCollection.teamID,
|
||||||
'abcdefg',
|
'abcdefg',
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
|
|
||||||
rootTeamCollection.id,
|
rootTeamCollection.id,
|
||||||
);
|
);
|
||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${rootTeamCollection.teamID}/coll_added`,
|
`team_coll/${rootTeamCollection.teamID}/coll_added`,
|
||||||
rootTeamCollection,
|
rootTeamCollectionsCasted,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -587,7 +812,7 @@ describe('renameCollection', () => {
|
|||||||
'NewTitle',
|
'NewTitle',
|
||||||
);
|
);
|
||||||
expect(result).toEqualRight({
|
expect(result).toEqualRight({
|
||||||
...rootTeamCollection,
|
...rootTeamCollectionsCasted,
|
||||||
title: 'NewTitle',
|
title: 'NewTitle',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -625,7 +850,7 @@ describe('renameCollection', () => {
|
|||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${rootTeamCollection.teamID}/coll_updated`,
|
`team_coll/${rootTeamCollection.teamID}/coll_updated`,
|
||||||
{
|
{
|
||||||
...rootTeamCollection,
|
...rootTeamCollectionsCasted,
|
||||||
title: 'NewTitle',
|
title: 'NewTitle',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -832,9 +1057,8 @@ describe('moveCollection', () => {
|
|||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
expect(result).toEqualRight({
|
expect(result).toEqualRight({
|
||||||
...childTeamCollection,
|
...childTeamCollectionCasted,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
orderIndex: 2,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -890,9 +1114,8 @@ describe('moveCollection', () => {
|
|||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${childTeamCollection.teamID}/coll_moved`,
|
`team_coll/${childTeamCollection.teamID}/coll_moved`,
|
||||||
{
|
{
|
||||||
...childTeamCollection,
|
...childTeamCollectionCasted,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
orderIndex: 2,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -931,9 +1154,8 @@ describe('moveCollection', () => {
|
|||||||
childTeamCollection_2.id,
|
childTeamCollection_2.id,
|
||||||
);
|
);
|
||||||
expect(result).toEqualRight({
|
expect(result).toEqualRight({
|
||||||
...rootTeamCollection,
|
...rootTeamCollectionsCasted,
|
||||||
parentID: childTeamCollection_2.id,
|
parentID: childTeamCollection_2Casted.id,
|
||||||
orderIndex: 1,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -973,9 +1195,8 @@ describe('moveCollection', () => {
|
|||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${childTeamCollection_2.teamID}/coll_moved`,
|
`team_coll/${childTeamCollection_2.teamID}/coll_moved`,
|
||||||
{
|
{
|
||||||
...rootTeamCollection,
|
...rootTeamCollectionsCasted,
|
||||||
parentID: childTeamCollection_2.id,
|
parentID: childTeamCollection_2Casted.id,
|
||||||
orderIndex: 1,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -1014,9 +1235,8 @@ describe('moveCollection', () => {
|
|||||||
childTeamCollection_2.id,
|
childTeamCollection_2.id,
|
||||||
);
|
);
|
||||||
expect(result).toEqualRight({
|
expect(result).toEqualRight({
|
||||||
...childTeamCollection,
|
...childTeamCollectionCasted,
|
||||||
parentID: childTeamCollection_2.id,
|
parentID: childTeamCollection_2Casted.id,
|
||||||
orderIndex: 1,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1056,9 +1276,8 @@ describe('moveCollection', () => {
|
|||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${childTeamCollection.teamID}/coll_moved`,
|
`team_coll/${childTeamCollection.teamID}/coll_moved`,
|
||||||
{
|
{
|
||||||
...childTeamCollection,
|
...childTeamCollectionCasted,
|
||||||
parentID: childTeamCollection_2.id,
|
parentID: childTeamCollection_2Casted.id,
|
||||||
orderIndex: 1,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -1154,7 +1373,7 @@ describe('updateCollectionOrder', () => {
|
|||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${childTeamCollectionList[4].teamID}/coll_order_updated`,
|
`team_coll/${childTeamCollectionList[4].teamID}/coll_order_updated`,
|
||||||
{
|
{
|
||||||
collection: rootTeamCollectionList[4],
|
collection: rootTeamCollectionListCasted[4],
|
||||||
nextCollection: null,
|
nextCollection: null,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -1235,8 +1454,8 @@ describe('updateCollectionOrder', () => {
|
|||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${childTeamCollectionList[2].teamID}/coll_order_updated`,
|
`team_coll/${childTeamCollectionList[2].teamID}/coll_order_updated`,
|
||||||
{
|
{
|
||||||
collection: childTeamCollectionList[4],
|
collection: childTeamCollectionListCasted[4],
|
||||||
nextCollection: childTeamCollectionList[2],
|
nextCollection: childTeamCollectionListCasted[2],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -1302,7 +1521,7 @@ describe('importCollectionsFromJSON', () => {
|
|||||||
);
|
);
|
||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${rootTeamCollection.teamID}/coll_added`,
|
`team_coll/${rootTeamCollection.teamID}/coll_added`,
|
||||||
rootTeamCollection,
|
rootTeamCollectionsCasted,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1421,7 +1640,7 @@ describe('replaceCollectionsWithJSON', () => {
|
|||||||
);
|
);
|
||||||
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
`team_coll/${rootTeamCollection.teamID}/coll_added`,
|
`team_coll/${rootTeamCollection.teamID}/coll_added`,
|
||||||
rootTeamCollection,
|
rootTeamCollectionsCasted,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1458,4 +1677,64 @@ describe('totalCollectionsInTeam', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('updateTeamCollection', () => {
|
||||||
|
test('should throw TEAM_COLL_SHORT_TITLE if title is invalid', async () => {
|
||||||
|
const result = await teamCollectionService.updateTeamCollection(
|
||||||
|
rootTeamCollection.id,
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
|
'de',
|
||||||
|
);
|
||||||
|
expect(result).toEqualLeft(TEAM_COLL_SHORT_TITLE);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should throw TEAM_COLL_DATA_INVALID is collection data is invalid', async () => {
|
||||||
|
const result = await teamCollectionService.updateTeamCollection(
|
||||||
|
rootTeamCollection.id,
|
||||||
|
'{',
|
||||||
|
rootTeamCollection.title,
|
||||||
|
);
|
||||||
|
expect(result).toEqualLeft(TEAM_COLL_DATA_INVALID);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should throw TEAM_COLL_NOT_FOUND is collectionID is invalid', async () => {
|
||||||
|
mockPrisma.teamCollection.update.mockRejectedValueOnce('RecordNotFound');
|
||||||
|
|
||||||
|
const result = await teamCollectionService.updateTeamCollection(
|
||||||
|
'invalid_id',
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
|
rootTeamCollection.title,
|
||||||
|
);
|
||||||
|
expect(result).toEqualLeft(TEAM_COLL_NOT_FOUND);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should successfully update a collection', async () => {
|
||||||
|
mockPrisma.teamCollection.update.mockResolvedValueOnce(rootTeamCollection);
|
||||||
|
|
||||||
|
const result = await teamCollectionService.updateTeamCollection(
|
||||||
|
rootTeamCollection.id,
|
||||||
|
JSON.stringify({ foo: 'bar' }),
|
||||||
|
'new_title',
|
||||||
|
);
|
||||||
|
expect(result).toEqualRight({
|
||||||
|
data: JSON.stringify({ foo: 'bar' }),
|
||||||
|
title: 'new_title',
|
||||||
|
...rootTeamCollectionsCasted,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should send pubsub message to "team_coll/<teamID>/coll_updated" if TeamCollection is updated successfully', async () => {
|
||||||
|
mockPrisma.teamCollection.update.mockResolvedValueOnce(rootTeamCollection);
|
||||||
|
|
||||||
|
const result = await teamCollectionService.updateTeamCollection(
|
||||||
|
rootTeamCollection.id,
|
||||||
|
JSON.stringify(rootTeamCollection.data),
|
||||||
|
rootTeamCollection.title,
|
||||||
|
);
|
||||||
|
expect(mockPubSub.publish).toHaveBeenCalledWith(
|
||||||
|
`team_coll/${rootTeamCollection.teamID}/coll_updated`,
|
||||||
|
rootTeamCollectionsCasted,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
//ToDo: write test cases for exportCollectionsToJSON
|
//ToDo: write test cases for exportCollectionsToJSON
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
TEAM_COLL_IS_PARENT_COLL,
|
TEAM_COLL_IS_PARENT_COLL,
|
||||||
TEAM_COL_SAME_NEXT_COLL,
|
TEAM_COL_SAME_NEXT_COLL,
|
||||||
TEAM_COL_REORDERING_FAILED,
|
TEAM_COL_REORDERING_FAILED,
|
||||||
|
TEAM_COLL_DATA_INVALID,
|
||||||
} from '../errors';
|
} from '../errors';
|
||||||
import { PubSubService } from '../pubsub/pubsub.service';
|
import { PubSubService } from '../pubsub/pubsub.service';
|
||||||
import { isValidLength } from 'src/utils';
|
import { isValidLength } from 'src/utils';
|
||||||
@@ -69,6 +70,7 @@ export class TeamCollectionService {
|
|||||||
this.generatePrismaQueryObjForFBCollFolder(f, teamID, index + 1),
|
this.generatePrismaQueryObjForFBCollFolder(f, teamID, index + 1),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
data: folder.data ?? undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +120,7 @@ export class TeamCollectionService {
|
|||||||
name: collection.right.title,
|
name: collection.right.title,
|
||||||
folders: childrenCollectionObjects,
|
folders: childrenCollectionObjects,
|
||||||
requests: requests.map((x) => x.request),
|
requests: requests.map((x) => x.request),
|
||||||
|
data: JSON.stringify(collection.right.data),
|
||||||
};
|
};
|
||||||
|
|
||||||
return E.right(result);
|
return E.right(result);
|
||||||
@@ -198,8 +201,11 @@ export class TeamCollectionService {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
teamCollections.forEach((x) =>
|
teamCollections.forEach((collection) =>
|
||||||
this.pubsub.publish(`team_coll/${destTeamID}/coll_added`, x),
|
this.pubsub.publish(
|
||||||
|
`team_coll/${destTeamID}/coll_added`,
|
||||||
|
this.cast(collection),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return E.right(true);
|
return E.right(true);
|
||||||
@@ -268,8 +274,11 @@ export class TeamCollectionService {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
teamCollections.forEach((x) =>
|
teamCollections.forEach((collections) =>
|
||||||
this.pubsub.publish(`team_coll/${destTeamID}/coll_added`, x),
|
this.pubsub.publish(
|
||||||
|
`team_coll/${destTeamID}/coll_added`,
|
||||||
|
this.cast(collections),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return E.right(true);
|
return E.right(true);
|
||||||
@@ -277,11 +286,17 @@ export class TeamCollectionService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Typecast a database TeamCollection to a TeamCollection model
|
* Typecast a database TeamCollection to a TeamCollection model
|
||||||
|
*
|
||||||
* @param teamCollection database TeamCollection
|
* @param teamCollection database TeamCollection
|
||||||
* @returns TeamCollection model
|
* @returns TeamCollection model
|
||||||
*/
|
*/
|
||||||
private cast(teamCollection: DBTeamCollection): TeamCollection {
|
private cast(teamCollection: DBTeamCollection): TeamCollection {
|
||||||
return <TeamCollection>{ ...teamCollection };
|
return <TeamCollection>{
|
||||||
|
id: teamCollection.id,
|
||||||
|
title: teamCollection.title,
|
||||||
|
parentID: teamCollection.parentID,
|
||||||
|
data: !teamCollection.data ? null : JSON.stringify(teamCollection.data),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -324,7 +339,7 @@ export class TeamCollectionService {
|
|||||||
});
|
});
|
||||||
if (!teamCollection) return null;
|
if (!teamCollection) return null;
|
||||||
|
|
||||||
return teamCollection.parent;
|
return !teamCollection.parent ? null : this.cast(teamCollection.parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -335,12 +350,12 @@ export class TeamCollectionService {
|
|||||||
* @param take Number of items we want returned
|
* @param take Number of items we want returned
|
||||||
* @returns A list of child collections
|
* @returns A list of child collections
|
||||||
*/
|
*/
|
||||||
getChildrenOfCollection(
|
async getChildrenOfCollection(
|
||||||
collectionID: string,
|
collectionID: string,
|
||||||
cursor: string | null,
|
cursor: string | null,
|
||||||
take: number,
|
take: number,
|
||||||
) {
|
) {
|
||||||
return this.prisma.teamCollection.findMany({
|
const res = await this.prisma.teamCollection.findMany({
|
||||||
where: {
|
where: {
|
||||||
parentID: collectionID,
|
parentID: collectionID,
|
||||||
},
|
},
|
||||||
@@ -351,6 +366,12 @@ export class TeamCollectionService {
|
|||||||
skip: cursor ? 1 : 0,
|
skip: cursor ? 1 : 0,
|
||||||
cursor: cursor ? { id: cursor } : undefined,
|
cursor: cursor ? { id: cursor } : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const childCollections = res.map((teamCollection) =>
|
||||||
|
this.cast(teamCollection),
|
||||||
|
);
|
||||||
|
|
||||||
|
return childCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -366,7 +387,7 @@ export class TeamCollectionService {
|
|||||||
cursor: string | null,
|
cursor: string | null,
|
||||||
take: number,
|
take: number,
|
||||||
) {
|
) {
|
||||||
return this.prisma.teamCollection.findMany({
|
const res = await this.prisma.teamCollection.findMany({
|
||||||
where: {
|
where: {
|
||||||
teamID,
|
teamID,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
@@ -378,6 +399,12 @@ export class TeamCollectionService {
|
|||||||
skip: cursor ? 1 : 0,
|
skip: cursor ? 1 : 0,
|
||||||
cursor: cursor ? { id: cursor } : undefined,
|
cursor: cursor ? { id: cursor } : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const teamCollections = res.map((teamCollection) =>
|
||||||
|
this.cast(teamCollection),
|
||||||
|
);
|
||||||
|
|
||||||
|
return teamCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -470,6 +497,7 @@ export class TeamCollectionService {
|
|||||||
async createCollection(
|
async createCollection(
|
||||||
teamID: string,
|
teamID: string,
|
||||||
title: string,
|
title: string,
|
||||||
|
data: string | null = null,
|
||||||
parentTeamCollectionID: string | null,
|
parentTeamCollectionID: string | null,
|
||||||
) {
|
) {
|
||||||
const isTitleValid = isValidLength(title, this.TITLE_LENGTH);
|
const isTitleValid = isValidLength(title, this.TITLE_LENGTH);
|
||||||
@@ -481,6 +509,13 @@ export class TeamCollectionService {
|
|||||||
if (O.isNone(isOwner)) return E.left(TEAM_NOT_OWNER);
|
if (O.isNone(isOwner)) return E.left(TEAM_NOT_OWNER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data === '') return E.left(TEAM_COLL_DATA_INVALID);
|
||||||
|
if (data) {
|
||||||
|
const jsonReq = stringToJson(data);
|
||||||
|
if (E.isLeft(jsonReq)) return E.left(TEAM_COLL_DATA_INVALID);
|
||||||
|
data = jsonReq.right;
|
||||||
|
}
|
||||||
|
|
||||||
const isParent = parentTeamCollectionID
|
const isParent = parentTeamCollectionID
|
||||||
? {
|
? {
|
||||||
connect: {
|
connect: {
|
||||||
@@ -498,18 +533,23 @@ export class TeamCollectionService {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parent: isParent,
|
parent: isParent,
|
||||||
|
data: data ?? undefined,
|
||||||
orderIndex: !parentTeamCollectionID
|
orderIndex: !parentTeamCollectionID
|
||||||
? (await this.getRootCollectionsCount(teamID)) + 1
|
? (await this.getRootCollectionsCount(teamID)) + 1
|
||||||
: (await this.getChildCollectionsCount(parentTeamCollectionID)) + 1,
|
: (await this.getChildCollectionsCount(parentTeamCollectionID)) + 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.pubsub.publish(`team_coll/${teamID}/coll_added`, teamCollection);
|
this.pubsub.publish(
|
||||||
|
`team_coll/${teamID}/coll_added`,
|
||||||
|
this.cast(teamCollection),
|
||||||
|
);
|
||||||
|
|
||||||
return E.right(this.cast(teamCollection));
|
return E.right(this.cast(teamCollection));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated Use updateTeamCollection method instead
|
||||||
* Update the title of a TeamCollection
|
* Update the title of a TeamCollection
|
||||||
*
|
*
|
||||||
* @param collectionID The Collection ID
|
* @param collectionID The Collection ID
|
||||||
@@ -532,10 +572,10 @@ export class TeamCollectionService {
|
|||||||
|
|
||||||
this.pubsub.publish(
|
this.pubsub.publish(
|
||||||
`team_coll/${updatedTeamCollection.teamID}/coll_updated`,
|
`team_coll/${updatedTeamCollection.teamID}/coll_updated`,
|
||||||
updatedTeamCollection,
|
this.cast(updatedTeamCollection),
|
||||||
);
|
);
|
||||||
|
|
||||||
return E.right(updatedTeamCollection);
|
return E.right(this.cast(updatedTeamCollection));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return E.left(TEAM_COLL_NOT_FOUND);
|
return E.left(TEAM_COLL_NOT_FOUND);
|
||||||
}
|
}
|
||||||
@@ -694,8 +734,8 @@ export class TeamCollectionService {
|
|||||||
* @returns An Option of boolean, is parent or not
|
* @returns An Option of boolean, is parent or not
|
||||||
*/
|
*/
|
||||||
private async isParent(
|
private async isParent(
|
||||||
collection: TeamCollection,
|
collection: DBTeamCollection,
|
||||||
destCollection: TeamCollection,
|
destCollection: DBTeamCollection,
|
||||||
): Promise<O.Option<boolean>> {
|
): Promise<O.Option<boolean>> {
|
||||||
//* Recursively check if collection is a parent by going up the tree of child-parent collections until we reach a root collection i.e parentID === null
|
//* Recursively check if collection is a parent by going up the tree of child-parent collections until we reach a root collection i.e parentID === null
|
||||||
//* Valid condition, isParent returns false
|
//* Valid condition, isParent returns false
|
||||||
@@ -971,4 +1011,49 @@ export class TeamCollectionService {
|
|||||||
const teamCollectionsCount = this.prisma.teamCollection.count();
|
const teamCollectionsCount = this.prisma.teamCollection.count();
|
||||||
return teamCollectionsCount;
|
return teamCollectionsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Team Collection details
|
||||||
|
*
|
||||||
|
* @param collectionID Collection ID
|
||||||
|
* @param collectionData new header data in a JSONified string form
|
||||||
|
* @param newTitle New title of the collection
|
||||||
|
* @returns Updated TeamCollection
|
||||||
|
*/
|
||||||
|
async updateTeamCollection(
|
||||||
|
collectionID: string,
|
||||||
|
collectionData: string = null,
|
||||||
|
newTitle: string = null,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
if (newTitle != null) {
|
||||||
|
const isTitleValid = isValidLength(newTitle, this.TITLE_LENGTH);
|
||||||
|
if (!isTitleValid) return E.left(TEAM_COLL_SHORT_TITLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collectionData === '') return E.left(TEAM_COLL_DATA_INVALID);
|
||||||
|
if (collectionData) {
|
||||||
|
const jsonReq = stringToJson(collectionData);
|
||||||
|
if (E.isLeft(jsonReq)) return E.left(TEAM_COLL_DATA_INVALID);
|
||||||
|
collectionData = jsonReq.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedTeamCollection = await this.prisma.teamCollection.update({
|
||||||
|
where: { id: collectionID },
|
||||||
|
data: {
|
||||||
|
data: collectionData ?? undefined,
|
||||||
|
title: newTitle ?? undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.pubsub.publish(
|
||||||
|
`team_coll/${updatedTeamCollection.teamID}/coll_updated`,
|
||||||
|
this.cast(updatedTeamCollection),
|
||||||
|
);
|
||||||
|
|
||||||
|
return E.right(this.cast(updatedTeamCollection));
|
||||||
|
} catch (e) {
|
||||||
|
return E.left(TEAM_COLL_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ const teamCollection: DbTeamCollection = {
|
|||||||
id: 'team-coll-1',
|
id: 'team-coll-1',
|
||||||
parentID: null,
|
parentID: null,
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
|
data: {},
|
||||||
title: 'Team Collection 1',
|
title: 'Team Collection 1',
|
||||||
orderIndex: 1,
|
orderIndex: 1,
|
||||||
createdOn: new Date(),
|
createdOn: new Date(),
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
// This interface defines how data will be received from the app when we are importing Hoppscotch collections
|
||||||
export interface CollectionFolder {
|
export interface CollectionFolder {
|
||||||
id?: string;
|
id?: string;
|
||||||
folders: CollectionFolder[];
|
folders: CollectionFolder[];
|
||||||
requests: any[];
|
requests: any[];
|
||||||
name: string;
|
name: string;
|
||||||
|
data?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ import { PaginationArgs } from 'src/types/input-types.args';
|
|||||||
export class CreateRootUserCollectionArgs {
|
export class CreateRootUserCollectionArgs {
|
||||||
@Field({ name: 'title', description: 'Title of the new user collection' })
|
@Field({ name: 'title', description: 'Title of the new user collection' })
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
name: 'data',
|
||||||
|
description: 'JSON string representing the collection data',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
data: string;
|
||||||
}
|
}
|
||||||
@ArgsType()
|
@ArgsType()
|
||||||
export class CreateChildUserCollectionArgs {
|
export class CreateChildUserCollectionArgs {
|
||||||
@@ -17,6 +24,13 @@ export class CreateChildUserCollectionArgs {
|
|||||||
description: 'ID of the parent to the new user collection',
|
description: 'ID of the parent to the new user collection',
|
||||||
})
|
})
|
||||||
parentUserCollectionID: string;
|
parentUserCollectionID: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
name: 'data',
|
||||||
|
description: 'JSON string representing the collection data',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
data: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ArgsType()
|
@ArgsType()
|
||||||
@@ -95,3 +109,26 @@ export class ImportUserCollectionsFromJSONArgs {
|
|||||||
})
|
})
|
||||||
parentCollectionID?: string;
|
parentCollectionID?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ArgsType()
|
||||||
|
export class UpdateUserCollectionsArgs {
|
||||||
|
@Field(() => ID, {
|
||||||
|
name: 'userCollectionID',
|
||||||
|
description: 'ID of the user collection',
|
||||||
|
})
|
||||||
|
userCollectionID: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
name: 'newTitle',
|
||||||
|
description: 'The updated title of the user collection',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
newTitle: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
name: 'data',
|
||||||
|
description: 'JSON string representing the collection data',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
data: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
MoveUserCollectionArgs,
|
MoveUserCollectionArgs,
|
||||||
RenameUserCollectionsArgs,
|
RenameUserCollectionsArgs,
|
||||||
UpdateUserCollectionArgs,
|
UpdateUserCollectionArgs,
|
||||||
|
UpdateUserCollectionsArgs,
|
||||||
} from './input-type.args';
|
} from './input-type.args';
|
||||||
import { ReqType } from 'src/types/RequestTypes';
|
import { ReqType } from 'src/types/RequestTypes';
|
||||||
import * as E from 'fp-ts/Either';
|
import * as E from 'fp-ts/Either';
|
||||||
@@ -142,7 +143,13 @@ export class UserCollectionResolver {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (E.isLeft(userCollection)) throwErr(userCollection.left);
|
if (E.isLeft(userCollection)) throwErr(userCollection.left);
|
||||||
return userCollection.right;
|
return <UserCollection>{
|
||||||
|
...userCollection.right,
|
||||||
|
userID: userCollection.right.userUid,
|
||||||
|
data: !userCollection.right.data
|
||||||
|
? null
|
||||||
|
: JSON.stringify(userCollection.right.data),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query(() => UserCollectionExportJSONData, {
|
@Query(() => UserCollectionExportJSONData, {
|
||||||
@@ -191,6 +198,7 @@ export class UserCollectionResolver {
|
|||||||
await this.userCollectionService.createUserCollection(
|
await this.userCollectionService.createUserCollection(
|
||||||
user,
|
user,
|
||||||
args.title,
|
args.title,
|
||||||
|
args.data,
|
||||||
null,
|
null,
|
||||||
ReqType.REST,
|
ReqType.REST,
|
||||||
);
|
);
|
||||||
@@ -212,6 +220,7 @@ export class UserCollectionResolver {
|
|||||||
await this.userCollectionService.createUserCollection(
|
await this.userCollectionService.createUserCollection(
|
||||||
user,
|
user,
|
||||||
args.title,
|
args.title,
|
||||||
|
args.data,
|
||||||
null,
|
null,
|
||||||
ReqType.GQL,
|
ReqType.GQL,
|
||||||
);
|
);
|
||||||
@@ -232,6 +241,7 @@ export class UserCollectionResolver {
|
|||||||
await this.userCollectionService.createUserCollection(
|
await this.userCollectionService.createUserCollection(
|
||||||
user,
|
user,
|
||||||
args.title,
|
args.title,
|
||||||
|
args.data,
|
||||||
args.parentUserCollectionID,
|
args.parentUserCollectionID,
|
||||||
ReqType.GQL,
|
ReqType.GQL,
|
||||||
);
|
);
|
||||||
@@ -252,6 +262,7 @@ export class UserCollectionResolver {
|
|||||||
await this.userCollectionService.createUserCollection(
|
await this.userCollectionService.createUserCollection(
|
||||||
user,
|
user,
|
||||||
args.title,
|
args.title,
|
||||||
|
args.data,
|
||||||
args.parentUserCollectionID,
|
args.parentUserCollectionID,
|
||||||
ReqType.REST,
|
ReqType.REST,
|
||||||
);
|
);
|
||||||
@@ -359,6 +370,26 @@ export class UserCollectionResolver {
|
|||||||
return importedCollection.right;
|
return importedCollection.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mutation(() => UserCollection, {
|
||||||
|
description: 'Update a UserCollection',
|
||||||
|
})
|
||||||
|
@UseGuards(GqlAuthGuard)
|
||||||
|
async updateUserCollection(
|
||||||
|
@GqlUser() user: AuthUser,
|
||||||
|
@Args() args: UpdateUserCollectionsArgs,
|
||||||
|
) {
|
||||||
|
const updatedUserCollection =
|
||||||
|
await this.userCollectionService.updateUserCollection(
|
||||||
|
args.newTitle,
|
||||||
|
args.data,
|
||||||
|
args.userCollectionID,
|
||||||
|
user.uid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (E.isLeft(updatedUserCollection)) throwErr(updatedUserCollection.left);
|
||||||
|
return updatedUserCollection.right;
|
||||||
|
}
|
||||||
|
|
||||||
// Subscriptions
|
// Subscriptions
|
||||||
@Subscription(() => UserCollection, {
|
@Subscription(() => UserCollection, {
|
||||||
description: 'Listen for User Collection Creation',
|
description: 'Listen for User Collection Creation',
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@ import {
|
|||||||
USER_NOT_FOUND,
|
USER_NOT_FOUND,
|
||||||
USER_NOT_OWNER,
|
USER_NOT_OWNER,
|
||||||
USER_COLL_INVALID_JSON,
|
USER_COLL_INVALID_JSON,
|
||||||
|
USER_COLL_DATA_INVALID,
|
||||||
} from 'src/errors';
|
} from 'src/errors';
|
||||||
import { PrismaService } from 'src/prisma/prisma.service';
|
import { PrismaService } from 'src/prisma/prisma.service';
|
||||||
import { AuthUser } from 'src/types/AuthUser';
|
import { AuthUser } from 'src/types/AuthUser';
|
||||||
@@ -43,8 +44,12 @@ export class UserCollectionService {
|
|||||||
*/
|
*/
|
||||||
private cast(collection: UserCollection) {
|
private cast(collection: UserCollection) {
|
||||||
return <UserCollectionModel>{
|
return <UserCollectionModel>{
|
||||||
...collection,
|
id: collection.id,
|
||||||
|
title: collection.title,
|
||||||
|
type: collection.type,
|
||||||
|
parentID: collection.parentID,
|
||||||
userID: collection.userUid,
|
userID: collection.userUid,
|
||||||
|
data: !collection.data ? null : JSON.stringify(collection.data),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +151,7 @@ export class UserCollectionService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return parent;
|
return !parent ? null : this.cast(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -164,7 +169,7 @@ export class UserCollectionService {
|
|||||||
take: number,
|
take: number,
|
||||||
type: ReqType,
|
type: ReqType,
|
||||||
) {
|
) {
|
||||||
return this.prisma.userCollection.findMany({
|
const res = await this.prisma.userCollection.findMany({
|
||||||
where: {
|
where: {
|
||||||
parentID: collectionID,
|
parentID: collectionID,
|
||||||
type: type,
|
type: type,
|
||||||
@@ -176,6 +181,12 @@ export class UserCollectionService {
|
|||||||
skip: cursor ? 1 : 0,
|
skip: cursor ? 1 : 0,
|
||||||
cursor: cursor ? { id: cursor } : undefined,
|
cursor: cursor ? { id: cursor } : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const childCollections = res.map((childCollection) =>
|
||||||
|
this.cast(childCollection),
|
||||||
|
);
|
||||||
|
|
||||||
|
return childCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,12 +222,20 @@ export class UserCollectionService {
|
|||||||
async createUserCollection(
|
async createUserCollection(
|
||||||
user: AuthUser,
|
user: AuthUser,
|
||||||
title: string,
|
title: string,
|
||||||
|
data: string | null = null,
|
||||||
parentUserCollectionID: string | null,
|
parentUserCollectionID: string | null,
|
||||||
type: ReqType,
|
type: ReqType,
|
||||||
) {
|
) {
|
||||||
const isTitleValid = isValidLength(title, this.TITLE_LENGTH);
|
const isTitleValid = isValidLength(title, this.TITLE_LENGTH);
|
||||||
if (!isTitleValid) return E.left(USER_COLL_SHORT_TITLE);
|
if (!isTitleValid) return E.left(USER_COLL_SHORT_TITLE);
|
||||||
|
|
||||||
|
if (data === '') return E.left(USER_COLL_DATA_INVALID);
|
||||||
|
if (data) {
|
||||||
|
const jsonReq = stringToJson(data);
|
||||||
|
if (E.isLeft(jsonReq)) return E.left(USER_COLL_DATA_INVALID);
|
||||||
|
data = jsonReq.right;
|
||||||
|
}
|
||||||
|
|
||||||
// If creating a child collection
|
// If creating a child collection
|
||||||
if (parentUserCollectionID !== null) {
|
if (parentUserCollectionID !== null) {
|
||||||
const parentCollection = await this.getUserCollection(
|
const parentCollection = await this.getUserCollection(
|
||||||
@@ -251,15 +270,19 @@ export class UserCollectionService {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
parent: isParent,
|
parent: isParent,
|
||||||
|
data: data ?? undefined,
|
||||||
orderIndex: !parentUserCollectionID
|
orderIndex: !parentUserCollectionID
|
||||||
? (await this.getRootCollectionsCount(user.uid)) + 1
|
? (await this.getRootCollectionsCount(user.uid)) + 1
|
||||||
: (await this.getChildCollectionsCount(parentUserCollectionID)) + 1,
|
: (await this.getChildCollectionsCount(parentUserCollectionID)) + 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.pubsub.publish(`user_coll/${user.uid}/created`, userCollection);
|
await this.pubsub.publish(
|
||||||
|
`user_coll/${user.uid}/created`,
|
||||||
|
this.cast(userCollection),
|
||||||
|
);
|
||||||
|
|
||||||
return E.right(userCollection);
|
return E.right(this.cast(userCollection));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -276,7 +299,7 @@ export class UserCollectionService {
|
|||||||
take: number,
|
take: number,
|
||||||
type: ReqType,
|
type: ReqType,
|
||||||
) {
|
) {
|
||||||
return this.prisma.userCollection.findMany({
|
const res = await this.prisma.userCollection.findMany({
|
||||||
where: {
|
where: {
|
||||||
userUid: user.uid,
|
userUid: user.uid,
|
||||||
parentID: null,
|
parentID: null,
|
||||||
@@ -289,6 +312,12 @@ export class UserCollectionService {
|
|||||||
skip: cursor ? 1 : 0,
|
skip: cursor ? 1 : 0,
|
||||||
cursor: cursor ? { id: cursor } : undefined,
|
cursor: cursor ? { id: cursor } : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const userCollections = res.map((childCollection) =>
|
||||||
|
this.cast(childCollection),
|
||||||
|
);
|
||||||
|
|
||||||
|
return userCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -307,7 +336,7 @@ export class UserCollectionService {
|
|||||||
take: number,
|
take: number,
|
||||||
type: ReqType,
|
type: ReqType,
|
||||||
) {
|
) {
|
||||||
return this.prisma.userCollection.findMany({
|
const res = await this.prisma.userCollection.findMany({
|
||||||
where: {
|
where: {
|
||||||
userUid: user.uid,
|
userUid: user.uid,
|
||||||
parentID: userCollectionID,
|
parentID: userCollectionID,
|
||||||
@@ -317,9 +346,16 @@ export class UserCollectionService {
|
|||||||
skip: cursor ? 1 : 0,
|
skip: cursor ? 1 : 0,
|
||||||
cursor: cursor ? { id: cursor } : undefined,
|
cursor: cursor ? { id: cursor } : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const childCollections = res.map((childCollection) =>
|
||||||
|
this.cast(childCollection),
|
||||||
|
);
|
||||||
|
|
||||||
|
return childCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated Use updateUserCollection method instead
|
||||||
* Update the title of a UserCollection
|
* Update the title of a UserCollection
|
||||||
*
|
*
|
||||||
* @param newTitle The new title of collection
|
* @param newTitle The new title of collection
|
||||||
@@ -351,10 +387,10 @@ export class UserCollectionService {
|
|||||||
|
|
||||||
this.pubsub.publish(
|
this.pubsub.publish(
|
||||||
`user_coll/${updatedUserCollection.userUid}/updated`,
|
`user_coll/${updatedUserCollection.userUid}/updated`,
|
||||||
updatedUserCollection,
|
this.cast(updatedUserCollection),
|
||||||
);
|
);
|
||||||
|
|
||||||
return E.right(updatedUserCollection);
|
return E.right(this.cast(updatedUserCollection));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return E.left(USER_COLL_NOT_FOUND);
|
return E.left(USER_COLL_NOT_FOUND);
|
||||||
}
|
}
|
||||||
@@ -591,10 +627,10 @@ export class UserCollectionService {
|
|||||||
|
|
||||||
this.pubsub.publish(
|
this.pubsub.publish(
|
||||||
`user_coll/${collection.right.userUid}/moved`,
|
`user_coll/${collection.right.userUid}/moved`,
|
||||||
updatedCollection.right,
|
this.cast(updatedCollection.right),
|
||||||
);
|
);
|
||||||
|
|
||||||
return E.right(updatedCollection.right);
|
return E.right(this.cast(updatedCollection.right));
|
||||||
}
|
}
|
||||||
|
|
||||||
// destCollectionID != null i.e move into another collection
|
// destCollectionID != null i.e move into another collection
|
||||||
@@ -642,10 +678,10 @@ export class UserCollectionService {
|
|||||||
|
|
||||||
this.pubsub.publish(
|
this.pubsub.publish(
|
||||||
`user_coll/${collection.right.userUid}/moved`,
|
`user_coll/${collection.right.userUid}/moved`,
|
||||||
updatedCollection.right,
|
this.cast(updatedCollection.right),
|
||||||
);
|
);
|
||||||
|
|
||||||
return E.right(updatedCollection.right);
|
return E.right(this.cast(updatedCollection.right));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -846,6 +882,7 @@ export class UserCollectionService {
|
|||||||
...(x.request as Record<string, unknown>), // type casting x.request of type Prisma.JSONValue to an object to enable spread
|
...(x.request as Record<string, unknown>), // type casting x.request of type Prisma.JSONValue to an object to enable spread
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
data: JSON.stringify(collection.right.data),
|
||||||
};
|
};
|
||||||
|
|
||||||
return E.right(result);
|
return E.right(result);
|
||||||
@@ -918,6 +955,7 @@ export class UserCollectionService {
|
|||||||
...(x.request as Record<string, unknown>), // type casting x.request of type Prisma.JSONValue to an object to enable spread
|
...(x.request as Record<string, unknown>), // type casting x.request of type Prisma.JSONValue to an object to enable spread
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
data: JSON.stringify(parentCollection.right.data),
|
||||||
}),
|
}),
|
||||||
collectionType: parentCollection.right.type,
|
collectionType: parentCollection.right.type,
|
||||||
});
|
});
|
||||||
@@ -971,6 +1009,7 @@ export class UserCollectionService {
|
|||||||
this.generatePrismaQueryObj(f, userID, index + 1, reqType),
|
this.generatePrismaQueryObj(f, userID, index + 1, reqType),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
data: folder.data ?? undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1040,10 +1079,63 @@ export class UserCollectionService {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
userCollections.forEach((x) =>
|
userCollections.forEach((collection) =>
|
||||||
this.pubsub.publish(`user_coll/${userID}/created`, x),
|
this.pubsub.publish(`user_coll/${userID}/created`, this.cast(collection)),
|
||||||
);
|
);
|
||||||
|
|
||||||
return E.right(true);
|
return E.right(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a UserCollection
|
||||||
|
*
|
||||||
|
* @param newTitle The new title of collection
|
||||||
|
* @param userCollectionID The Collection Id
|
||||||
|
* @param userID The User UID
|
||||||
|
* @returns An Either of the updated UserCollection
|
||||||
|
*/
|
||||||
|
async updateUserCollection(
|
||||||
|
newTitle: string = null,
|
||||||
|
collectionData: string | null = null,
|
||||||
|
userCollectionID: string,
|
||||||
|
userID: string,
|
||||||
|
) {
|
||||||
|
if (collectionData === '') return E.left(USER_COLL_DATA_INVALID);
|
||||||
|
|
||||||
|
if (collectionData) {
|
||||||
|
const jsonReq = stringToJson(collectionData);
|
||||||
|
if (E.isLeft(jsonReq)) return E.left(USER_COLL_DATA_INVALID);
|
||||||
|
collectionData = jsonReq.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newTitle != null) {
|
||||||
|
const isTitleValid = isValidLength(newTitle, this.TITLE_LENGTH);
|
||||||
|
if (!isTitleValid) return E.left(USER_COLL_SHORT_TITLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see is the collection belongs to the user
|
||||||
|
const isOwner = await this.isOwnerCheck(userCollectionID, userID);
|
||||||
|
if (O.isNone(isOwner)) return E.left(USER_NOT_OWNER);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const updatedUserCollection = await this.prisma.userCollection.update({
|
||||||
|
where: {
|
||||||
|
id: userCollectionID,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
data: collectionData ?? undefined,
|
||||||
|
title: newTitle ?? undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.pubsub.publish(
|
||||||
|
`user_coll/${updatedUserCollection.userUid}/updated`,
|
||||||
|
this.cast(updatedUserCollection),
|
||||||
|
);
|
||||||
|
|
||||||
|
return E.right(this.cast(updatedUserCollection));
|
||||||
|
} catch (error) {
|
||||||
|
return E.left(USER_COLL_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ export class UserCollection {
|
|||||||
})
|
})
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
description: 'JSON string representing the collection data',
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
data: string;
|
||||||
|
|
||||||
@Field(() => ReqType, {
|
@Field(() => ReqType, {
|
||||||
description: 'Type of the user collection',
|
description: 'Type of the user collection',
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user