const Street = require('../../models/Street'); const User = require('../../models/User'); const couchdbService = require('../../services/couchdbService'); describe('Street Model', () => { beforeAll(async () => { await couchdbService.initialize(); }); describe('Schema Validation', () => { it('should create a valid street', async () => { const user = await User.create({ name: 'Test User', email: 'test@example.com', password: 'password123', }); const streetData = { name: 'Main Street', location: { type: 'Point', coordinates: [-73.935242, 40.730610], }, city: 'New York', state: 'NY', }; const street = await Street.create(streetData); const savedStreet = await street.save(); expect(savedStreet._id).toBeDefined(); expect(savedStreet.name).toBe(streetData.name); expect(savedStreet.location.type).toBe('Point'); expect(savedStreet.location.coordinates).toEqual(streetData.location.coordinates); expect(savedStreet.status).toBe('available'); }); it('should require name field', async () => { let error; try { await Street.create({ location: { type: 'Point', coordinates: [-73.935242, 40.730610], }, city: 'New York', state: 'NY', }); } catch (err) { error = err; } expect(error).toBeDefined(); expect(error.message).toContain('name'); }); it('should require location field', async () => { let error; try { await Street.create({ name: 'Main Street', city: 'New York', state: 'NY', }); } catch (err) { error = err; } expect(error).toBeDefined(); expect(error.message).toContain('location'); }); it('should not require adoptedBy field', async () => { const street = await Street.create({ name: 'Main Street', location: { type: 'Point', coordinates: [-73.935242, 40.730610], }, city: 'New York', state: 'NY', }); expect(street._id).toBeDefined(); expect(street.adoptedBy).toBeNull(); expect(street.status).toBe('available'); }); }); describe('GeoJSON Location', () => { it('should store Point type correctly', async () => { const street = await Street.create({ name: 'Geo Street', location: { type: 'Point', coordinates: [-122.4194, 37.7749], // San Francisco }, city: 'San Francisco', state: 'CA', }); expect(street.location.type).toBe('Point'); expect(street.location.coordinates).toEqual([-122.4194, 37.7749]); expect(street.location.coordinates[0]).toBe(-122.4194); // longitude expect(street.location.coordinates[1]).toBe(37.7749); // latitude }); it('should support geospatial queries', async () => { const street = await Street.create({ name: 'NYC Street', location: { type: 'Point', coordinates: [-73.935242, 40.730610], }, city: 'New York', state: 'NY', }); // Test findNearby method const nearbyStreets = await Street.findNearby([-73.935242, 40.730610], 1000); expect(nearbyStreets.length).toBeGreaterThan(0); expect(nearbyStreets[0].name).toBe('NYC Street'); }); }); describe('Status Field', () => { it('should default status to available', async () => { const street = await Street.create({ name: 'Status Street', location: { type: 'Point', coordinates: [-73.935242, 40.730610], }, city: 'New York', state: 'NY', }); expect(street.status).toBe('available'); }); it('should allow setting custom status', async () => { const street = await Street.create({ name: 'Custom Status Street', location: { type: 'Point', coordinates: [-73.935242, 40.730610], }, city: 'New York', state: 'NY', status: 'adopted', }); expect(street.status).toBe('adopted'); }); }); describe('Timestamps', () => { it('should automatically set createdAt and updatedAt', async () => { const street = await Street.create({ name: 'Timestamp Street', location: { type: 'Point', coordinates: [-73.935242, 40.730610], }, city: 'New York', state: 'NY', }); expect(street.createdAt).toBeDefined(); expect(street.updatedAt).toBeDefined(); expect(typeof street.createdAt).toBe('string'); expect(typeof street.updatedAt).toBe('string'); }); }); describe('Relationships', () => { it('should reference User model through adoptedBy', async () => { const user = await User.create({ name: 'Adopter User', email: 'adopter@example.com', password: 'password123', }); const street = await Street.create({ name: 'Relationship Street', location: { type: 'Point', coordinates: [-73.935242, 40.730610], }, city: 'New York', state: 'NY', adoptedBy: { userId: user._id, name: user.name, profilePicture: user.profilePicture || '' }, status: 'adopted', }); const populatedStreet = await Street.findById(street._id); await populatedStreet.populate('adoptedBy'); expect(populatedStreet.adoptedBy).toBeDefined(); expect(populatedStreet.adoptedBy.name).toBe('Adopter User'); }); }); describe('Coordinates Format', () => { it('should accept valid longitude and latitude', async () => { const validCoordinates = [ [-180, -90], // min values [180, 90], // max values [0, 0], // origin [-74.006, 40.7128], // NYC ]; for (const coords of validCoordinates) { const street = await Street.create({ name: `Street at ${coords.join(',')}`, location: { type: 'Point', coordinates: coords, }, city: 'Test City', state: 'TS', }); expect(street.location.coordinates).toEqual(coords); } }); }); });