forked from elizaOS/eliza
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adding tests for instagram client (elizaOS#2454)
Co-authored-by: Sayo <hi@sayo.wtf>
- Loading branch information
1 parent
9e0af0e
commit 5a85d7f
Showing
3 changed files
with
215 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { describe, it, expect, vi } from 'vitest'; | ||
import { validateInstagramConfig, instagramEnvSchema } from '../src/environment'; | ||
import { IAgentRuntime } from '@elizaos/core'; | ||
|
||
describe('Instagram Environment Configuration', () => { | ||
const mockRuntime: IAgentRuntime = { | ||
getSetting: vi.fn(), | ||
} as unknown as IAgentRuntime; | ||
|
||
it('validates correct Instagram configuration', async () => { | ||
const validConfig = { | ||
INSTAGRAM_DRY_RUN: false, | ||
INSTAGRAM_USERNAME: 'test_user', | ||
INSTAGRAM_PASSWORD: 'test_password', | ||
INSTAGRAM_APP_ID: 'test_app_id', | ||
INSTAGRAM_APP_SECRET: 'test_app_secret', | ||
INSTAGRAM_POST_INTERVAL_MIN: 60, | ||
INSTAGRAM_POST_INTERVAL_MAX: 120, | ||
INSTAGRAM_ENABLE_ACTION_PROCESSING: false, | ||
INSTAGRAM_ACTION_INTERVAL: 5, | ||
INSTAGRAM_MAX_ACTIONS: 1, | ||
}; | ||
|
||
vi.mocked(mockRuntime.getSetting).mockImplementation((key: string) => { | ||
if (key === 'INSTAGRAM_DRY_RUN') return 'false'; | ||
if (key === 'INSTAGRAM_ENABLE_ACTION_PROCESSING') return 'false'; | ||
return validConfig[key as keyof typeof validConfig]; | ||
}); | ||
|
||
const config = await validateInstagramConfig(mockRuntime); | ||
expect(config).toEqual(validConfig); | ||
}); | ||
|
||
it('validates configuration with optional business account', async () => { | ||
const validConfig = { | ||
INSTAGRAM_DRY_RUN: false, | ||
INSTAGRAM_USERNAME: 'test_user', | ||
INSTAGRAM_PASSWORD: 'test_password', | ||
INSTAGRAM_APP_ID: 'test_app_id', | ||
INSTAGRAM_APP_SECRET: 'test_app_secret', | ||
INSTAGRAM_BUSINESS_ACCOUNT_ID: 'business_123', | ||
INSTAGRAM_POST_INTERVAL_MIN: 60, | ||
INSTAGRAM_POST_INTERVAL_MAX: 120, | ||
INSTAGRAM_ENABLE_ACTION_PROCESSING: false, | ||
INSTAGRAM_ACTION_INTERVAL: 5, | ||
INSTAGRAM_MAX_ACTIONS: 1, | ||
}; | ||
|
||
vi.mocked(mockRuntime.getSetting).mockImplementation((key: string) => { | ||
if (key === 'INSTAGRAM_DRY_RUN') return 'false'; | ||
if (key === 'INSTAGRAM_ENABLE_ACTION_PROCESSING') return 'false'; | ||
return validConfig[key as keyof typeof validConfig]; | ||
}); | ||
|
||
const config = await validateInstagramConfig(mockRuntime); | ||
expect(config).toEqual(validConfig); | ||
}); | ||
|
||
it('throws error for invalid username format', async () => { | ||
const invalidConfig = { | ||
INSTAGRAM_DRY_RUN: false, | ||
INSTAGRAM_USERNAME: 'invalid@username', // Invalid characters | ||
INSTAGRAM_PASSWORD: 'test_password', | ||
INSTAGRAM_APP_ID: 'test_app_id', | ||
INSTAGRAM_APP_SECRET: 'test_app_secret', | ||
}; | ||
|
||
vi.mocked(mockRuntime.getSetting).mockImplementation((key: string) => { | ||
if (key === 'INSTAGRAM_DRY_RUN') return 'false'; | ||
return invalidConfig[key as keyof typeof invalidConfig]; | ||
}); | ||
|
||
await expect(validateInstagramConfig(mockRuntime)).rejects.toThrow(); | ||
}); | ||
|
||
it('throws error for missing required fields', async () => { | ||
const invalidConfig = { | ||
INSTAGRAM_DRY_RUN: false, | ||
INSTAGRAM_USERNAME: 'test_user', | ||
// Missing password and other required fields | ||
}; | ||
|
||
vi.mocked(mockRuntime.getSetting).mockImplementation((key: string) => { | ||
if (key === 'INSTAGRAM_DRY_RUN') return 'false'; | ||
return invalidConfig[key as keyof typeof invalidConfig]; | ||
}); | ||
|
||
await expect(validateInstagramConfig(mockRuntime)).rejects.toThrow(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import { describe, it, expect, vi, beforeEach } from 'vitest'; | ||
import { InstagramClientInterface } from '../src'; | ||
import { IAgentRuntime, elizaLogger } from '@elizaos/core'; | ||
import { InstagramInteractionService } from '../src/services/interaction'; | ||
import { InstagramPostService } from '../src/services/post'; | ||
|
||
// Mock dependencies | ||
vi.mock('@elizaos/core', async (importOriginal) => { | ||
const actual = await importOriginal(); | ||
return { | ||
...actual, | ||
elizaLogger: { | ||
log: vi.fn(), | ||
error: vi.fn(), | ||
}, | ||
parseBooleanFromText: (value: string | undefined) => value === 'true', | ||
}; | ||
}); | ||
|
||
// Mock service instances | ||
const mockPostService = { | ||
start: vi.fn().mockResolvedValue(undefined), | ||
}; | ||
|
||
const mockInteractionService = { | ||
start: vi.fn().mockResolvedValue(undefined), | ||
}; | ||
|
||
vi.mock('../src/lib/auth', () => ({ | ||
initializeClient: vi.fn().mockResolvedValue({ | ||
ig: {}, | ||
config: { | ||
INSTAGRAM_DRY_RUN: false, | ||
INSTAGRAM_ENABLE_ACTION_PROCESSING: true, | ||
}, | ||
}), | ||
})); | ||
|
||
vi.mock('../src/services/post', () => ({ | ||
InstagramPostService: vi.fn().mockImplementation(() => mockPostService), | ||
})); | ||
|
||
vi.mock('../src/services/interaction', () => ({ | ||
InstagramInteractionService: vi.fn().mockImplementation(() => mockInteractionService), | ||
})); | ||
|
||
describe('InstagramClientInterface', () => { | ||
let mockRuntime: IAgentRuntime; | ||
const mockConfig = { | ||
INSTAGRAM_DRY_RUN: false, | ||
INSTAGRAM_USERNAME: 'test_user', | ||
INSTAGRAM_PASSWORD: 'test_password', | ||
INSTAGRAM_APP_ID: 'test_app_id', | ||
INSTAGRAM_APP_SECRET: 'test_app_secret', | ||
INSTAGRAM_POST_INTERVAL_MIN: 60, | ||
INSTAGRAM_POST_INTERVAL_MAX: 120, | ||
INSTAGRAM_ENABLE_ACTION_PROCESSING: true, | ||
INSTAGRAM_ACTION_INTERVAL: 5, | ||
INSTAGRAM_MAX_ACTIONS: 1, | ||
}; | ||
|
||
beforeEach(() => { | ||
vi.clearAllMocks(); | ||
mockRuntime = { | ||
getSetting: vi.fn((key: string) => { | ||
if (key === 'INSTAGRAM_DRY_RUN' || key === 'INSTAGRAM_ENABLE_ACTION_PROCESSING') { | ||
return String(mockConfig[key as keyof typeof mockConfig]); | ||
} | ||
return mockConfig[key as keyof typeof mockConfig]; | ||
}), | ||
} as unknown as IAgentRuntime; | ||
}); | ||
|
||
it('starts successfully with all services', async () => { | ||
const result = await InstagramClientInterface.start(mockRuntime); | ||
|
||
expect(result).toBeDefined(); | ||
expect(result.post).toBeDefined(); | ||
expect(result.interaction).toBeDefined(); | ||
expect(InstagramPostService).toHaveBeenCalled(); | ||
expect(InstagramInteractionService).toHaveBeenCalled(); | ||
expect(result.post.start).toHaveBeenCalled(); | ||
expect(result.interaction.start).toHaveBeenCalled(); | ||
expect(elizaLogger.log).toHaveBeenCalledWith('Instagram client configuration validated'); | ||
expect(elizaLogger.log).toHaveBeenCalledWith('Instagram client initialized'); | ||
expect(elizaLogger.log).toHaveBeenCalledWith('Instagram post service started'); | ||
expect(elizaLogger.log).toHaveBeenCalledWith('Instagram interaction service started'); | ||
}); | ||
|
||
it('starts in dry-run mode', async () => { | ||
const dryRunConfig = { ...mockConfig, INSTAGRAM_DRY_RUN: true }; | ||
mockRuntime.getSetting = vi.fn((key: string) => { | ||
if (key === 'INSTAGRAM_DRY_RUN') return 'true'; | ||
if (key === 'INSTAGRAM_ENABLE_ACTION_PROCESSING') return String(dryRunConfig.INSTAGRAM_ENABLE_ACTION_PROCESSING); | ||
return dryRunConfig[key as keyof typeof dryRunConfig]; | ||
}); | ||
|
||
const result = await InstagramClientInterface.start(mockRuntime); | ||
|
||
expect(result).toBeDefined(); | ||
expect(elizaLogger.log).toHaveBeenCalledWith('Instagram client running in dry-run mode'); | ||
expect(mockPostService.start).not.toHaveBeenCalled(); | ||
expect(mockInteractionService.start).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('handles errors during startup', async () => { | ||
const error = new Error('Startup failed'); | ||
vi.mocked(mockRuntime.getSetting).mockImplementation(() => { | ||
throw error; | ||
}); | ||
|
||
await expect(InstagramClientInterface.start(mockRuntime)).rejects.toThrow('Startup failed'); | ||
expect(elizaLogger.error).toHaveBeenCalledWith('Failed to start Instagram client:', error); | ||
}); | ||
|
||
it('stops gracefully', async () => { | ||
await InstagramClientInterface.stop(mockRuntime); | ||
expect(elizaLogger.log).toHaveBeenCalledWith('Stopping Instagram client services...'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters