import { hashRoundsFor, PRODUCTION_ROUNDS, TEST_ROUNDS } from '../../src/passwordHashing'; // The cost factor is a security property, and the whole point of lowering it // under test is that it must not be lowered anywhere else. Asserted rather than // read, so a later edit that widens the test branch fails here first. describe('hashRoundsFor', () => { it('uses the cheap cost under test', () => { expect(hashRoundsFor('test')).toBe(TEST_ROUNDS); }); it('uses the real cost in production', () => { expect(hashRoundsFor('production')).toBe(PRODUCTION_ROUNDS); }); // The container sets NODE_ENV=production, but a bare `node dist/server.js` // does not set it at all. Absent must mean the strong cost, never the cheap // one — defaulting the other way is how a weak hash reaches real passwords. it('uses the real cost when NODE_ENV is unset', () => { expect(hashRoundsFor(undefined)).toBe(PRODUCTION_ROUNDS); }); it('uses the real cost for any value that is not exactly "test"', () => { for (const value of ['development', 'staging', 'Test', 'TEST', 'testing', '']) { expect(hashRoundsFor(value)).toBe(PRODUCTION_ROUNDS); } }); // Pinning the numbers themselves. Without this the tests above pass while // both constants drift to something useless. it('keeps the production cost at 12', () => { expect(PRODUCTION_ROUNDS).toBe(12); }); it('keeps the test cost cheap enough to be worth doing', () => { expect(TEST_ROUNDS).toBeLessThanOrEqual(6); // bcrypt refuses a cost below 4. expect(TEST_ROUNDS).toBeGreaterThanOrEqual(4); }); });