Skip to content

Commit

Permalink
feat(api): add pagination to getPets
Browse files Browse the repository at this point in the history
  • Loading branch information
luke-h1 committed Aug 6, 2024
1 parent 15953c7 commit 9d7bffb
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 125 deletions.
87 changes: 66 additions & 21 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,33 @@ async function main() {
password: 'password123',
role: Role.USER,
pets: {
create: {
name: 'Mittens',
age: '4',
birthDate: '2019-02-20',
breed: 'Tabby',
description:
'Mittens is a sweet and affectionate Tabby cat who loves to cuddle.',
photoUrl:
'https://images.pexels.com/photos/10891037/pexels-photo-10891037.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
tags: ['cute', 'fluffy'],
createMany: {
data: [
{
name: 'Mittens',
age: '4',
birthDate: '2019-02-20',
breed: 'Tabby',
status: PetStatus.PENDING,
description:
'Mittens is a sweet and affectionate Tabby cat who loves to cuddle.',
photoUrl:
'https://images.pexels.com/photos/10891037/pexels-photo-10891037.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
tags: ['cute', 'fluffy'],
},
{
name: 'Mittens',
age: '4',
birthDate: '2019-02-20',
breed: 'Tabby',
status: PetStatus.ADOPTED,
description:
'Mittens is a sweet and affectionate Tabby cat who loves to cuddle.',
photoUrl:
'https://images.pexels.com/photos/10891037/pexels-photo-10891037.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
tags: ['cute', 'fluffy'],
},
],
},
},
},
Expand All @@ -61,17 +78,45 @@ async function main() {
password: 'password123',
role: Role.USER,
pets: {
create: {
name: 'Whiskers',
age: '2',
birthDate: '2021-08-10',
breed: 'Siamese',
description:
'Whiskers is a curious and playful Siamese cat who loves to explore and climb.',
photoUrl:
'https://images.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
status: PetStatus.AVAILABLE,
tags: ['curious', 'playful'],
createMany: {
data: [
{
name: 'Chloe',
age: '2',
birthDate: '2021-06-18',
breed: 'Sphynx',
status: PetStatus.AVAILABLE,
description:
'Chloe is a unique Sphynx cat who loves to stay warm.',
photoUrl:
'https://images.pexels.com/photos/617278/pexels-photo-617278.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
tags: ['unique', 'warm'],
},
{
name: 'Leo',
age: '3',
birthDate: '2020-09-22',
breed: 'British Shorthair',
status: PetStatus.AVAILABLE,
description:
'Leo is a friendly British Shorthair cat who loves to play.',
photoUrl:
'https://images.pexels.com/photos/617278/pexels-photo-617278.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
tags: ['friendly', 'playful'],
},
{
name: 'Nala',
age: '5',
birthDate: '2018-04-14',
breed: 'Russian Blue',
status: PetStatus.AVAILABLE,
description:
'Nala is a graceful Russian Blue cat with a calm demeanor.',
photoUrl:
'https://images.pexels.com/photos/617278/pexels-photo-617278.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
tags: ['graceful', 'calm'],
},
],
},
},
},
Expand Down
127 changes: 63 additions & 64 deletions src/controllers/__mocks__/pet.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,64 @@
import { Pet } from '@prisma/client';
import { CreatePetInput } from 'src/schema/pet.schema';

export const pets: Omit<Pet, 'createdAt' | 'updatedAt' | 'id' | 'creatorId'>[] =
[
{
name: 'Buddy',
breed: 'Golden Retriever',
status: 'AVAILABLE',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1560807707-8cc777a4d2f9',
},
{
name: 'Mittens',
breed: 'Siamese',
status: 'ADOPTED',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1592194996308-7d9c3f8d4a2b',
},
{
name: 'Charlie',
breed: 'Labrador Retriever',
status: 'AVAILABLE',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1517423440428-a5a00ad493e8',
},
{
name: 'Whiskers',
breed: 'Maine Coon',
status: 'PENDING',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1560807707-8cc777a4d2f9',
},
{
name: 'Max',
breed: 'Beagle',
status: 'ADOPTED',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1558788353-f76d92427f16',
},
{
name: 'Luna',
breed: 'Bengal',
status: 'AVAILABLE',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1592194996308-7d9c3f8d4a2b',
},
];
export const pets: CreatePetInput['body'][] = [
{
name: 'Buddy',
breed: 'Golden Retriever',
status: 'AVAILABLE',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1560807707-8cc777a4d2f9',
},
{
name: 'Mittens',
breed: 'Siamese',
status: 'ADOPTED',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1592194996308-7d9c3f8d4a2b',
},
{
name: 'Charlie',
breed: 'Labrador Retriever',
status: 'AVAILABLE',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1517423440428-a5a00ad493e8',
},
{
name: 'Whiskers',
breed: 'Maine Coon',
status: 'PENDING',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1560807707-8cc777a4d2f9',
},
{
name: 'Max',
breed: 'Beagle',
status: 'ADOPTED',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1558788353-f76d92427f16',
},
{
name: 'Luna',
breed: 'Bengal',
status: 'AVAILABLE',
age: '12',
birthDate: '2022',
description: 'dog',
tags: ['dog'],
photoUrl: 'https://images.unsplash.com/photo-1592194996308-7d9c3f8d4a2b',
},
];
88 changes: 56 additions & 32 deletions src/controllers/__tests__/petController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,64 @@ import { user, user2 } from '../__mocks__/user';
describe('pet', () => {
const app = server.init();

test('getPets', async () => {
const u = await db.user.create({
data: {
...user,
},
});
await db.pet.createMany({
data: pets.slice(3).map(p => ({
...p,
creatorId: u.id,
})),
describe('getPets', () => {
test('getPets', async () => {
const u = await db.user.create({
data: user,
});
await db.pet.createMany({
data: pets.slice(3).map(p => ({
...p,
creatorId: u.id,
})),
});

const { body, statusCode } = await supertest(app).get('/api/pets');

expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({
age: expect.any(String),
birthDate: expect.any(String),
breed: expect.any(String),
createdAt: expect.any(String),
creatorId: expect.any(String),
description: expect.any(String),
id: expect.any(String),
name: expect.any(String),
photoUrl: expect.any(String),
status: expect.any(String),
tags: expect.arrayContaining([expect.any(String)]),
updatedAt: expect.any(String),
}),
]),
);
expect(statusCode).toBe(200);
});

const { body, statusCode } = await supertest(app).get('/api/pets');

expect(body).toEqual(
expect.arrayContaining([
expect.objectContaining({
age: expect.any(String),
birthDate: expect.any(String),
breed: expect.any(String),
createdAt: expect.any(String),
creatorId: expect.any(String),
description: expect.any(String),
id: expect.any(String),
name: expect.any(String),
photoUrl: expect.any(String),
status: expect.any(String),
tags: expect.arrayContaining([expect.any(String)]),
updatedAt: expect.any(String),
}),
]),
);
expect(statusCode).toBe(200);
test('getPets with pagination', async () => {
const u = await db.user.create({
data: user,
});
await db.pet.createMany({
data: pets.slice(3).map(p => ({
...p,
creatorId: u.id,
})),
});

const { body, statusCode } = await supertest(app).get(
'/api/pets?page=1&pageSize=2',
);
expect(body).toHaveLength(2);
expect(statusCode).toBe(200);

// test we return empty array if no results
const { body: secondPageBody, statusCode: secondPageStatusCode } =
await supertest(app).get('/api/pets?page=2&pageSize=3');
expect(secondPageBody).toHaveLength(0);
expect(secondPageStatusCode).toBe(200);
});
});

test('getPet', async () => {
Expand Down
4 changes: 3 additions & 1 deletion src/controllers/petController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
UpdatePetRequest,
} from '../requests/pet';
import PetService from '../services/petService';
import parsePaginationParams from '../utils/parsePaginationParams';

export default class PetController {
private readonly petService: PetService;
Expand All @@ -16,7 +17,8 @@ export default class PetController {
}

async getPets(req: Request, res: Response) {
const pets = await this.petService.getPets();
const { page, pageSize } = parsePaginationParams(req.query);
const pets = await this.petService.getPets(page, pageSize);
return res.status(200).json(pets);
}

Expand Down
4 changes: 2 additions & 2 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import testRedis from './test/redis';
import logger from './utils/logger';

dotenv.config({
path: process.env.NODE_ENV === 'test' ? '.env.test' : '.env',
path: process.env.NODE_ENV === 'test' ? '.env.test' : '.env.development',
});

class CreateServer {
Expand Down Expand Up @@ -71,7 +71,7 @@ class CreateServer {
logger.error(`redis session error: ${error}`);
},
}),
secret: process.env.SESSION_SECRET as string,
secret: process.env.SESSION_SECRET ?? 'pets',
resave: false,
saveUninitialized: false,
cookie: {
Expand Down
7 changes: 5 additions & 2 deletions src/services/petService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ export default class PetService {
this.redis = RedisDatabase;
}

async getPets() {
async getPets(page?: number, pageSize?: number) {
// const cachedPets = await this.redis.getAll<Pet[]>('pets');

// if (cachedPets && cachedPets.length) {
// return JSON.parse(cachedPets as unknown as string);
// }

const pets = await db.pet.findMany();
const pets = await db.pet.findMany({
take: pageSize,
skip: page && pageSize ? (page - 1) * pageSize : 0,
});

// save to cache
// console.log('pets', JSON.stringify(pets, null, 2));
Expand Down
Loading

0 comments on commit 9d7bffb

Please sign in to comment.