diff --git a/packages/api/src/entity/folder_policy.ts b/packages/api/src/entity/folder_policy.ts index 82bc0a160..94e72be5b 100644 --- a/packages/api/src/entity/folder_policy.ts +++ b/packages/api/src/entity/folder_policy.ts @@ -1,9 +1,11 @@ import { Column, + CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, + UpdateDateColumn, } from 'typeorm' import { User } from './user' @@ -36,9 +38,15 @@ export class FolderPolicy { @Column('int') minimumItems!: number - @Column('timestamptz') + @CreateDateColumn({ + type: 'timestamptz', + default: () => 'CURRENT_TIMESTAMP', + }) createdAt!: Date - @Column('timestamptz') + @UpdateDateColumn({ + type: 'timestamptz', + default: () => 'CURRENT_TIMESTAMP', + }) updatedAt!: Date } diff --git a/packages/api/src/resolvers/folder_policy/index.ts b/packages/api/src/resolvers/folder_policy/index.ts index d9ad12c2b..737d655e2 100644 --- a/packages/api/src/resolvers/folder_policy/index.ts +++ b/packages/api/src/resolvers/folder_policy/index.ts @@ -1,9 +1,15 @@ -import { FolderPolicy } from '../../entity/folder_policy' +import { FolderPolicy, FolderPolicyAction } from '../../entity/folder_policy' import { + CreateFolderPolicyError, + CreateFolderPolicySuccess, FolderPoliciesError, FolderPoliciesSuccess, + MutationCreateFolderPolicyArgs, } from '../../generated/graphql' -import { findFolderPoliciesByUserId } from '../../services/folder_policy' +import { + createFolderPolicy, + findFolderPoliciesByUserId, +} from '../../services/folder_policy' import { Merge } from '../../util' import { authorized } from '../../utils/gql-utils' @@ -21,3 +27,23 @@ export const folderPoliciesResolver = authorized< policies, } }) + +export const createFolderPolicyResolver = authorized< + Merge, + CreateFolderPolicyError, + MutationCreateFolderPolicyArgs +>(async (_, { input }, { uid }) => { + const { folder, action, afterDays, minimumItems } = input + + const policy = await createFolderPolicy({ + userId: uid, + folder, + action: action as unknown as FolderPolicyAction, + afterDays, + minimumItems: minimumItems ?? 0, + }) + + return { + policy, + } +}) diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index b03b13e90..21a5d4d78 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -5,7 +5,6 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { createHmac } from 'crypto' import { isError } from 'lodash' -import { FolderPolicy } from '../entity/folder_policy' import { Highlight } from '../entity/highlight' import { LibraryItem } from '../entity/library_item' import { @@ -53,7 +52,10 @@ import { saveDiscoverArticleResolver, } from './discover_feeds' import { optInFeatureResolver } from './features' -import { folderPoliciesResolver } from './folder_policy' +import { + createFolderPolicyResolver, + folderPoliciesResolver, +} from './folder_policy' import { highlightsResolver } from './highlight' import { hiddenHomeSectionResolver, @@ -309,6 +311,7 @@ export const functionResolvers = { exportToIntegration: exportToIntegrationResolver, replyToEmail: replyToEmailResolver, refreshHome: refreshHomeResolver, + createFolderPolicy: createFolderPolicyResolver, }, Query: { me: getMeUserResolver, @@ -884,4 +887,5 @@ export const functionResolvers = { ...resultResolveTypeResolver('HiddenHomeSection'), ...resultResolveTypeResolver('Highlights'), ...resultResolveTypeResolver('FolderPolicies'), + ...resultResolveTypeResolver('CreateFolderPolicy'), } diff --git a/packages/api/test/resolvers/folder_policy.test.ts b/packages/api/test/resolvers/folder_policy.test.ts index 84254eb14..f4d30925a 100644 --- a/packages/api/test/resolvers/folder_policy.test.ts +++ b/packages/api/test/resolvers/folder_policy.test.ts @@ -1,10 +1,15 @@ +import { expect } from 'chai' import { FolderPolicyAction } from '../../src/entity/folder_policy' import { User } from '../../src/entity/user' -import { createFolderPolicy } from '../../src/services/folder_policy' +import { FolderPolicy } from '../../src/generated/graphql' +import { + createFolderPolicy, + deleteFolderPolicy, + findFolderPolicyById, +} from '../../src/services/folder_policy' import { deleteUser } from '../../src/services/user' import { createTestUser } from '../db' import { graphqlRequest, loginAndGetAuthToken } from '../util' -import { expect } from 'chai' describe('Folder Policy API', () => { let loginUser: User @@ -54,6 +59,51 @@ describe('Folder Policy API', () => { const policies = res.body.data.folderPolicies.policies as any[] expect(policies).to.have.lengthOf(1) expect(policies[0].id).to.equal(existingPolicy.id) + + await deleteFolderPolicy(existingPolicy.id) + }) + }) + + describe('Create Folder Policy', () => { + const mutation = ` + mutation CreateFolderPolicy($input: CreateFolderPolicyInput!) { + createFolderPolicy(input: $input) { + ... on CreateFolderPolicySuccess { + policy { + id + folder + action + createdAt + updatedAt + } + } + ... on CreateFolderPolicyError { + errorCodes + } + } + } + ` + + it('should create a folder policy', async () => { + const input = { + folder: 'test-folder', + action: FolderPolicyAction.ARCHIVE, + afterDays: 30, + minimumItems: 10, + } + + const res = await graphqlRequest(mutation, authToken, { input }).expect( + 200 + ) + + const createdPolicy = res.body.data.createFolderPolicy + .policy as FolderPolicy + + const policy = await findFolderPolicyById(createdPolicy.id) + expect(policy).to.exist + expect(policy?.folder).to.equal(input.folder) + + await deleteFolderPolicy(createdPolicy.id) }) }) })