const knex = require('knex');
const migration = require('../src/database/migrations/knex/2026073000000000_users_gender');

describe('users gender migration', () => {
  let database;

  beforeEach(async () => {
    database = knex({
      client: 'better-sqlite3',
      connection: { filename: ':memory:' },
      useNullAsDefault: true,
    });
    await database.schema.createTable('users', (table) => {
      table.increments('id');
      table.text('email').notNullable();
    });
  });

  afterEach(async () => {
    await database.destroy();
  });

  it('adds a constrained gender field to legacy user tables', async () => {
    await migration.up(database);

    expect(await database.schema.hasColumn('users', 'gender')).toBe(true);
    await database('users').insert({ email: 'valid@example.com', gender: 'female' });
    await expect(database('users').insert({ email: 'invalid@example.com', gender: 'invalid' })).rejects.toThrow();
  });

  it('enforces valid values when an unconstrained gender field already exists', async () => {
    await database.schema.alterTable('users', (table) => {
      table.text('gender');
    });
    await database('users').insert([
      { email: 'uppercase@example.com', gender: 'Female' },
      { email: 'legacy-invalid@example.com', gender: 'unknown' },
    ]);

    await migration.up(database);

    expect((await database('users').where({ email: 'uppercase@example.com' }).first()).gender).toBe('female');
    expect((await database('users').where({ email: 'legacy-invalid@example.com' }).first()).gender).toBeNull();
    await database('users').insert({ email: 'valid-existing@example.com', gender: 'other' });
    await expect(database('users').insert({ email: 'invalid-existing@example.com', gender: 'invalid' })).rejects.toThrow();
  });

  it('is idempotent when gender already exists', async () => {
    await migration.up(database);
    await expect(migration.up(database)).resolves.toBeUndefined();
  });
});
