UNPKG

matterbridge-roborock-vacuum-plugin

Version:
156 lines 9.68 kB
import { beforeEach, describe, expect, it, vi } from 'vitest'; import { AuthenticationError, InvalidCredentialsError, TokenExpiredError, VerificationCodeExpiredError, } from '../../errors/index.js'; import { AuthenticationService } from '../../services/authenticationService.js'; import { asPartial, makeLogger } from '../testUtils.js'; const mockAuthGateway = asPartial({ requestVerificationCode: vi.fn(), authenticate2FA: vi.fn(), authenticatePassword: vi.fn(), refreshToken: vi.fn(), }); const mockLogger = makeLogger(); let service; function createMockUserData(username = 'test@example.com') { return { uid: 'test-uid', tokentype: 'Bearer', token: 'test-token', rruid: 'rr-uid', region: 'us', countrycode: 'US', country: 'United States', nickname: 'Test User', username, rriot: { u: 'test-user', s: 'test-secret', h: 'test-host', k: 'test-key', r: { a: 'test-region-a', m: 'test-mqtt' }, }, }; } beforeEach(() => { vi.clearAllMocks(); service = new AuthenticationService(mockAuthGateway, mockLogger); }); describe('AuthenticationService', () => { describe('loginWithVerificationCode', () => { it('should login with verification code', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.authenticate2FA).mockResolvedValue(userData); const result = await service.loginWithVerificationCode('test@example.com', '123456'); expect(result).toBe(userData); expect(mockAuthGateway.authenticate2FA).toHaveBeenCalledWith('test@example.com', '123456'); }); it('should throw VerificationCodeExpiredError when error message contains expired', async () => { vi.mocked(mockAuthGateway.authenticate2FA).mockRejectedValue(new Error('Code expired')); await expect(service.loginWithVerificationCode('test@example.com', '123456')).rejects.toThrow(VerificationCodeExpiredError); }); it('should throw VerificationCodeExpiredError when error message contains invalid', async () => { vi.mocked(mockAuthGateway.authenticate2FA).mockRejectedValue(new Error('Code invalid')); await expect(service.loginWithVerificationCode('test@example.com', '123456')).rejects.toThrow(VerificationCodeExpiredError); }); it('should throw generic AuthenticationError for other errors', async () => { vi.mocked(mockAuthGateway.authenticate2FA).mockRejectedValue(new Error('Network error')); await expect(service.loginWithVerificationCode('test@example.com', '123456')).rejects.toThrow(AuthenticationError); await expect(service.loginWithVerificationCode('test@example.com', '123456')).rejects.toThrow('Authentication failed'); }); it('should log debug message when authenticating', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.authenticate2FA).mockResolvedValue(userData); await service.loginWithVerificationCode('test@example.com', '123456'); expect(mockLogger.debug).toHaveBeenCalledWith('Authenticating with verification code for email:', 'test@example.com'); }); it('should log notice when authentication succeeds', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.authenticate2FA).mockResolvedValue(userData); await service.loginWithVerificationCode('test@example.com', '123456'); expect(mockLogger.notice).toHaveBeenCalledWith('Successfully authenticated with verification code'); }); }); describe('loginWithCachedToken', () => { it('should login with cached token', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.refreshToken).mockResolvedValue(userData); const result = await service.loginWithCachedToken('test@example.com', userData); expect(result).toBe(userData); expect(mockAuthGateway.refreshToken).toHaveBeenCalledWith(userData); }); it('should set username on userData before refreshing token', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.refreshToken).mockImplementation((data) => { expect(data.username).toBe('test@example.com'); return Promise.resolve(data); }); await service.loginWithCachedToken('test@example.com', userData); }); it('should throw TokenExpiredError when error message contains expired', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.refreshToken).mockRejectedValue(new Error('Token expired')); await expect(service.loginWithCachedToken('test@example.com', userData)).rejects.toThrow(TokenExpiredError); }); it('should throw TokenExpiredError when error message contains token', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.refreshToken).mockRejectedValue(new Error('Invalid token')); await expect(service.loginWithCachedToken('test@example.com', userData)).rejects.toThrow(TokenExpiredError); }); it('should throw generic AuthenticationError for other errors', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.refreshToken).mockRejectedValue(new Error('Network error')); await expect(service.loginWithCachedToken('test@example.com', userData)).rejects.toThrow(AuthenticationError); await expect(service.loginWithCachedToken('test@example.com', userData)).rejects.toThrow('Session expired or invalid'); }); it('should log debug message when authenticating', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.refreshToken).mockResolvedValue(userData); await service.loginWithCachedToken('test@example.com', userData); expect(mockLogger.debug).toHaveBeenCalledWith('Authenticating with cached token for user:', 'test@example.com'); }); it('should log notice when authentication succeeds', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.refreshToken).mockResolvedValue(userData); await service.loginWithCachedToken('test@example.com', userData); expect(mockLogger.notice).toHaveBeenCalledWith('[loginWithCachedToken]: Successfully authenticated with cached token'); }); }); describe('loginWithPassword', () => { it('should login with password', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.authenticatePassword).mockResolvedValue(userData); const result = await service.loginWithPassword('test@example.com', 'pw'); expect(result).toBe(userData); expect(mockAuthGateway.authenticatePassword).toHaveBeenCalledWith('test@example.com', 'pw'); }); it('should throw InvalidCredentialsError when error message contains invalid', async () => { vi.mocked(mockAuthGateway.authenticatePassword).mockRejectedValue(new Error('invalid password')); await expect(service.loginWithPassword('test@example.com', 'pw')).rejects.toThrow(InvalidCredentialsError); }); it('should throw InvalidCredentialsError when error message contains incorrect', async () => { vi.mocked(mockAuthGateway.authenticatePassword).mockRejectedValue(new Error('incorrect credentials')); await expect(service.loginWithPassword('test@example.com', 'pw')).rejects.toThrow(InvalidCredentialsError); }); it('should throw InvalidCredentialsError when error message contains wrong', async () => { vi.mocked(mockAuthGateway.authenticatePassword).mockRejectedValue(new Error('wrong password')); await expect(service.loginWithPassword('test@example.com', 'pw')).rejects.toThrow(InvalidCredentialsError); }); it('should throw generic AuthenticationError for other errors', async () => { vi.mocked(mockAuthGateway.authenticatePassword).mockRejectedValue(new Error('Network error')); await expect(service.loginWithPassword('test@example.com', 'pw')).rejects.toThrow(AuthenticationError); await expect(service.loginWithPassword('test@example.com', 'pw')).rejects.toThrow('Authentication failed. Please use verification code login.'); }); it('should log debug when authenticating with password', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.authenticatePassword).mockResolvedValue(userData); await service.loginWithPassword('test@example.com', 'pw'); expect(mockLogger.debug).toHaveBeenCalledWith('Authenticating with password for user:', 'test@example.com'); }); it('should log notice when password authentication succeeds', async () => { const userData = createMockUserData(); vi.mocked(mockAuthGateway.authenticatePassword).mockResolvedValue(userData); await service.loginWithPassword('test@example.com', 'pw'); expect(mockLogger.notice).toHaveBeenCalledWith('Successfully authenticated with password'); }); }); }); //# sourceMappingURL=authenticationService.test.js.map