Skip to content

Commit

Permalink
WILD_017: Refacto - Ajout test pagination, fix test lié
Browse files Browse the repository at this point in the history
  • Loading branch information
JTissot-Dev committed Aug 23, 2024
1 parent 8d2a7c3 commit a7c7df2
Show file tree
Hide file tree
Showing 13 changed files with 541 additions and 376 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
.env.test
data/*
data/*
docker-compose-local.test.yaml
103 changes: 85 additions & 18 deletions back/src/__tests__/Url.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import dataSource from "../database/dataSource";
import { Url } from "../entities/Url";
import { ILike } from "typeorm";


describe("Integration Test Url Entity", () => {
beforeAll(async () => {
Expand All @@ -10,35 +10,102 @@ describe("Integration Test Url Entity", () => {
await dataSource.destroy();
});

it("find method should return a list of Url", async () => {
const urls = await Url.find({
order: { createdAt: "DESC" },
it("getPaginateUrls method should return a list of Url", async () => {
const paginateUrls = await Url.getPaginateUrls(1);

// Check if the result has the expected structure
expect(paginateUrls).toHaveProperty('urls');
expect(paginateUrls).toHaveProperty('totalPages');
expect(paginateUrls).toHaveProperty('currentPage');
expect(paginateUrls).toHaveProperty('previousPage');
expect(paginateUrls).toHaveProperty('nextPage');
expect(Array.isArray(paginateUrls.urls)).toBe(true);

// Check if values have the expected structure
paginateUrls.urls.forEach((url) => {
expect(url).toHaveProperty('id');
expect(url).toHaveProperty('name');
expect(url).toHaveProperty('path');
});
});

// Check if the result is an array
expect(Array.isArray(urls)).toBeTruthy();
it("getPaginateUrls method whith searchText should return a list of Url", async () => {
const paginateUrls = await Url.getPaginateUrls(1, "a");

// Check if values are instances of Url
urls.forEach((url) => {
expect(url).toBeInstanceOf(Url);
// Check if the result has the expected structure
expect(paginateUrls).toHaveProperty('urls');
expect(paginateUrls).toHaveProperty('totalPages');
expect(paginateUrls).toHaveProperty('currentPage');
expect(paginateUrls).toHaveProperty('previousPage');
expect(paginateUrls).toHaveProperty('nextPage');
expect(Array.isArray(paginateUrls.urls)).toBe(true);

// Check if values have the expected structure
paginateUrls.urls.forEach((url) => {
expect(url).toHaveProperty('id');
expect(url).toHaveProperty('name');
expect(url).toHaveProperty('path');
});
});

it("find with where method and order should return a list of Url in clause", async () => {
const urls = await Url.find({
where: [{ name: ILike(`%Fa%`) }, { path: ILike(`%Fa%`) }],
order: { createdAt: "DESC" },
it("getPaginateUrls method whith searchText and sortField should return a list of Url", async () => {
const paginateUrls = await Url.getPaginateUrls(1, "a", "name");

// Check if the result has the expected structure
expect(paginateUrls).toHaveProperty('urls');
expect(paginateUrls).toHaveProperty('totalPages');
expect(paginateUrls).toHaveProperty('currentPage');
expect(paginateUrls).toHaveProperty('previousPage');
expect(paginateUrls).toHaveProperty('nextPage');
expect(Array.isArray(paginateUrls.urls)).toBe(true);

// Check if values have the expected structure
paginateUrls.urls.forEach((url) => {
expect(url).toHaveProperty('id');
expect(url).toHaveProperty('name');
expect(url).toHaveProperty('path');
});
});

// Check if the result is an array
expect(Array.isArray(urls)).toBeTruthy();
it("getPaginateUrls method whith connected user and private url should return a list of Url", async () => {
const paginateUrls = await Url.getPaginateUrls(1, "a", "name", true, "741fbb42-1dd9-40c5-a29e-604407a7bc8c");

// Check if values are instances of Url
urls.forEach((url) => {
expect(url).toBeInstanceOf(Url);
// Check if the result has the expected structure
expect(paginateUrls).toHaveProperty('urls');
expect(paginateUrls).toHaveProperty('totalPages');
expect(paginateUrls).toHaveProperty('currentPage');
expect(paginateUrls).toHaveProperty('previousPage');
expect(paginateUrls).toHaveProperty('nextPage');
expect(Array.isArray(paginateUrls.urls)).toBe(true);

// Check if values have the expected structure
paginateUrls.urls.forEach((url) => {
expect(url).toHaveProperty('id');
expect(url).toHaveProperty('name');
expect(url).toHaveProperty('path');
});
});

it("getPaginateUrls method whith connected user and public url should return a list of Url", async () => {
const paginateUrls = await Url.getPaginateUrls(1, "a", "name", false, "741fbb42-1dd9-40c5-a29e-604407a7bc8c");

// Check if the result has the expected structure
expect(paginateUrls).toHaveProperty('urls');
expect(paginateUrls).toHaveProperty('totalPages');
expect(paginateUrls).toHaveProperty('currentPage');
expect(paginateUrls).toHaveProperty('previousPage');
expect(paginateUrls).toHaveProperty('nextPage');
expect(Array.isArray(paginateUrls.urls)).toBe(true);

// Check if values have the expected structure
paginateUrls.urls.forEach((url) => {
expect(url).toHaveProperty('id');
expect(url).toHaveProperty('name');
expect(url).toHaveProperty('path');
});
});


it("findOneByOrFail method should return a single Url", async () => {
const url = await Url.findOneByOrFail({
id: "737fbb42-1dd9-40c5-a29e-604407a7bc7b",
Expand Down
54 changes: 46 additions & 8 deletions back/src/__tests__/UrlResolver.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Url } from "../entities/Url";
import PaginateUrls from "@/types/PaginatesUrls";
import UrlResolver from "../resolvers/UrlResolver";
import { MyContext, JwtPayload } from "..";

type PartialUrl = Partial<Url>;

Expand All @@ -9,6 +11,23 @@ const mockUrl: PartialUrl = {
path: "https://example.com",
};
const mockUrls: PartialUrl[] = [mockUrl];
const mockPaginateUrls: PaginateUrls = {
urls: mockUrls as Url[],
totalPages: 1,
currentPage: 1,
previousPage: 1,
nextPage: 1,
};

const mockContext: MyContext = {
res: {
setHeader: jest.fn(),
},
payload: {
id: "testId",
email: "[email protected]",
} as JwtPayload,
};

describe("Unit Test Url Resolver", () => {
let urlResolver: UrlResolver;
Expand All @@ -21,19 +40,38 @@ describe("Unit Test Url Resolver", () => {
jest.restoreAllMocks();
});

it("Query urls should return an array of Url", async () => {
jest.spyOn(Url, "find").mockImplementation(() =>
Promise.resolve(mockUrls as Url[]),
it("Query urls whith context should return a pagination of urls", async () => {
jest.spyOn(Url, "getPaginateUrls").mockImplementation(() =>
Promise.resolve(mockPaginateUrls as PaginateUrls),
);

const result = await urlResolver.urls(mockContext, false, 1, "", "");
expect(result).toEqual(mockPaginateUrls);
});

it("Query urls whith context should throw an error when fetching urls fails", async () => {
jest.spyOn(Url, "getPaginateUrls").mockRejectedValue(
new Error("Internal server error"),
);
await expect(urlResolver.urls(mockContext, false, 1, "", "")).rejects.toThrow(
"Internal server error",
);
});

it("Query urls whithout context should return a pagination of urls", async () => {
jest.spyOn(Url, "getPaginateUrls").mockImplementation(() =>
Promise.resolve(mockPaginateUrls as PaginateUrls),
);
const result = await urlResolver.urls();
expect(result).toEqual(mockUrls);

const result = await urlResolver.urls({} as MyContext, false, 1, "", "");
expect(result).toEqual(mockPaginateUrls);
});

it("Query urls should throw an error when fetching urls fails", async () => {
jest.spyOn(Url, "find").mockRejectedValue(
it("Query urls whithout context should throw an error when fetching urls fails", async () => {
jest.spyOn(Url, "getPaginateUrls").mockRejectedValue(
new Error("Internal server error"),
);
await expect(urlResolver.urls()).rejects.toThrow(
await expect(urlResolver.urls({} as MyContext, false, 1, "", "")).rejects.toThrow(
"Internal server error",
);
});
Expand Down
7 changes: 7 additions & 0 deletions back/src/database/seeder/dataInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ export const historiesData = [
response: "Facebook response",
},
];

export const userData = {
id: "e5fb990e-f9d9-4858-82d1-1fd1755485a5",
username: "test",
email: "[email protected]",
hashedPassword: "hashedPasswordTest",
};
20 changes: 20 additions & 0 deletions back/src/database/seeder/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Url } from "../../entities/Url";
import { User } from "../../entities/User";
import { UserUrl } from "../../entities/UserUrl";
import { History } from "../../entities/History";
import dataSource from "../dataSource";
import { urlsData, historiesData } from "./dataInput";
Expand All @@ -21,6 +23,24 @@ async function generateFixtures() {
return url;
}),
);
await Url.create({
id: "737fbb42-1dd9-40c5-a29e-604407a7bc7b",
name: "TestUrl for fetch private urls",
path: "https://excalidraw.com"
});

await User.save({
id: "741fbb42-1dd9-40c5-a29e-604407a7bc8c",
username: "testuser",
email: "[email protected]",
hashedPassword: "hashedPasswordTest",
});

await UserUrl.save({
userId: "741fbb42-1dd9-40c5-a29e-604407a7bc8c",
urlId: "737fbb42-1dd9-40c5-a29e-604407a7bc7b",
});

await History.save({ ...historiesData[0], url: savedUrls[0] });
await History.save({ ...historiesData[1], url: savedUrls[1] });
console.log("Fixtures generated successfully!");
Expand Down
2 changes: 1 addition & 1 deletion back/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import HistoryResolver from "./resolvers/HistoryResolver";
import UserResolver from "./resolvers/UserResolver";
import UserUrlResolver from "./resolvers/UserUrlResolver";

interface JwtPayload {
export interface JwtPayload {
id: string;
email: string;
}
Expand Down
4 changes: 4 additions & 0 deletions docker-compose.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ services:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
TZ: Europe/Paris
LC_ALL: fr_FR.UTF-8
depends_on:
database-test:
condition: service_healthy
Expand All @@ -23,6 +25,8 @@ services:
environment:
APP_ENV: ${APP_ENV}
VITE_API_URL: ${VITE_API_URL}
TZ: Europe/Paris
LC_ALL: fr_FR.UTF-8

database-test:
container_name: database-test
Expand Down
54 changes: 54 additions & 0 deletions front/src/__tests__/CustomPagination.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import CustomPagination from '@/components/custom/CustomPagination';


vi.mock('@/hooks/useScreenDimensions', () => ({
default: () => ({ width: 1024 })
}));

describe('CustomPagination', () => {
const defaultProps = {
currentPage: 3,
totalPages: 10,
previousPage: 2,
nextPage: 4,
onPageChange: vi.fn(),
};

it('renders correctly', () => {
render(<CustomPagination {...defaultProps} />);
expect(screen.getByText('3')).toHaveAttribute('aria-current', 'page');
expect(screen.getByText('Précédent')).toBeInTheDocument();
expect(screen.getByText('Suivant')).toBeInTheDocument();
});

it('calls onPageChange with correct page number when clicking on a page', () => {
render(<CustomPagination {...defaultProps} />);
fireEvent.click(screen.getByText('4'));
expect(defaultProps.onPageChange).toHaveBeenCalledWith(4);
});

it('calls onPageChange with Previous page when clicking Précédent', () => {
render(<CustomPagination {...defaultProps} />);
fireEvent.click(screen.getByText('Précédent'));
expect(defaultProps.onPageChange).toHaveBeenCalledWith(2);
});

it('calls onPageChange with next page when clicking Next', () => {
render(<CustomPagination {...defaultProps} />);
fireEvent.click(screen.getByText('Suivant'));
expect(defaultProps.onPageChange).toHaveBeenCalledWith(4);
});

it('renders ellipsis when there are many pages', () => {
render(<CustomPagination {...defaultProps} />);
expect(screen.getAllByText('More pages')).toHaveLength(1);
});

it('renders first and last page numbers', () => {
render(<CustomPagination {...defaultProps} />);
expect(screen.getByText('1')).toBeInTheDocument();
expect(screen.getByText('10')).toBeInTheDocument();
});
});
Loading

0 comments on commit a7c7df2

Please sign in to comment.