Skip to main content
Glama

WhaTap MXQL CLI

by devload
AuthManager.test.ts11.3 kB
/** * AuthManager Unit Tests (Mock-based) * * Tests authentication flow with mocked HTTP responses */ import MockAdapter from 'axios-mock-adapter'; import axios from 'axios'; import * as fs from 'fs/promises'; import * as path from 'path'; import * as os from 'os'; import { AuthManager } from '../../../src/core/auth/AuthManager'; import { SessionStore } from '../../../src/core/auth/SessionStore'; import { AuthenticationError } from '../../../src/core/types'; describe('AuthManager (Unit Tests)', () => { let testDir: string; let sessionStore: SessionStore; let authManager: AuthManager; let mock: MockAdapter; const mockCredentials = { email: 'test@whatap.io', password: 'test-password', serviceUrl: 'https://test.whatap.io', }; beforeEach(async () => { // Create temporary test directory testDir = path.join(os.tmpdir(), `whatap-test-${Date.now()}`); await fs.mkdir(testDir, { recursive: true }); sessionStore = new SessionStore(testDir); // Setup axios mock BEFORE creating AuthManager mock = new MockAdapter(axios, { onNoMatch: 'throwException' }); authManager = new AuthManager(sessionStore); }); afterEach(async () => { // Clean up mock.restore(); try { await fs.rm(testDir, { recursive: true, force: true }); } catch (error) { // Ignore cleanup errors } }); describe('login - success flow', () => { test('should complete full login flow successfully', async () => { // Mock Step 1: CSRF token mock.onGet('https://test.whatap.io/account/login').reply(200, ` <html> <input id="_csrf" value="test-csrf-token" /> </html> `); // Mock Step 2: Web login mock.onPost('https://test.whatap.io/account/login').reply(200, 'success', { 'set-cookie': [ 'wa=test-wa-cookie; Path=/; HttpOnly', 'JSESSIONID=test-jsessionid; Path=/; HttpOnly', ] as any, }); // Mock Step 3: Mobile API token mock.onPost('https://test.whatap.io/mobile/api/login').reply(200, { accountId: 12345, apiToken: 'test-api-token', }); // Execute login const session = await authManager.login(mockCredentials); // Verify session expect(session.email).toBe(mockCredentials.email); expect(session.accountId).toBe(12345); expect(session.apiToken).toBe('test-api-token'); expect(session.cookies.wa).toBe('test-wa-cookie'); expect(session.cookies.jsessionid).toBe('test-jsessionid'); expect(session.serviceUrl).toBe(mockCredentials.serviceUrl); // Verify session is authenticated expect(authManager.isAuthenticated()).toBe(true); }); test('should save session after successful login', async () => { // Setup mocks mock.onGet('https://test.whatap.io/account/login').reply(200, ` <html><input id="_csrf" value="csrf" /></html> `); mock.onPost('https://test.whatap.io/account/login').reply(200, 'ok', { 'set-cookie': ['wa=wa-val; Path=/', 'JSESSIONID=session-val; Path=/'] as any, }); mock.onPost('https://test.whatap.io/mobile/api/login').reply(200, { accountId: 99999, apiToken: 'token-123', }); // Login await authManager.login(mockCredentials); // Load session from store const loaded = await sessionStore.load(); expect(loaded).not.toBeNull(); expect(loaded?.accountId).toBe(99999); }); }); describe('login - error cases', () => { test('should throw error when CSRF token not found', async () => { mock.onGet('https://test.whatap.io/account/login').reply(200, ` <html><body>No CSRF token here</body></html> `); await expect(authManager.login(mockCredentials)).rejects.toThrow( AuthenticationError ); await expect(authManager.login(mockCredentials)).rejects.toThrow( 'CSRF token not found' ); }); test('should throw error when web login fails (no cookies)', async () => { mock.onGet('https://test.whatap.io/account/login').reply(200, ` <html><input id="_csrf" value="csrf" /></html> `); mock.onPost('https://test.whatap.io/account/login').reply(200, 'ok'); // No set-cookie header await expect(authManager.login(mockCredentials)).rejects.toThrow( AuthenticationError ); await expect(authManager.login(mockCredentials)).rejects.toThrow( 'Required cookies not found' ); }); test('should throw error when account is locked', async () => { mock.onGet('https://test.whatap.io/account/login').reply(200, ` <html><input id="_csrf" value="csrf" /></html> `); mock.onPost('https://test.whatap.io/account/login').reply(200, ` <html><body>Account is locked</body></html> `); await expect(authManager.login(mockCredentials)).rejects.toThrow( AuthenticationError ); await expect(authManager.login(mockCredentials)).rejects.toThrow( 'Account is locked' ); }); test('should throw error when MFA is required', async () => { mock.onGet('https://test.whatap.io/account/login').reply(200, ` <html><input id="_csrf" value="csrf" /></html> `); mock.onPost('https://test.whatap.io/account/login').reply( 302, 'redirect', { location: '/account/mfa', 'set-cookie': ['wa=wa-val; Path=/', 'JSESSIONID=session-val; Path=/'] as any, } ); await expect(authManager.login(mockCredentials)).rejects.toThrow( AuthenticationError ); await expect(authManager.login(mockCredentials)).rejects.toThrow('MFA'); }); test('should throw error when mobile API token not received', async () => { mock.onGet('https://test.whatap.io/account/login').reply(200, ` <html><input id="_csrf" value="csrf" /></html> `); mock.onPost('https://test.whatap.io/account/login').reply(200, 'ok', { 'set-cookie': ['wa=wa-val; Path=/', 'JSESSIONID=session-val; Path=/'] as any, }); mock.onPost('https://test.whatap.io/mobile/api/login').reply(200, { // Missing apiToken accountId: 12345, }); await expect(authManager.login(mockCredentials)).rejects.toThrow( AuthenticationError ); await expect(authManager.login(mockCredentials)).rejects.toThrow( 'API token not received' ); }); }); describe('session management', () => { test('should load existing session', async () => { // Create and save a session manually const mockSession = { email: 'test@whatap.io', accountId: 12345, cookies: { wa: 'wa-cookie', jsessionid: 'session-id' }, apiToken: 'api-token', serviceUrl: 'https://test.whatap.io', createdAt: new Date(), expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), }; await sessionStore.save(mockSession); // Create new AuthManager and load session const newAuthManager = new AuthManager(sessionStore); const loaded = await newAuthManager.loadSession(); expect(loaded).not.toBeNull(); expect(loaded?.email).toBe(mockSession.email); expect(newAuthManager.isAuthenticated()).toBe(true); }); test('should return null when no session exists', async () => { const loaded = await authManager.loadSession(); expect(loaded).toBeNull(); expect(authManager.isAuthenticated()).toBe(false); }); test('should logout and clear session', async () => { // Setup session mock.onGet().reply(200, '<html><input id="_csrf" value="csrf" /></html>'); mock.onPost('https://test.whatap.io/account/login').reply(200, 'ok', { 'set-cookie': ['wa=wa; Path=/', 'JSESSIONID=jsession; Path=/'] as any, }); mock.onPost('https://test.whatap.io/mobile/api/login').reply(200, { accountId: 12345, apiToken: 'token', }); await authManager.login(mockCredentials); expect(authManager.isAuthenticated()).toBe(true); // Logout await authManager.logout(); expect(authManager.isAuthenticated()).toBe(false); // Verify session file is deleted const loaded = await sessionStore.load(); expect(loaded).toBeNull(); }); }); describe('getSession and getCookieHeader', () => { test('should get current session', async () => { // Setup mocks and login mock.onGet().reply(200, '<html><input id="_csrf" value="csrf" /></html>'); mock.onPost('https://test.whatap.io/account/login').reply(200, 'ok', { 'set-cookie': ['wa=wa-cookie; Path=/', 'JSESSIONID=session-id; Path=/'] as any, }); mock.onPost('https://test.whatap.io/mobile/api/login').reply(200, { accountId: 12345, apiToken: 'token', }); await authManager.login(mockCredentials); const session = authManager.getSession(); expect(session.accountId).toBe(12345); }); test('should throw error when not authenticated', () => { expect(() => authManager.getSession()).toThrow(AuthenticationError); expect(() => authManager.getCookieHeader()).toThrow(AuthenticationError); }); test('should get cookie header string', async () => { // Setup mocks and login mock.onGet().reply(200, '<html><input id="_csrf" value="csrf" /></html>'); mock.onPost('https://test.whatap.io/account/login').reply(200, 'ok', { 'set-cookie': ['wa=my-wa-cookie; Path=/', 'JSESSIONID=my-session; Path=/'] as any, }); mock.onPost('https://test.whatap.io/mobile/api/login').reply(200, { accountId: 12345, apiToken: 'token', }); await authManager.login(mockCredentials); const cookieHeader = authManager.getCookieHeader(); expect(cookieHeader).toBe('WHATAP=my-wa-cookie; JSESSIONID=my-session'); }); }); describe('isAuthenticated', () => { test('should return false when no session', () => { expect(authManager.isAuthenticated()).toBe(false); }); test('should return true when session exists and not expired', async () => { // Setup mocks and login mock.onGet().reply(200, '<html><input id="_csrf" value="csrf" /></html>'); mock.onPost('https://test.whatap.io/account/login').reply(200, 'ok', { 'set-cookie': ['wa=wa; Path=/', 'JSESSIONID=js; Path=/'] as any, }); mock.onPost('https://test.whatap.io/mobile/api/login').reply(200, { accountId: 12345, apiToken: 'token', }); await authManager.login(mockCredentials); expect(authManager.isAuthenticated()).toBe(true); }); test('should return false when session expired', async () => { // Create expired session const expiredSession = { email: 'test@whatap.io', accountId: 12345, cookies: { wa: 'wa', jsessionid: 'js' }, apiToken: 'token', serviceUrl: 'https://test.whatap.io', createdAt: new Date(Date.now() - 25 * 60 * 60 * 1000), expiresAt: new Date(Date.now() - 1000), // Expired }; await sessionStore.save(expiredSession); await authManager.loadSession(); expect(authManager.isAuthenticated()).toBe(false); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/devload/whatap-mxql-cli'

If you have feedback or need assistance with the MCP directory API, please join our Discord server