Skip to content

Commit

Permalink
feat(chat): Implement user private and public chat
Browse files Browse the repository at this point in the history
- a user should be able to read previous chats
- a user should be able to post a public chat
- users should be able to chat privately

Delivers #187419133
  • Loading branch information
Heisjabo committed Jul 22, 2024
1 parent 837a593 commit fcb5d4f
Show file tree
Hide file tree
Showing 27 changed files with 1,509 additions and 111 deletions.
69 changes: 69 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"jest-environment-jsdom": "^29.7.0",
"jest-fetch-mock": "^3.0.3",
"jest-mock-extended": "^3.0.7",
"moment": "^2.30.1",
"node-fetch": "^3.3.2",
"npm": "^10.8.1",
"prop-types": "^15.8.1",
Expand All @@ -57,6 +58,7 @@
"react-toastify": "^10.0.5",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"socket.io-client": "^4.7.5",
"swiper": "^11.1.4",
"tailwindcss": "^3.4.4",
"vite-plugin-environment": "^1.1.3",
Expand Down
26 changes: 21 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,28 @@ import * as React from "react";
import "react-toastify/dist/ReactToastify.css";
import "./App.css";

import { IoChatbubbleEllipsesOutline } from "react-icons/io5";
import { Link, useLocation } from "react-router-dom";

import AppRoutes from "./routes/AppRoutes";

const App: React.FC = () => (
<main>
<AppRoutes />
</main>
);
const App: React.FC = () => {
const location = useLocation();

return (
<main>
<AppRoutes />
{location.pathname !== "/chat"
&& location.pathname !== "/login"
&& location.pathname !== "/register" && (
<Link to="/chat">
<div className="fixed bg-primary text-white shadow-md rounded px-3 py-3 z-50 right-6 bottom-6 cursor-pointer group">
<IoChatbubbleEllipsesOutline className="text-[30px] text-white" />
</div>
</Link>
)}
</main>
);
};

export default App;
84 changes: 84 additions & 0 deletions src/__test__/authSlice.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { configureStore } from "@reduxjs/toolkit";
import MockAdapter from "axios-mock-adapter";

import api from "../redux/api/api";
import authSlice, { fetchUser, setUser } from "../redux/reducers/authSlice";

const mockApi = new MockAdapter(api);
const mockStore = (initialState) =>
configureStore({
reducer: {
// @ts-ignore
auth: authSlice,
},
preloadedState: initialState,
});

describe("Auth Slice Thunks", () => {
let store;

beforeEach(() => {
mockApi.reset();
store = mockStore({
auth: {
loading: false,
data: [],
error: null,
userInfo: JSON.parse(localStorage.getItem("userInfo") || "{}"),
},
});
});

it("should handle fetchUser pending", async () => {
mockApi.onGet("/users/me").reply(200, {});

store.dispatch(fetchUser());
expect(store.getState().auth.loading).toBe(true);
});

it("should handle fetchUser fulfilled", async () => {
const mockData = { id: "1", name: "John Doe" };
mockApi.onGet("/users/me").reply(200, mockData);

await store.dispatch(fetchUser());

expect(store.getState().auth.loading).toBe(false);
expect(store.getState().auth.data).toEqual(mockData);
expect(localStorage.getItem("userInfo")).toEqual(JSON.stringify(mockData));
});

it("should handle fetchUser rejected", async () => {
mockApi.onGet("/users/me").reply(500);

await store.dispatch(fetchUser());

expect(store.getState().auth.loading).toBe(false);
expect(store.getState().auth.error).toBe("Rejected");
});

it("should handle setUser", () => {
const mockUser = { id: "2", name: "Jane Doe" };
store.dispatch(setUser(mockUser));

expect(store.getState().auth.userInfo).toEqual(mockUser);
expect(localStorage.getItem("userInfo")).toEqual(JSON.stringify(mockUser));
});

it("should handle fetchUser axios error with specific message", async () => {
mockApi.onGet("/users/me").reply(500, { message: "Server error" });

await store.dispatch(fetchUser());

expect(store.getState().auth.loading).toBe(false);
expect(store.getState().auth.error.message).toBe("Server error");
});

it("should handle fetchUser axios network error", async () => {
mockApi.onGet("/users/me").networkError();

await store.dispatch(fetchUser());

expect(store.getState().auth.loading).toBe(false);
expect(store.getState().auth.error).toBe("Rejected");
});
});
Loading

0 comments on commit fcb5d4f

Please sign in to comment.