/**
 * Security Utilities Tests
 */

import { describe, it, expect, beforeEach } from 'vitest'
import { validateAddress, generateSecureId } from '../../utils/security'
import { checkRateLimit } from '../../utils/rateLimiter'

describe('Security Utilities', () => {
  describe('validateAddress', () => {
    it('should validate a correct Ethereum address', () => {
      const address = '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'
      const result = validateAddress(address)
      expect(result.valid).toBe(true)
      expect(result.checksummed).toBeDefined()
    })

    it('should reject an invalid address', () => {
      const address = '0xInvalid'
      const result = validateAddress(address)
      expect(result.valid).toBe(false)
      expect(result.error).toBeDefined()
    })

    it('should handle empty string', () => {
      const result = validateAddress('')
      expect(result.valid).toBe(false)
    })
  })

  describe('generateSecureId', () => {
    it('should generate a unique ID', () => {
      const id1 = generateSecureId()
      const id2 = generateSecureId()
      expect(id1).not.toBe(id2)
      expect(id1.length).toBeGreaterThan(0)
    })

    it('should generate IDs with consistent format', () => {
      const id = generateSecureId()
      expect(typeof id).toBe('string')
    })
  })

  describe('checkRateLimit', () => {
    beforeEach(() => {
      // Clear rate limit storage
      localStorage.clear()
    })

    it('should allow actions within rate limit', () => {
      const result = checkRateLimit('test-action', 'default')
      expect(result.allowed).toBe(true)
    })

    it('should block actions exceeding rate limit', () => {
      // Perform actions up to limit
      for (let i = 0; i < 10; i++) {
        checkRateLimit(`test-action-${i}`, 'default')
      }
      
      // Fill up the rate limit for a specific action
      for (let i = 0; i < 10; i++) {
        checkRateLimit('test-action-limit', 'default')
      }
      
      // Next action should be blocked
      const result = checkRateLimit('test-action-limit', 'default')
      expect(result.allowed).toBe(false)
    })

    it('should reset after time window', async () => {
      // Fill up rate limit
      for (let i = 0; i < 5; i++) {
        checkRateLimit('test-action', 5, 60000)
      }
      
      // Wait for time window (using real time in test)
      await new Promise(resolve => setTimeout(resolve, 100))
      
      // Note: In a real implementation, rate limiting would check actual time
      // This test demonstrates the concept
      const result = checkRateLimit('test-action-2', 5, 60000)
      expect(result).toBe(true) // Different action key should work
    })
  })
})
