import { validateHubForm } from '@/lib/hubForm'; /** * A hub in this console is a BASE to a rider. * * The bug these tests exist to prevent is already in production data: of the 18 * hubs live today, one carries no address and no coordinates. Only `hubname` * and `applocationid` were ever validated, so a base could be saved that the * rider app can name but cannot route anyone to — Navigate does nothing without * a pin, and a rider standing outside an industrial estate has nothing to read * without an address. * * The backend hands six fields to the rider app for a base. Five of six is not * "mostly there"; it is a rider with a parcel and no way to deliver it. */ const VALID = { hubname: 'Coimbatore Gandhipuram Hub', applocationid: 1, address: '14 Avinashi Road, Peelamedu, Coimbatore', pincode: '641004', latitude: '11.0168', longitude: '76.9558' }; describe('validateHubForm', () => { describe('a complete base', () => { it('should accept a form carrying all six rider-facing fields', () => { const { errors, isValid } = validateHubForm(VALID); expect(errors).toEqual({}); expect(isValid).toBe(true); }); it('should hand back coordinates already coerced, so the caller does not re-parse', () => { const { values } = validateHubForm(VALID); expect(values.latitude).toBe(11.0168); expect(values.longitude).toBe(76.9558); expect(values.applocationid).toBe(1); }); it('should accept a southern or western hemisphere base', () => { // Nothing in the range check may assume India. expect(validateHubForm({ ...VALID, latitude: '-33.8688', longitude: '-70.6693' }).isValid).toBe(true); }); }); describe('the fields that were never checked', () => { it('should reject a base with no address, because the rider reads it at the gate', () => { const { errors, isValid } = validateHubForm({ ...VALID, address: '' }); expect(isValid).toBe(false); expect(errors.address).toBeTruthy(); }); it('should reject whitespace as an address', () => { expect(validateHubForm({ ...VALID, address: ' ' }).errors.address).toBeTruthy(); }); it('should reject a base with no pincode', () => { expect(validateHubForm({ ...VALID, pincode: '' }).errors.pincode).toBeTruthy(); }); it('should reject a base with no coordinates, because Navigate cannot work', () => { const { errors, isValid } = validateHubForm({ ...VALID, latitude: '', longitude: '' }); expect(isValid).toBe(false); expect(errors.latitude).toBeTruthy(); expect(errors.longitude).toBeTruthy(); }); it('should treat 0,0 as unset rather than as a location', () => { // The previous code coerced an empty coordinate to 0 and sent it. 0,0 is // in the Gulf of Guinea; it is always an unset value, never a base. const { errors } = validateHubForm({ ...VALID, latitude: '0', longitude: '0' }); expect(errors.latitude).toBeTruthy(); expect(errors.longitude).toBeTruthy(); }); it('should reject a single missing coordinate, not just both', () => { // Half a pin is no pin. expect(validateHubForm({ ...VALID, latitude: '' }).isValid).toBe(false); expect(validateHubForm({ ...VALID, longitude: '' }).isValid).toBe(false); }); it('should reject coordinates outside the possible range', () => { expect(validateHubForm({ ...VALID, latitude: '91' }).errors.latitude).toBeTruthy(); expect(validateHubForm({ ...VALID, latitude: '-91' }).errors.latitude).toBeTruthy(); expect(validateHubForm({ ...VALID, longitude: '181' }).errors.longitude).toBeTruthy(); expect(validateHubForm({ ...VALID, longitude: '-181' }).errors.longitude).toBeTruthy(); }); it('should reject a coordinate that is not a number at all', () => { expect(validateHubForm({ ...VALID, latitude: 'near the flyover' }).errors.latitude).toBeTruthy(); }); it('should catch a swapped lat/lng pair for an Indian base', () => { // 76.9 as a latitude is inside the Arctic Circle. The range check is the // only thing standing between a transposed paste and a base in the sea. expect(validateHubForm({ ...VALID, latitude: '76.9558', longitude: '11.0168' }).isValid).toBe(true); // ...but a longitude beyond 90 in the latitude slot is caught outright. expect(validateHubForm({ ...VALID, latitude: '176.9558' }).errors.latitude).toBeTruthy(); }); }); describe('the checks that already existed', () => { it('should still require a name', () => { expect(validateHubForm({ ...VALID, hubname: '' }).errors.hubname).toBeTruthy(); expect(validateHubForm({ ...VALID, hubname: ' ' }).errors.hubname).toBeTruthy(); }); it('should still require a numeric city id', () => { expect(validateHubForm({ ...VALID, applocationid: '' }).errors.applocationid).toBeTruthy(); expect(validateHubForm({ ...VALID, applocationid: 'Coimbatore' }).errors.applocationid).toBeTruthy(); }); it('should accept city id 0, which is a valid id and not an absence', () => { expect(validateHubForm({ ...VALID, applocationid: 0 }).errors.applocationid).toBeUndefined(); }); }); describe('robustness', () => { it('should report every problem at once rather than one at a time', () => { // An operator fixing a form field by field, submit by submit, is a worse // experience than being told everything that is wrong. const { errors } = validateHubForm({}); expect(Object.keys(errors).sort()).toEqual( ['address', 'applocationid', 'hubname', 'latitude', 'longitude', 'pincode'].sort() ); }); it('should not throw on an empty or missing form', () => { expect(() => validateHubForm()).not.toThrow(); expect(validateHubForm().isValid).toBe(false); }); }); });