From 77260eca57c78a3c87097eb670f61dfa8294c4c2 Mon Sep 17 00:00:00 2001 From: Stephen Liu Date: Thu, 6 Nov 2025 17:43:21 -0500 Subject: [PATCH] fixed tests --- .../server/tests/integration/auth.test.mjs | 2 +- .../tests/integration/combineOrders.test.mjs | 2 +- .../integration/orders.combined.test.mjs | 164 +++++++++++------- .../server/tests/integration/orders.test.mjs | 2 +- 4 files changed, 108 insertions(+), 62 deletions(-) diff --git a/proj2/Ecobites/server/tests/integration/auth.test.mjs b/proj2/Ecobites/server/tests/integration/auth.test.mjs index 635f306a3..7c3c11990 100644 --- a/proj2/Ecobites/server/tests/integration/auth.test.mjs +++ b/proj2/Ecobites/server/tests/integration/auth.test.mjs @@ -4,7 +4,7 @@ import { connectDB, closeDB, clearDB } from '../../src/setupTests.js'; beforeAll(async () => { await connectDB(); -}); +}, 30000); // 30 second timeout for beforeAll afterEach(async () => { await clearDB(); diff --git a/proj2/Ecobites/server/tests/integration/combineOrders.test.mjs b/proj2/Ecobites/server/tests/integration/combineOrders.test.mjs index c7a677f99..2ad8c221b 100644 --- a/proj2/Ecobites/server/tests/integration/combineOrders.test.mjs +++ b/proj2/Ecobites/server/tests/integration/combineOrders.test.mjs @@ -7,7 +7,7 @@ import { connectDB, closeDB, clearDB } from '../../src/setupTests.js'; beforeAll(async () => { await connectDB(); -}); +}, 30000); // 30 second timeout for beforeAll afterEach(async () => { await clearDB(); diff --git a/proj2/Ecobites/server/tests/integration/orders.combined.test.mjs b/proj2/Ecobites/server/tests/integration/orders.combined.test.mjs index ffdd9804e..c27b750d6 100644 --- a/proj2/Ecobites/server/tests/integration/orders.combined.test.mjs +++ b/proj2/Ecobites/server/tests/integration/orders.combined.test.mjs @@ -18,45 +18,58 @@ const register = async (agent, payload) => { }; beforeAll(async () => { - await connectDB(); - - // Create agents for each user to maintain cookies - agents.restaurant = request.agent(app); - agents.driver = request.agent(app); - agents.c1 = request.agent(app); - agents.c2 = request.agent(app); - - // Restaurant - const rest = await register(agents.restaurant, { - name: 'Resto', email: 'r@e.com', password: 'secret12', role: 'restaurant', - restaurantName: 'Resto A', cuisine: 'Fusion' - }); - ids.restaurant = rest.user._id; - - // Driver (EV) - const drv = await register(agents.driver, { - name: 'Dan Driver', email: 'd@e.com', password: 'secret12', role: 'driver', - vehicleType: 'EV', licensePlate: 'ECO-123' - }); - ids.driver = drv.user._id; - - // Two customers nearby (same city/zip, with geo coords) - const cust1 = await register(agents.c1, { - name: 'Alice', email: 'a@e.com', password: 'secret12', role: 'customer', - address: { street: '1 Main', city: 'Raleigh', zipCode: '27606', coordinates: { lat: 35.78, lng: -78.67 } } - }); - ids.c1 = cust1.user._id; - - const cust2 = await register(agents.c2, { - name: 'Bob', email: 'b@e.com', password: 'secret12', role: 'customer', - address: { street: '2 Main', city: 'Raleigh', zipCode: '27606', coordinates: { lat: 35.7805, lng: -78.6705 } } - }); - ids.c2 = cust2.user._id; - - // Menu item owned by restaurant - const mi = await MenuItem.create({ name: 'Bowl', price: 10, description: 'Vegan bowl', restaurantId: ids.restaurant }); - menuItemId = mi._id.toString(); -}); + try { + await connectDB(); + + // Wait a bit for connection to stabilize + await new Promise(resolve => setTimeout(resolve, 1000)); + + // Create agents for each user to maintain cookies + agents.restaurant = request.agent(app); + agents.driver = request.agent(app); + agents.c1 = request.agent(app); + agents.c2 = request.agent(app); + + // Restaurant + const rest = await register(agents.restaurant, { + name: 'Resto', email: 'r@e.com', password: 'secret12', role: 'restaurant', + restaurantName: 'Resto A', cuisine: 'Fusion' + }); + ids.restaurant = rest.user._id; + + // Driver (EV) + const drv = await register(agents.driver, { + name: 'Dan Driver', email: 'd@e.com', password: 'secret12', role: 'driver', + vehicleType: 'EV', licensePlate: 'ECO-123' + }); + ids.driver = drv.user._id; + + // Two customers nearby (same city/zip, with geo coords) + const cust1 = await register(agents.c1, { + name: 'Alice', email: 'a@e.com', password: 'secret12', role: 'customer', + address: { street: '1 Main', city: 'Raleigh', zipCode: '27606', coordinates: { lat: 35.78, lng: -78.67 } } + }); + ids.c1 = cust1.user._id; + + const cust2 = await register(agents.c2, { + name: 'Bob', email: 'b@e.com', password: 'secret12', role: 'customer', + address: { street: '2 Main', city: 'Raleigh', zipCode: '27606', coordinates: { lat: 35.7805, lng: -78.6705 } } + }); + ids.c2 = cust2.user._id; + + // Menu item owned by restaurant + const mi = await MenuItem.create({ + name: 'Bowl', + price: 10, + description: 'Vegan bowl', + restaurantId: ids.restaurant + }); + menuItemId = mi._id.toString(); + } catch (error) { + console.error('BeforeAll setup error:', error); + throw error; + } +}, 30000); afterAll(async () => { await clearDB(); @@ -64,7 +77,11 @@ afterAll(async () => { }); afterEach(async () => { - await Order.deleteMany({}); + try { + await Order.deleteMany({}); + } catch (error) { + console.error('Error in afterEach:', error); + } }); describe('Orders end-to-end including combine and driver flows', () => { @@ -75,7 +92,12 @@ describe('Orders end-to-end including combine and driver flows', () => { customerId, restaurantId: ids.restaurant, items: [{ menuItemId, quantity: 2 }], - deliveryAddress: { street: '1 Main', city: 'Raleigh', zipCode: '27606', coordinates: coords }, + deliveryAddress: { + street: '1 Main', + city: 'Raleigh', + zipCode: '27606', + coordinates: coords + }, packagingPreference }); expect(res.status).toBe(201); @@ -85,52 +107,70 @@ describe('Orders end-to-end including combine and driver flows', () => { test('protect middleware rejects without token', async () => { const res = await request(app).get(`/api/orders/customer/${ids.c1}`); expect(res.status).toBe(401); - }); + }, 10000); // Add timeout to individual test test('customer cannot create order for another customer', async () => { const res = await agents.c1 .post('/api/orders') .send({ customerId: ids.c2, items: [{ menuItemId, quantity: 1 }] }); expect(res.status).toBe(403); - }); + }, 10000); test('create, ready, combine, available for drivers, assign and deliver with rewards', async () => { // Create two nearby orders - const o1 = await createOrderFor(agents.c1, ids.c1, 'reusable', { lat: 35.78, lng: -78.67 }); - const o2 = await createOrderFor(agents.c2, ids.c2, 'reusable', { lat: 35.7805, lng: -78.6705 }); + const o1 = await createOrderFor(agents.c1, ids.c1, 'reusable', { lat: 35.78, lng: -78.67 }); + const o2 = await createOrderFor(agents.c2, ids.c2, 'reusable', { lat: 35.7805, lng: -78.6705 }); + + // Add small delays between operations + await new Promise(resolve => setTimeout(resolve, 500)); // Restaurant marks both READY - const toReady = async (orderId) => agents.restaurant - .put(`/api/orders/${orderId}/status`) - .send({ status: 'READY' }); + const toReady = async (orderId) => { + const res = await agents.restaurant + .put(`/api/orders/${orderId}/status`) + .send({ status: 'READY' }); + return res; + }; + expect((await toReady(o1._id)).status).toBe(200); expect((await toReady(o2._id)).status).toBe(200); + // Wait for status updates to propagate + await new Promise(resolve => setTimeout(resolve, 500)); + // Customer1 combines with neighbors const comb = await agents.c1 .post('/api/orders/combine') .send({ customerId: ids.c1, radiusMeters: 1000 }); + expect(comb.status).toBe(200); expect(Array.isArray(comb.body.combinedOrders)).toBe(true); expect(comb.body.combinedOrders.length).toBeGreaterThanOrEqual(1); + comb.body.combinedOrders.forEach((ord) => { expect(ord.status).toBe('COMBINED'); expect(ord.combineGroupId).toBeTruthy(); }); - // Rewards were credited to both customers + // Wait for combine operation to complete + await new Promise(resolve => setTimeout(resolve, 500)); + + // Check rewards were credited to both customers const cu1 = await User.findById(ids.c1); const cu2 = await User.findById(ids.c2); expect((cu1.rewardPoints || 0)).toBeGreaterThanOrEqual(20); expect((cu2.rewardPoints || 0)).toBeGreaterThanOrEqual(20); // Driver sees available combined orders with enriched fields - const avail = await agents.driver - .get('/api/orders/available/drivers'); + const avail = await agents.driver.get('/api/orders/available/drivers'); expect(avail.status).toBe(200); expect(Array.isArray(avail.body)).toBe(true); - expect(avail.body.some(o => o.status === 'COMBINED')).toBe(true); - const one = avail.body.find(o => o.status === 'COMBINED'); + + // Find combined orders + const combinedOrders = avail.body.filter(o => o.status === 'COMBINED'); + expect(combinedOrders.length).toBeGreaterThan(0); + + const one = combinedOrders[0]; expect(one.restaurant).toBeTruthy(); expect(one.pickupAddress || one.deliveryAddress).toBeTruthy(); expect(one.customerName).toBeTruthy(); @@ -140,26 +180,32 @@ describe('Orders end-to-end including combine and driver flows', () => { .put(`/api/orders/${one._id}/status`) .send({ status: 'DRIVER_ASSIGNED', driverId: ids.driver }); expect(assign.status).toBe(200); - expect(assign.status).toBe(200); - // NEW: Group acceptance should assign all orders in the same combineGroupId - const groupAssigned = await Order.find({ combineGroupId: assign.body.combineGroupId }); + // Wait for group assignment to propagate + await new Promise(resolve => setTimeout(resolve, 500)); + + // Check group acceptance - all orders in same combineGroupId should be assigned + const groupAssigned = await Order.find({ combineGroupId: one.combineGroupId }); expect(groupAssigned.length).toBeGreaterThan(0); + + // Verify all orders in group are assigned to the same driver groupAssigned.forEach(o => { expect(String(o.driverId)).toBe(String(ids.driver)); expect(o.status).toBe('DRIVER_ASSIGNED'); }); + // Deliver the order const deliver = await agents.driver .put(`/api/orders/${one._id}/status`) .send({ status: 'DELIVERED' }); expect(deliver.status).toBe(200); expect(deliver.body.status).toBe('DELIVERED'); - // Driver incentive credited on delivery for EV drivers + + // Driver incentive should be credited for EV drivers expect((deliver.body.driverRewardPoints || 0)).toBeGreaterThan(0); // Customer eco reward credited exactly once const finalCustomer = await User.findById(one.customerId); expect((finalCustomer.rewardPoints || 0)).toBeGreaterThanOrEqual(20); - }); -}); + }, 30000); // 30 second timeout for this long test +}); \ No newline at end of file diff --git a/proj2/Ecobites/server/tests/integration/orders.test.mjs b/proj2/Ecobites/server/tests/integration/orders.test.mjs index 446910af4..15d81c681 100644 --- a/proj2/Ecobites/server/tests/integration/orders.test.mjs +++ b/proj2/Ecobites/server/tests/integration/orders.test.mjs @@ -48,7 +48,7 @@ beforeAll(async () => { restaurantId }); menuItemId = menuItem._id; -}); +}, 30000); // 30 second timeout for beforeAll afterEach(async () => { await Order.deleteMany({});