Files
kappa f5df0c0ffe feat: add optimistic locking and improve type safety
- Implement optimistic locking for deposit balance updates
  - Prevent race conditions in concurrent deposit requests
  - Add automatic retry with exponential backoff (max 3 attempts)
  - Add version column to user_deposits table

- Improve type safety across codebase
  - Add explicit types for Namecheap API responses
  - Add typed function arguments (ManageDepositArgs, etc.)
  - Remove `any` types from deposit-agent and tool files

- Add reconciliation job for balance integrity verification
  - Compare user_deposits.balance vs SUM(confirmed transactions)
  - Alert admin on discrepancy detection

- Set up test environment with Vitest + Miniflare
  - Add 50+ test cases for deposit system
  - Add helper functions for test data creation

- Update documentation
  - Add migration guide for version columns
  - Document optimistic locking patterns

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 23:23:09 +09:00

5.0 KiB

Unit Tests for telegram-bot-workers

이 디렉토리는 Cloudflare Workers 환경에서 실행되는 Telegram Bot의 단위 테스트를 포함합니다.

테스트 프레임워크

  • Vitest: 빠르고 현대적인 테스트 프레임워크
  • Miniflare: Cloudflare Workers 로컬 시뮬레이터 (D1, KV 지원)
  • Coverage: V8 Coverage Provider

설치

npm install

필요한 의존성:

  • vitest - 테스트 러너
  • miniflare - Workers 환경 시뮬레이션
  • @cloudflare/vitest-pool-workers - Vitest Workers 통합
  • @vitest/coverage-v8 - 커버리지 리포트

실행

# 모든 테스트 실행
npm test

# Watch 모드 (파일 변경 감지)
npm run test:watch

# 커버리지 리포트 생성
npm run test:coverage

테스트 파일

deposit-agent.test.ts

예치금 시스템 (deposit-agent.ts) 테스트

커버리지:

  • get_balance: 신규 사용자 0원, 기존 잔액 조회
  • get_account_info: 은행 계좌 정보 반환
  • request_deposit: 음수/0원 거부, 7글자 매칭, 자동/수동 처리
  • get_transactions: 거래 내역 조회, 정렬, LIMIT 처리
  • cancel_transaction: 본인/관리자 권한, 상태 검증
  • confirm_deposit: 잔액 증가, Batch 실패 처리
  • reject_deposit: 거래 거절
  • get_pending_list: 관리자 전용
  • Concurrency: 동시 요청 처리, Race condition
  • Edge Cases: 큰 금액, 특수문자, 짧은 이름

테스트 수: 50+개

setup.ts

테스트 환경 초기화 및 헬퍼 함수

기능:

  • D1 Database 스키마 초기화 (in-memory SQLite)
  • 각 테스트 후 데이터 정리 (스키마 유지)
  • 테스트 데이터 생성 헬퍼 함수

헬퍼 함수:

createTestUser(telegramId, username)
createBankNotification(depositorName, amount)
createDepositTransaction(userId, amount, status, depositorName?)
getTestDB()

테스트 작성 가이드

기본 구조

import { describe, it, expect, beforeEach } from 'vitest';
import { executeDepositFunction } from '../src/deposit-agent';
import { createTestUser, getTestDB } from './setup';

describe('Feature Name', () => {
  let testUserId: number;

  beforeEach(async () => {
    testUserId = await createTestUser('123456789', 'testuser');
  });

  it('should do something', async () => {
    const result = await executeDepositFunction('function_name', {
      param: 'value'
    }, {
      userId: testUserId,
      telegramUserId: '123456789',
      isAdmin: false,
      db: getTestDB()
    });

    expect(result).toHaveProperty('success', true);
  });
});

Mock 전략

D1 Database: Miniflare가 자동으로 in-memory SQLite 제공

환경 변수: vitest.config.ts에서 설정

environmentOptions: {
  bindings: {
    BOT_TOKEN: 'test-bot-token',
    WEBHOOK_SECRET: 'test-webhook-secret',
    DEPOSIT_ADMIN_ID: '999999999',
  }
}

외부 API Mock: vi.fn() 사용

const mockFetch = vi.fn().mockResolvedValue({
  ok: true,
  json: async () => ({ data: 'mocked' })
});

Batch 실패 시뮬레이션

const originalBatch = testContext.db.batch;
testContext.db.batch = vi.fn().mockResolvedValue([
  { success: true, meta: { changes: 1 } },
  { success: false, meta: { changes: 0 } }, // 실패
]);

await expect(someFunction()).rejects.toThrow('처리 실패');

// 복원
testContext.db.batch = originalBatch;

디버깅

Verbose 모드

npm test -- --reporter=verbose

특정 테스트만 실행

# 파일명으로 필터링
npm test deposit-agent

# 테스트 설명으로 필터링
npm test -- -t "should reject negative amounts"

로그 출력

테스트 내에서 console.log 사용 가능:

it('debugging test', async () => {
  console.log('Debug info:', result);
  expect(result).toBeDefined();
});

CI/CD 통합

GitHub Actions 예시:

- name: Run tests
  run: npm test

- name: Upload coverage
  uses: codecov/codecov-action@v3
  with:
    files: ./coverage/coverage-final.json

향후 계획

  • openai-service.ts - Function Calling 도구 테스트
  • summary-service.ts - 프로필 시스템 테스트
  • Integration Tests - 전체 워크플로우 테스트
  • E2E Tests - Telegram Bot API 통합 테스트

문제 해결

"Cannot find module" 에러

npm install

D1 스키마 초기화 실패

setup.ts에서 schema.sql 경로 확인:

const schemaPath = join(__dirname, '../schema.sql');

Miniflare 버전 충돌

package.json에서 버전 확인:

{
  "miniflare": "^3.20231030.0",
  "@cloudflare/vitest-pool-workers": "^0.1.0"
}

테스트 타임아웃

vitest.config.ts에서 타임아웃 증가:

test: {
  testTimeout: 10000, // 기본 5초 → 10초
}

참고 자료