@mehdashti/testing-utils
v0.1.1
Published
Testing utilities for Smart Platform - MSW handlers, mocks, and factories
Maintainers
Readme
@smart/testing-utils
Testing utilities for Smart Platform - MSW handlers, mocks, and factories
Installation
pnpm add -D @smart/testing-utils mswFeatures
- ✅ MSW Handlers: Pre-configured handlers for auth, users, and errors
- ✅ Auth Mocks: Mock users, tokens, and login responses
- ✅ Data Factories: Generate realistic test data with Faker
- ✅ Test Helpers: Utility functions for async testing
- ✅ @smart/contracts: Compatible with platform error formats
Quick Start
1. Setup MSW Server
// src/setupTests.ts
import { server } from "@smart/testing-utils/server";
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());2. Use in Tests
import { mockUser, mockLoginResponse } from "@smart/testing-utils";
test("login flow", async () => {
// Mock data is automatically available
const response = await fetch("/api/auth/login", {
method: "POST",
body: JSON.stringify({
email: "[email protected]",
password: "password",
}),
});
const data = await response.json();
expect(data.user).toEqual(mockUser);
});MSW Handlers
Available Handlers
import {
handlers, // All handlers
authHandlers, // Auth endpoints only
userHandlers, // User endpoints only
errorHandlers, // Error simulation
} from "@smart/testing-utils";Endpoints
Auth:
POST /api/auth/login- Login with email/passwordPOST /api/auth/refresh- Refresh access tokenPOST /api/auth/logout- LogoutGET /api/users/me- Get current user
Users:
GET /api/users- List users (paginated)GET /api/users/:id- Get user by ID
Error Simulation:
POST /api/test/validation-error- Returns 422GET /api/test/server-error- Returns 500GET /api/test/rate-limit- Returns 429
Custom Handlers
import { http, HttpResponse } from "msw";
import { server } from "@smart/testing-utils/server";
test("custom endpoint", () => {
server.use(
http.get("/api/custom", () => {
return HttpResponse.json({ message: "custom response" });
})
);
// Your test code
});Mock Data
Auth Mocks
import {
mockUser, // Admin user
mockViewerUser, // Viewer role
mockInactiveUser, // Inactive user
mockUsers, // Array of users
mockTokens, // Auth tokens
mockLoginResponse, // Full login response
} from "@smart/testing-utils";
// Use in tests
expect(user).toEqual(mockUser);
// Check roles
import { isAdmin, userHasRole } from "@smart/testing-utils";
expect(isAdmin(mockUser)).toBe(true);
expect(userHasRole(mockViewerUser, "admin")).toBe(false);Data Factories
User Factory
import {
createUser,
createAdminUser,
createViewerUser,
createUsers,
} from "@smart/testing-utils";
// Create a random user
const user = createUser();
// Create with specific data
const admin = createAdminUser({
email: "[email protected]",
name: "Test Admin",
});
// Create multiple users
const users = createUsers(10);Pagination Factory
import {
createPaginationMeta,
createPaginatedResponse,
} from "@smart/testing-utils";
const users = createUsers(5);
const response = createPaginatedResponse(users, 1, 20);
expect(response).toEqual({
data: users,
meta: {
page: 1,
page_size: 20,
total_items: 5,
total_pages: 1,
},
});Test Helpers
import {
wait,
waitForNextTick,
createDelayedMock,
createDelayedErrorMock,
} from "@smart/testing-utils";
// Wait for async operations
await wait(100);
// Wait for next tick
await waitForNextTick();
// Create delayed mock
const mockFn = createDelayedMock({ data: "test" }, 200);
const result = await mockFn(); // Resolves after 200ms
// Create error mock
const errorFn = createDelayedErrorMock(new Error("Failed"), 100);
await expect(errorFn()).rejects.toThrow("Failed");Examples
Testing Login
import { mockLoginResponse } from "@smart/testing-utils";
test("successful login", async () => {
const response = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: "[email protected]",
password: "password",
}),
});
expect(response.ok).toBe(true);
const data = await response.json();
expect(data).toMatchObject(mockLoginResponse);
});Testing Error Handling
test("handles validation errors", async () => {
const response = await fetch("/api/test/validation-error", {
method: "POST",
});
expect(response.status).toBe(422);
const error = await response.json();
expect(error).toMatchObject({
type: "validation_error",
status: 422,
errors: expect.arrayContaining([
expect.objectContaining({
field: "email",
message: expect.any(String),
}),
]),
});
});Testing with Custom Data
import { createUser, createPaginatedResponse } from "@smart/testing-utils";
import { server } from "@smart/testing-utils/server";
import { http, HttpResponse } from "msw";
test("custom user list", () => {
const customUsers = [
createUser({ email: "[email protected]" }),
createUser({ email: "[email protected]" }),
];
server.use(
http.get("/api/users", () => {
return HttpResponse.json(
createPaginatedResponse(customUsers, 1, 20)
);
})
);
// Your test code
});Browser Testing
For browser tests (Playwright, Cypress), use MSW browser worker:
// src/mocks/browser.ts
import { setupWorker } from "msw/browser";
import { handlers } from "@smart/testing-utils";
export const worker = setupWorker(...handlers);License
MIT
