Skip to content

Commit

Permalink
feat(api): Add pagination metadata to Project module (#393)
Browse files Browse the repository at this point in the history
  • Loading branch information
muntaxir4 authored and rajdip-b committed Jul 29, 2024
1 parent 3119001 commit bc274fd
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 19 deletions.
41 changes: 36 additions & 5 deletions apps/api/src/project/project.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { VariableService } from '../variable/service/variable.service'
import { VariableModule } from '../variable/variable.module'
import { SecretModule } from '../secret/secret.module'
import { EnvironmentModule } from '../environment/environment.module'
import { QueryTransformPipe } from '../common/query.transform.pipe'

describe('Project Controller Tests', () => {
let app: NestFastifyApplication
Expand Down Expand Up @@ -86,6 +87,8 @@ describe('Project Controller Tests', () => {
secretService = moduleRef.get(SecretService)
variableService = moduleRef.get(VariableService)

app.useGlobalPipes(new QueryTransformPipe())

await app.init()
await app.getHttpAdapter().getInstance().ready()
})
Expand Down Expand Up @@ -463,14 +466,29 @@ describe('Project Controller Tests', () => {
it('should be able to fetch all projects of a workspace', async () => {
const response = await app.inject({
method: 'GET',
url: `/project/all/${workspace1.id}?page=0`,
url: `/project/all/${workspace1.id}?page=0&limit=10`,
headers: {
'x-e2e-user-email': user1.email
}
})

expect(response.statusCode).toBe(200)
expect(response.json().length).toEqual(2)
expect(response.json().items.length).toEqual(2)

//check metadata
const metadata = response.json().metadata
expect(metadata.totalCount).toEqual(2)
expect(metadata.links.self).toBe(
`/project/all/${workspace1.id}?page=0&limit=10&sort=name&order=asc&search=`
)
expect(metadata.links.first).toBe(
`/project/all/${workspace1.id}?page=0&limit=10&sort=name&order=asc&search=`
)
expect(metadata.links.previous).toEqual(null)
expect(metadata.links.next).toEqual(null)
expect(metadata.links.last).toBe(
`/project/all/${workspace1.id}?page=0&limit=10&sort=name&order=asc&search=`
)
})

it('should not be able to fetch all projects of a non existing workspace', async () => {
Expand Down Expand Up @@ -1722,9 +1740,22 @@ describe('Project Controller Tests', () => {
'x-e2e-user-email': user2.email
}
})

expect(response.statusCode).toBe(200)
expect(response.json()).toHaveLength(1)
expect(response.json().items).toHaveLength(1)

//check metadata
const metadata = response.json().metadata
expect(metadata.links.self).toBe(
`/project/${project3.id}/forks?page=0&limit=10`
)
expect(metadata.links.first).toBe(
`/project/${project3.id}/forks?page=0&limit=10`
)
expect(metadata.links.previous).toEqual(null)
expect(metadata.links.next).toEqual(null)
expect(metadata.links.last).toBe(
`/project/${project3.id}/forks?page=0&limit=10`
)
})

it('should not contain a forked project that has access level other than GLOBAL', async () => {
Expand Down Expand Up @@ -1754,7 +1785,7 @@ describe('Project Controller Tests', () => {
})

expect(response.statusCode).toBe(200)
expect(response.json()).toHaveLength(1)
expect(response.json().items).toHaveLength(1)
})
})
})
77 changes: 63 additions & 14 deletions apps/api/src/project/service/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import createEvent from '../../common/create-event'
import { ProjectWithSecrets } from '../project.types'
import { AuthorityCheckerService } from '../../common/authority-checker.service'
import { ForkProject } from '../dto/fork.project/fork.project'
import { paginate } from '../../common/paginate'

@Injectable()
export class ProjectService {
Expand Down Expand Up @@ -593,19 +594,30 @@ export class ProjectService {
}
})

return forks
.slice(page * limit, (page + 1) * limit)
.filter(async (fork) => {
const allowed =
(await this.authorityCheckerService.checkAuthorityOverProject({
userId: user.id,
entity: { id: fork.id },
authority: Authority.READ_PROJECT,
prisma: this.prisma
})) != null

return allowed
})
const forksAllowed = forks.filter(async (fork) => {
const allowed =
(await this.authorityCheckerService.checkAuthorityOverProject({
userId: user.id,
entity: { id: fork.id },
authority: Authority.READ_PROJECT,
prisma: this.prisma
})) != null

return allowed
})

const items = forksAllowed.slice(page * limit, (page + 1) * limit)
//calculate metadata
const metadata = paginate(
forksAllowed.length,
`/project/${projectId}/forks`,
{
page,
limit
}
)

return { items, metadata }
}

async getProjectById(user: User, projectId: Project['id']) {
Expand Down Expand Up @@ -638,7 +650,8 @@ export class ProjectService {
prisma: this.prisma
})

return (
//fetch projects with required properties
const items = (
await this.prisma.project.findMany({
skip: page * limit,
take: limit,
Expand Down Expand Up @@ -669,6 +682,42 @@ export class ProjectService {
}
})
).map((project) => excludeFields(project, 'privateKey', 'publicKey'))

//calculate metadata
const totalCount = await this.prisma.project.count({
where: {
workspaceId,
OR: [
{
name: {
contains: search
}
},
{
description: {
contains: search
}
}
],
workspace: {
members: {
some: {
userId: user.id
}
}
}
}
})

const metadata = paginate(totalCount, `/project/all/${workspaceId}`, {
page,
limit,
sort,
order,
search
})

return { items, metadata }
}

private async projectExists(
Expand Down

0 comments on commit bc274fd

Please sign in to comment.