feat(auth): add refresh api call call

This commit is contained in:
Ilia Mashkov
2026-03-17 14:15:32 +03:00
parent ed718eea71
commit 226874bbec
6 changed files with 68 additions and 0 deletions

View File

@@ -1,3 +1,4 @@
export * from "./login";
export * from "./register";
export * from "./logout";
export * from "./refresh";

View 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";

View File

@@ -0,0 +1,2 @@
export { refresh } from "./refresh";
export { REFRESH_API_ROUTE } from "./constants";

View 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 });
});

View 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();
});
});
});

View 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>();
}