Skip to content

Commit

Permalink
Merge pull request #35 from atlp-rwanda/ft-user-logout-#187984515
Browse files Browse the repository at this point in the history
User: Auth logout  #187984515
  • Loading branch information
teerenzo authored Jul 30, 2024
2 parents ee7d51f + c62ea67 commit a44d64b
Show file tree
Hide file tree
Showing 22 changed files with 1,002 additions and 247 deletions.
67 changes: 47 additions & 20 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
version: '3.1'

services:
web:
build:
context: .
dockerfile: Dockerfile
container_name: eagle-ec-fe-container
image: mugemanebertin/eagle-ec-fe
ports:
- "5173:5173"
env_file:
- .env

# Backend Service
backend:
image: mugemanebertin/eagle_ec_be:latest
container_name: eagle-ec-be-container
container_name: express-server-container
ports:
- "499:499"
command: sh -c "npm run migrate && (npm run seed || true) && npm run dev"
- "${PORT}:${PORT}"
volumes:
- ./backend:/usr/src/app
- /usr/src/app/node_modules
command: sh -c "npm run migrate && npm run seed || true && npm run dev"
depends_on:
- db
- postgres_db
- redis
env_file:
- ./.env
environment:
- DB_CONNECTION=${DOCKER_DB_CONNECTION}
- JWT_SECRET=${JWT_SECRET}
Expand All @@ -35,12 +30,14 @@ services:
- GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
- GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
- GOOGLE_CALLBACK_URL=${GOOGLE_CALLBACK_URL}
- REDIS_HOST=redis
- REDIS_PORT=6379
- FE_URL=${FE_URL}
networks:
- eagle-ec

db:
# PostgreSQL Database Service
postgres_db:
image: postgres:latest
container_name: eagle-ec-db-container
container_name: postgres-db-container
ports:
- "5433:5432"
environment:
Expand All @@ -49,11 +46,41 @@ services:
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- eagle-ec

# Redis Service
redis:
image: redis:latest
container_name: redis-container
ports:
- "6379:6379"
networks:
- eagle-ec

# Web Frontend Service
frontend:
build:
context: .
dockerfile: Dockerfile
container_name: eagle-ec-fe-container
image: mugemanebertin/eagle-ec-fe
ports:
- "5173:5173"
env_file:
- ./.env
volumes:
- ./frontend:/app
- /app/node_modules
networks:
- eagle-ec
command: npm run dev -- --host
depends_on:
- backend

volumes:
postgres_data:
postgres_data:

networks:
eagle-ec:
driver: bridge
20 changes: 20 additions & 0 deletions src/__test__/HomeButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import { MemoryRouter, Routes, Route } from "react-router-dom";

import HomeButton from "../components/dashboard/HomeButton";

describe("HomeButton", () => {
it("should render the Home button", () => {
render(
<MemoryRouter initialEntries={["/test"]}>
<Routes>
<Route path="/test" element={<HomeButton />} />
</Routes>
</MemoryRouter>,
);

const homeButton = screen.getByText("Home");
expect(homeButton).toBeInTheDocument();
});
});
62 changes: 62 additions & 0 deletions src/__test__/LogoutContext.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import "@testing-library/jest-dom";
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";

import {
LogoutProvider,
useLogout,
} from "../components/dashboard/admin/LogoutContext";

// Mock LogoutModal component
jest.mock("../components/dashboard/admin/LogoutModal", () => ({
__esModule: true,
default: ({ isOpen, onClose, onConfirm }: any) =>
(isOpen ? (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<div className="p-6 bg-white rounded shadow-lg">
<h2 className="mb-4 text-xl">Confirm Logout</h2>
<p className="mb-4">Are you sure you want to logout?</p>
<div className="flex justify-end gap-4">
<button
className="px-4 py-2 text-white bg-gray-500 rounded"
onClick={onClose}
>
Cancel
</button>
<button
className="px-4 py-2 text-white bg-red-500 rounded"
onClick={onConfirm}
>
Logout
</button>
</div>
</div>
</div>
) : null),
}));

const TestComponent: React.FC = () => {
const { openLogoutModal } = useLogout();
return <button onClick={openLogoutModal}>Open Logout Modal</button>;
};

describe("LogoutProvider Component", () => {
it("should render LogoutProvider and trigger logout modal", () => {
render(
<LogoutProvider>
<TestComponent />
</LogoutProvider>,
);

const openModalButton = screen.getByText("Open Logout Modal");
fireEvent.click(openModalButton);

// Verify that the modal is rendered
expect(screen.getByText("Confirm Logout")).toBeInTheDocument();
expect(
screen.getByText("Are you sure you want to logout?"),
).toBeInTheDocument();
expect(screen.getByText("Cancel")).toBeInTheDocument();
expect(screen.getByText("Logout")).toBeInTheDocument();
});
});
97 changes: 97 additions & 0 deletions src/__test__/ProfileDropdown.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import "@testing-library/jest-dom";
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { BrowserRouter as Router } from "react-router-dom";

import { useLogout } from "../components/dashboard/admin/LogoutContext"; // Ensure the correct path
import ProfileDropdown from "../components/common/ProfileDropdown";

// Mock the useLogout hook
jest.mock("../components/dashboard/admin/LogoutContext", () => ({
useLogout: jest.fn(),
}));

describe("ProfileDropdown", () => {
const openLogoutModalMock = jest.fn();

beforeEach(() => {
(useLogout as jest.Mock).mockReturnValue({
openLogoutModal: openLogoutModalMock,
});
});

afterEach(() => {
jest.clearAllMocks();
});

it("should render profile and orders links for a user with roleId 1", () => {
const userInfo = { roleId: 1 };

render(
<Router>
<ProfileDropdown userInfo={userInfo} />
</Router>,
);

expect(screen.getByText("Profile")).toBeInTheDocument();
expect(screen.getByText("My Orders")).toBeInTheDocument();
expect(screen.getByText("Logout")).toBeInTheDocument();
});

it("should render the correct dashboard link for roleId 2", () => {
const userInfo = { roleId: 2 };

render(
<Router>
<ProfileDropdown userInfo={userInfo} />
</Router>,
);

expect(screen.getByText("My Dashboard")).toBeInTheDocument();
expect(screen.getByRole("link", { name: /My Dashboard/i })).toHaveAttribute(
"href",
"/dashboard",
);
});

it("should render the correct dashboard link for roleId 3", () => {
const userInfo = { roleId: 3 };

render(
<Router>
<ProfileDropdown userInfo={userInfo} />
</Router>,
);

expect(screen.getByText("My Dashboard")).toBeInTheDocument();
expect(screen.getByRole("link", { name: /My Dashboard/i })).toHaveAttribute(
"href",
"/admin/dashboard",
);
});

it("should call openLogoutModal when logout button is clicked", () => {
const userInfo = { roleId: 1 };

render(
<Router>
<ProfileDropdown userInfo={userInfo} />
</Router>,
);

const logoutButton = screen.getByText("Logout");
fireEvent.click(logoutButton);

expect(openLogoutModalMock).toHaveBeenCalled();
});

it("should render login link if userInfo is not provided", () => {
render(
<Router>
<ProfileDropdown userInfo={null} />
</Router>,
);

expect(screen.getByText("Login")).toBeInTheDocument();
});
});
Loading

0 comments on commit a44d64b

Please sign in to comment.