import { describe, it, expect } from 'vitest';
import { hashPassword, verifyPassword } from './password.js';

describe('hashPassword', () => {
  it('returns a string different from input', () => {
    const result = hashPassword('testpassword');
    expect(result).not.toBe('testpassword');
    expect(result).toBeTypeOf('string');
  });

  it('result starts with bcrypt hash prefix', () => {
    const result = hashPassword('mypassword');
    expect(result.startsWith('$2a$') || result.startsWith('$2b$')).toBe(true);
  });

  it('throws on empty string', () => {
    expect(() => hashPassword('')).toThrow('Password cannot be empty');
  });

  it('throws on null/undefined', () => {
    expect(() => hashPassword(null)).toThrow();
    expect(() => hashPassword(undefined)).toThrow();
  });
});

describe('verifyPassword', () => {
  it('returns true for correct password', () => {
    const hash = hashPassword('correct');
    expect(verifyPassword('correct', hash)).toBe(true);
  });

  it('returns false for wrong password', () => {
    const hash = hashPassword('original');
    expect(verifyPassword('wrong', hash)).toBe(false);
  });

  it('returns false for null/undefined inputs', () => {
    expect(verifyPassword(null, 'hash')).toBe(false);
    expect(verifyPassword('pw', null)).toBe(false);
  });

  it('different hashes for same password (salt)', () => {
    const h1 = hashPassword('same');
    const h2 = hashPassword('same');
    expect(h1).not.toBe(h2);
    expect(verifyPassword('same', h1)).toBe(true);
    expect(verifyPassword('same', h2)).toBe(true);
  });
});
