feat(auth): add refresh api call call
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
export * from "./login";
|
export * from "./login";
|
||||||
export * from "./register";
|
export * from "./register";
|
||||||
export * from "./logout";
|
export * from "./logout";
|
||||||
|
export * from "./refresh";
|
||||||
|
|||||||
3
src/features/auth/api/calls/refresh/constants.ts
Normal file
3
src/features/auth/api/calls/refresh/constants.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export const REFRESH_API_ROUTE = "auth/refresh";
|
||||||
|
export const MOCK_TOKEN = "mock.access.token";
|
||||||
|
export const MOCK_FRESH_TOKEN = "mock.fresh.access.token";
|
||||||
2
src/features/auth/api/calls/refresh/index.ts
Normal file
2
src/features/auth/api/calls/refresh/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export { refresh } from "./refresh";
|
||||||
|
export { REFRESH_API_ROUTE } from "./constants";
|
||||||
22
src/features/auth/api/calls/refresh/refresh.mock.ts
Normal file
22
src/features/auth/api/calls/refresh/refresh.mock.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { http, HttpResponse } from "msw";
|
||||||
|
import { BASE_URL } from "shared/config";
|
||||||
|
import { MOCK_FRESH_TOKEN, MOCK_TOKEN, REFRESH_API_ROUTE } from "./constants";
|
||||||
|
|
||||||
|
const REFRESH_URL = `${BASE_URL}/${REFRESH_API_ROUTE}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Msw interceptor. Mocks the refresh endpoint response.
|
||||||
|
* Validates the Authorization header — returns a fresh token on success, 401 on expired/missing session.
|
||||||
|
*/
|
||||||
|
export const refreshMock = http.post(REFRESH_URL, ({ request }) => {
|
||||||
|
const authHeader = request.headers.get("Authorization");
|
||||||
|
|
||||||
|
if (authHeader === `Bearer ${MOCK_TOKEN}`) {
|
||||||
|
return HttpResponse.json({
|
||||||
|
accessToken: MOCK_FRESH_TOKEN,
|
||||||
|
user: { id: "1", email: "test@test.com" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return HttpResponse.json({ message: "Session expired" }, { status: 401 });
|
||||||
|
});
|
||||||
33
src/features/auth/api/calls/refresh/refresh.spec.ts
Normal file
33
src/features/auth/api/calls/refresh/refresh.spec.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { setupServer } from "msw/node";
|
||||||
|
import { useAuthStore } from "../../../model";
|
||||||
|
import { refresh } from "./refresh";
|
||||||
|
import { refreshMock } from "./refresh.mock";
|
||||||
|
import { MOCK_FRESH_TOKEN, MOCK_TOKEN } from "./constants";
|
||||||
|
|
||||||
|
const server = setupServer(refreshMock);
|
||||||
|
|
||||||
|
describe("refresh", () => {
|
||||||
|
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
|
||||||
|
afterEach(() => {
|
||||||
|
server.resetHandlers();
|
||||||
|
useAuthStore.setState({ accessToken: undefined });
|
||||||
|
});
|
||||||
|
afterAll(() => server.close());
|
||||||
|
|
||||||
|
describe("happy path", () => {
|
||||||
|
it("returns a fresh access token and user when session is valid", async () => {
|
||||||
|
useAuthStore.setState({ accessToken: MOCK_TOKEN });
|
||||||
|
|
||||||
|
const result = await refresh();
|
||||||
|
|
||||||
|
expect(result.accessToken).toBe(MOCK_FRESH_TOKEN);
|
||||||
|
expect(result.user).toEqual({ id: "1", email: "test@test.com" });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("error cases", () => {
|
||||||
|
it("throws when session is expired or missing", async () => {
|
||||||
|
await expect(refresh()).rejects.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
7
src/features/auth/api/calls/refresh/refresh.ts
Normal file
7
src/features/auth/api/calls/refresh/refresh.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { api } from "../../../api";
|
||||||
|
import type { AuthResponse } from "../../../model/types/service";
|
||||||
|
import { REFRESH_API_ROUTE } from "./constants";
|
||||||
|
|
||||||
|
export function refresh() {
|
||||||
|
return api.post(REFRESH_API_ROUTE).json<AuthResponse>();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user