@lobehub/chat
Version:
Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.
140 lines (115 loc) • 3.66 kB
text/typescript
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { extractBearerToken, getUserAuth } from '../auth';
// Mock auth constants
let mockEnableClerk = false;
let mockEnableNextAuth = false;
vi.mock('@/const/auth', () => ({
get enableClerk() {
return mockEnableClerk;
},
get enableNextAuth() {
return mockEnableNextAuth;
},
}));
vi.mock('@/libs/clerk-auth', () => ({
ClerkAuth: class {
async getAuth() {
return {
clerkAuth: {
redirectToSignIn: vi.fn(),
},
userId: 'clerk-user-id',
};
}
},
}));
vi.mock('@/libs/next-auth/edge', () => ({
default: {
auth: vi.fn().mockResolvedValue({
user: {
id: 'next-auth-user-id',
},
}),
},
}));
describe('getUserAuth', () => {
beforeEach(() => {
vi.clearAllMocks();
mockEnableClerk = false;
mockEnableNextAuth = false;
});
it('should throw error when no auth method is enabled', async () => {
await expect(getUserAuth()).rejects.toThrow('Auth method is not enabled');
});
it('should return clerk auth when clerk is enabled', async () => {
mockEnableClerk = true;
mockEnableNextAuth = false;
const auth = await getUserAuth();
expect(auth).toEqual({
clerkAuth: {
redirectToSignIn: expect.any(Function),
},
userId: 'clerk-user-id',
});
});
it('should return next auth when next auth is enabled', async () => {
mockEnableClerk = false;
mockEnableNextAuth = true;
const auth = await getUserAuth();
expect(auth).toEqual({
nextAuth: {
user: {
id: 'next-auth-user-id',
},
},
userId: 'next-auth-user-id',
});
});
it('should prioritize clerk auth over next auth when both are enabled', async () => {
mockEnableClerk = true;
mockEnableNextAuth = true;
const auth = await getUserAuth();
expect(auth).toEqual({
clerkAuth: {
redirectToSignIn: expect.any(Function),
},
userId: 'clerk-user-id',
});
});
});
describe('extractBearerToken', () => {
it('should return the token when authHeader is valid', () => {
const token = 'test-token';
const authHeader = `Bearer ${token}`;
expect(extractBearerToken(authHeader)).toBe(token);
});
it('should return null when authHeader is missing', () => {
expect(extractBearerToken()).toBeNull();
});
it('should return null when authHeader is null', () => {
expect(extractBearerToken(null)).toBeNull();
});
it('should return null when authHeader does not start with "Bearer "', () => {
const authHeader = 'Invalid format';
expect(extractBearerToken(authHeader)).toBeNull();
});
it('should return null when authHeader is only "Bearer"', () => {
const authHeader = 'Bearer';
expect(extractBearerToken(authHeader)).toBeNull();
});
it('should return null when authHeader is an empty string', () => {
const authHeader = '';
expect(extractBearerToken(authHeader)).toBeNull();
});
it('should handle extra spaces correctly', () => {
const token = 'test-token-with-spaces';
const authHeaderWithExtraSpaces = ` Bearer ${token} `;
const authHeaderLeadingSpace = ` Bearer ${token}`;
const authHeaderTrailingSpace = `Bearer ${token} `;
const authHeaderMultipleSpacesBetween = `Bearer ${token}`;
expect(extractBearerToken(authHeaderWithExtraSpaces)).toBe(token);
expect(extractBearerToken(authHeaderLeadingSpace)).toBe(token);
expect(extractBearerToken(authHeaderTrailingSpace)).toBe(token);
expect(extractBearerToken(authHeaderMultipleSpacesBetween)).toBe(token);
});
});