|
|
@@ -512,4 +512,530 @@ describe('用户端订单API集成测试', () => {
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
+ describe('订单列表API测试', () => {
|
|
|
+ let testOrder: any;
|
|
|
+
|
|
|
+ beforeEach(async () => {
|
|
|
+ // 创建测试订单
|
|
|
+ const orderData = {
|
|
|
+ routeId: testRoute.id,
|
|
|
+ passengerCount: 1,
|
|
|
+ totalAmount: testRoute.price,
|
|
|
+ passengerSnapshots: [
|
|
|
+ {
|
|
|
+ id: testPassenger.id,
|
|
|
+ name: testPassenger.name,
|
|
|
+ idType: testPassenger.idType,
|
|
|
+ idNumber: testPassenger.idNumber,
|
|
|
+ phone: testPassenger.phone
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ routeSnapshot: {
|
|
|
+ id: testRoute.id,
|
|
|
+ name: testRoute.name,
|
|
|
+ pickupPoint: testRoute.pickupPoint,
|
|
|
+ dropoffPoint: testRoute.dropoffPoint,
|
|
|
+ departureTime: testRoute.departureTime,
|
|
|
+ price: testRoute.price,
|
|
|
+ vehicleType: testRoute.vehicleType,
|
|
|
+ travelMode: testRoute.travelMode
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const response = await client.orders.$post({
|
|
|
+ json: orderData,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (response.status === 201) {
|
|
|
+ testOrder = await response.json();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该成功获取订单列表', async () => {
|
|
|
+ const response = await client.orders.$get({
|
|
|
+ query: {
|
|
|
+ page: 1,
|
|
|
+ pageSize: 10
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(200);
|
|
|
+ if (response.status === 200) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData).toHaveProperty('data');
|
|
|
+ expect(responseData).toHaveProperty('total');
|
|
|
+ expect(responseData).toHaveProperty('page');
|
|
|
+ expect(responseData).toHaveProperty('pageSize');
|
|
|
+ expect(Array.isArray(responseData.data)).toBe(true);
|
|
|
+ expect(responseData.data.length).toBeGreaterThan(0);
|
|
|
+
|
|
|
+ // 验证订单数据格式
|
|
|
+ const order = responseData.data[0];
|
|
|
+ expect(order).toHaveProperty('id');
|
|
|
+ expect(order).toHaveProperty('userId');
|
|
|
+ expect(order).toHaveProperty('routeId');
|
|
|
+ expect(order).toHaveProperty('status');
|
|
|
+ expect(order).toHaveProperty('paymentStatus');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该支持按状态筛选订单', async () => {
|
|
|
+ const response = await client.orders.$get({
|
|
|
+ query: {
|
|
|
+ page: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ status: OrderStatus.PENDING_PAYMENT
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(200);
|
|
|
+ if (response.status === 200) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(Array.isArray(responseData.data)).toBe(true);
|
|
|
+
|
|
|
+ // 验证所有返回的订单都是待支付状态
|
|
|
+ if (responseData.data.length > 0) {
|
|
|
+ responseData.data.forEach((order: any) => {
|
|
|
+ expect(order.status).toBe(OrderStatus.PENDING_PAYMENT);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该支持分页功能', async () => {
|
|
|
+ const pageSize = 5;
|
|
|
+ const response = await client.orders.$get({
|
|
|
+ query: {
|
|
|
+ page: 1,
|
|
|
+ pageSize: pageSize
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(200);
|
|
|
+ if (response.status === 200) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.page).toBe(1);
|
|
|
+ expect(responseData.pageSize).toBe(pageSize);
|
|
|
+ expect(responseData.data.length).toBeLessThanOrEqual(pageSize);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝未认证用户的订单列表请求', async () => {
|
|
|
+ const response = await client.orders.$get({
|
|
|
+ query: {
|
|
|
+ page: 1,
|
|
|
+ pageSize: 10
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(401);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('订单详情API测试', () => {
|
|
|
+ let testOrder: any;
|
|
|
+
|
|
|
+ beforeEach(async () => {
|
|
|
+ // 创建测试订单
|
|
|
+ const orderData = {
|
|
|
+ routeId: testRoute.id,
|
|
|
+ passengerCount: 1,
|
|
|
+ totalAmount: testRoute.price,
|
|
|
+ passengerSnapshots: [
|
|
|
+ {
|
|
|
+ id: testPassenger.id,
|
|
|
+ name: testPassenger.name,
|
|
|
+ idType: testPassenger.idType,
|
|
|
+ idNumber: testPassenger.idNumber,
|
|
|
+ phone: testPassenger.phone
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ routeSnapshot: {
|
|
|
+ id: testRoute.id,
|
|
|
+ name: testRoute.name,
|
|
|
+ pickupPoint: testRoute.pickupPoint,
|
|
|
+ dropoffPoint: testRoute.dropoffPoint,
|
|
|
+ departureTime: testRoute.departureTime,
|
|
|
+ price: testRoute.price,
|
|
|
+ vehicleType: testRoute.vehicleType,
|
|
|
+ travelMode: testRoute.travelMode
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const response = await client.orders.$post({
|
|
|
+ json: orderData,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (response.status === 201) {
|
|
|
+ testOrder = await response.json();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该成功获取订单详情', async () => {
|
|
|
+ const response = await client.orders[':id'].$get({
|
|
|
+ param: {
|
|
|
+ id: testOrder.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(200);
|
|
|
+ if (response.status === 200) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.id).toBe(testOrder.id);
|
|
|
+ expect(responseData.userId).toBe(testUser.id);
|
|
|
+ expect(responseData.routeId).toBe(testRoute.id);
|
|
|
+ expect(responseData.status).toBe(OrderStatus.PENDING_PAYMENT);
|
|
|
+ expect(responseData.passengerSnapshots).toEqual(testOrder.passengerSnapshots);
|
|
|
+ expect(responseData.routeSnapshot).toEqual(testOrder.routeSnapshot);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝查看不存在的订单', async () => {
|
|
|
+ const response = await client.orders[':id'].$get({
|
|
|
+ param: {
|
|
|
+ id: 999999
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(404);
|
|
|
+ if (response.status === 404) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.message).toContain('订单不存在');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝查看其他用户的订单', async () => {
|
|
|
+ // 创建另一个用户
|
|
|
+ const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
+ const userService = new UserService(dataSource);
|
|
|
+ const authService = new AuthService(userService);
|
|
|
+
|
|
|
+ const otherUser = await TestDataFactory.createTestUser(dataSource, {
|
|
|
+ username: 'other_user',
|
|
|
+ phone: '13987654321'
|
|
|
+ });
|
|
|
+ const otherToken = authService.generateToken(otherUser);
|
|
|
+
|
|
|
+ const response = await client.orders[':id'].$get({
|
|
|
+ param: {
|
|
|
+ id: testOrder.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${otherToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(403);
|
|
|
+ if (response.status === 403) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.message).toContain('权限不足');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝未认证用户的订单详情请求', async () => {
|
|
|
+ const response = await client.orders[':id'].$get({
|
|
|
+ param: {
|
|
|
+ id: testOrder.id
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(401);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('订单取消API测试', () => {
|
|
|
+ let testOrder: any;
|
|
|
+
|
|
|
+ beforeEach(async () => {
|
|
|
+ // 创建测试订单并更新为待出发状态
|
|
|
+ const orderData = {
|
|
|
+ routeId: testRoute.id,
|
|
|
+ passengerCount: 1,
|
|
|
+ totalAmount: testRoute.price,
|
|
|
+ passengerSnapshots: [
|
|
|
+ {
|
|
|
+ id: testPassenger.id,
|
|
|
+ name: testPassenger.name,
|
|
|
+ idType: testPassenger.idType,
|
|
|
+ idNumber: testPassenger.idNumber,
|
|
|
+ phone: testPassenger.phone
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ routeSnapshot: {
|
|
|
+ id: testRoute.id,
|
|
|
+ name: testRoute.name,
|
|
|
+ pickupPoint: testRoute.pickupPoint,
|
|
|
+ dropoffPoint: testRoute.dropoffPoint,
|
|
|
+ departureTime: new Date(Date.now() + 2 * 60 * 60 * 1000), // 2小时后出发
|
|
|
+ price: testRoute.price,
|
|
|
+ vehicleType: testRoute.vehicleType,
|
|
|
+ travelMode: testRoute.travelMode
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const response = await client.orders.$post({
|
|
|
+ json: orderData,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (response.status === 201) {
|
|
|
+ testOrder = await response.json();
|
|
|
+
|
|
|
+ // 更新订单状态为待出发
|
|
|
+ const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
+ const orderRepository = dataSource.getRepository('Order');
|
|
|
+ await orderRepository.update(testOrder.id, {
|
|
|
+ status: OrderStatus.WAITING_DEPARTURE,
|
|
|
+ paymentStatus: PaymentStatus.PAID
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该成功取消待出发状态的订单', async () => {
|
|
|
+ const response = await client.orders[':id'].cancel.$post({
|
|
|
+ param: {
|
|
|
+ id: testOrder.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(200);
|
|
|
+ if (response.status === 200) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.id).toBe(testOrder.id);
|
|
|
+ expect(responseData.status).toBe(OrderStatus.CANCELLED);
|
|
|
+ expect(responseData.paymentStatus).toBe(PaymentStatus.REFUNDED);
|
|
|
+
|
|
|
+ // 验证数据库中的状态更新
|
|
|
+ const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
+ const orderRepository = dataSource.getRepository('Order');
|
|
|
+ const updatedOrder = await orderRepository.findOne({
|
|
|
+ where: { id: testOrder.id }
|
|
|
+ });
|
|
|
+ expect(updatedOrder?.status).toBe(OrderStatus.CANCELLED);
|
|
|
+ expect(updatedOrder?.paymentStatus).toBe(PaymentStatus.REFUNDED);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝取消非待出发状态的订单', async () => {
|
|
|
+ // 创建已完成状态的订单
|
|
|
+ const orderData = {
|
|
|
+ routeId: testRoute.id,
|
|
|
+ passengerCount: 1,
|
|
|
+ totalAmount: testRoute.price,
|
|
|
+ passengerSnapshots: [],
|
|
|
+ routeSnapshot: {
|
|
|
+ id: testRoute.id,
|
|
|
+ name: testRoute.name,
|
|
|
+ pickupPoint: testRoute.pickupPoint,
|
|
|
+ dropoffPoint: testRoute.dropoffPoint,
|
|
|
+ departureTime: new Date(),
|
|
|
+ price: testRoute.price,
|
|
|
+ vehicleType: testRoute.vehicleType,
|
|
|
+ travelMode: testRoute.travelMode
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const createResponse = await client.orders.$post({
|
|
|
+ json: orderData,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (createResponse.status === 201) {
|
|
|
+ const completedOrder = await createResponse.json();
|
|
|
+
|
|
|
+ // 更新订单状态为已完成
|
|
|
+ const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
+ const orderRepository = dataSource.getRepository('Order');
|
|
|
+ await orderRepository.update(completedOrder.id, {
|
|
|
+ status: OrderStatus.COMPLETED,
|
|
|
+ paymentStatus: PaymentStatus.PAID
|
|
|
+ });
|
|
|
+
|
|
|
+ const response = await client.orders[':id'].cancel.$post({
|
|
|
+ param: {
|
|
|
+ id: completedOrder.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(422);
|
|
|
+ if (response.status === 422) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.message).toContain('只能取消待出发状态的订单');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝取消距离出发时间不足1小时的订单', async () => {
|
|
|
+ // 创建即将出发的订单
|
|
|
+ const orderData = {
|
|
|
+ routeId: testRoute.id,
|
|
|
+ passengerCount: 1,
|
|
|
+ totalAmount: testRoute.price,
|
|
|
+ passengerSnapshots: [],
|
|
|
+ routeSnapshot: {
|
|
|
+ id: testRoute.id,
|
|
|
+ name: testRoute.name,
|
|
|
+ pickupPoint: testRoute.pickupPoint,
|
|
|
+ dropoffPoint: testRoute.dropoffPoint,
|
|
|
+ departureTime: new Date(Date.now() + 30 * 60 * 1000), // 30分钟后出发
|
|
|
+ price: testRoute.price,
|
|
|
+ vehicleType: testRoute.vehicleType,
|
|
|
+ travelMode: testRoute.travelMode
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const createResponse = await client.orders.$post({
|
|
|
+ json: orderData,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (createResponse.status === 201) {
|
|
|
+ const urgentOrder = await createResponse.json();
|
|
|
+
|
|
|
+ // 更新订单状态为待出发
|
|
|
+ const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
+ const orderRepository = dataSource.getRepository('Order');
|
|
|
+ await orderRepository.update(urgentOrder.id, {
|
|
|
+ status: OrderStatus.WAITING_DEPARTURE,
|
|
|
+ paymentStatus: PaymentStatus.PAID
|
|
|
+ });
|
|
|
+
|
|
|
+ const response = await client.orders[':id'].cancel.$post({
|
|
|
+ param: {
|
|
|
+ id: urgentOrder.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(422);
|
|
|
+ if (response.status === 422) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.message).toContain('距离出发时间不足1小时');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝取消其他用户的订单', async () => {
|
|
|
+ // 创建另一个用户
|
|
|
+ const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
+ const userService = new UserService(dataSource);
|
|
|
+ const authService = new AuthService(userService);
|
|
|
+
|
|
|
+ const otherUser = await TestDataFactory.createTestUser(dataSource, {
|
|
|
+ username: 'other_user',
|
|
|
+ phone: '13987654321'
|
|
|
+ });
|
|
|
+ const otherToken = authService.generateToken(otherUser);
|
|
|
+
|
|
|
+ const response = await client.orders[':id'].cancel.$post({
|
|
|
+ param: {
|
|
|
+ id: testOrder.id
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${otherToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(403);
|
|
|
+ if (response.status === 403) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.message).toContain('权限不足');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝取消不存在的订单', async () => {
|
|
|
+ const response = await client.orders[':id'].cancel.$post({
|
|
|
+ param: {
|
|
|
+ id: 999999
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'Authorization': `Bearer ${testToken}`
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(404);
|
|
|
+ if (response.status === 404) {
|
|
|
+ const responseData = await response.json();
|
|
|
+ expect(responseData.message).toContain('订单不存在');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('应该拒绝未认证用户的订单取消请求', async () => {
|
|
|
+ const response = await client.orders[':id'].cancel.$post({
|
|
|
+ param: {
|
|
|
+ id: testOrder.id
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(response.status).toBe(401);
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|