| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- import { describe, it, expect, beforeEach } from 'vitest';
- import { testClient } from 'hono/testing';
- import {
- IntegrationTestDatabase,
- setupIntegrationDatabaseHooksWithEntities,
- IntegrationTestAssertions
- } from '@d8d/shared-test-util';
- import { areaRoutes } from '../../src/api/areas';
- import { AreaEntity, AreaLevel } from '../../src/modules/areas/area.entity';
- import { DisabledStatus } from '@d8d/shared-types';
- import { TestDataFactory } from '../utils/test-data-factory';
- // 设置集成测试钩子
- setupIntegrationDatabaseHooksWithEntities([AreaEntity])
- describe('区域API集成测试', () => {
- let client: ReturnType<typeof testClient<typeof areaRoutes>>;
- let testAreas: AreaEntity[];
- beforeEach(async () => {
- // 创建测试客户端
- client = testClient(areaRoutes);
- // 创建测试数据
- const dataSource = await IntegrationTestDatabase.getDataSource();
- // 创建启用状态的省份
- const province1 = await TestDataFactory.createTestArea(dataSource, {
- name: '北京市',
- level: AreaLevel.PROVINCE,
- isDisabled: DisabledStatus.ENABLED
- });
- const province2 = await TestDataFactory.createTestArea(dataSource, {
- name: '上海市',
- level: AreaLevel.PROVINCE,
- isDisabled: DisabledStatus.ENABLED
- });
- const province3 = await TestDataFactory.createTestArea(dataSource, {
- name: '广东省',
- level: AreaLevel.PROVINCE,
- isDisabled: DisabledStatus.ENABLED
- });
- // 创建启用状态的城市
- const city11 = await TestDataFactory.createTestArea(dataSource, {
- name: '北京市',
- level: AreaLevel.CITY,
- parentId: province1.id,
- isDisabled: DisabledStatus.ENABLED
- });
- const city12 = await TestDataFactory.createTestArea(dataSource, {
- name: '朝阳区',
- level: AreaLevel.CITY,
- parentId: province1.id,
- isDisabled: DisabledStatus.ENABLED
- });
- const city13 = await TestDataFactory.createTestArea(dataSource, {
- name: '海淀区',
- level: AreaLevel.CITY,
- parentId: province1.id,
- isDisabled: DisabledStatus.ENABLED
- });
- const city21 = await TestDataFactory.createTestArea(dataSource, {
- name: '上海市',
- level: AreaLevel.CITY,
- parentId: province2.id,
- isDisabled: DisabledStatus.ENABLED
- });
- const city22 = await TestDataFactory.createTestArea(dataSource, {
- name: '浦东新区',
- level: AreaLevel.CITY,
- parentId: province2.id,
- isDisabled: DisabledStatus.ENABLED
- });
- // 创建启用状态的区县
- const district101 = await TestDataFactory.createTestArea(dataSource, {
- name: '朝阳区',
- level: AreaLevel.DISTRICT,
- parentId: city12.id,
- isDisabled: DisabledStatus.ENABLED
- });
- const district102 = await TestDataFactory.createTestArea(dataSource, {
- name: '海淀区',
- level: AreaLevel.DISTRICT,
- parentId: city13.id,
- isDisabled: DisabledStatus.ENABLED
- });
- const district103 = await TestDataFactory.createTestArea(dataSource, {
- name: '西城区',
- level: AreaLevel.DISTRICT,
- parentId: city12.id,
- isDisabled: DisabledStatus.ENABLED
- });
- const district201 = await TestDataFactory.createTestArea(dataSource, {
- name: '浦东新区',
- level: AreaLevel.DISTRICT,
- parentId: city22.id,
- isDisabled: DisabledStatus.ENABLED
- });
- // 创建禁用状态的区域用于测试过滤
- const disabledProvince = await TestDataFactory.createTestArea(dataSource, {
- name: '禁用省份',
- level: AreaLevel.PROVINCE,
- isDisabled: DisabledStatus.DISABLED
- });
- const disabledCity = await TestDataFactory.createTestArea(dataSource, {
- name: '禁用城市',
- level: AreaLevel.CITY,
- parentId: province3.id,
- isDisabled: DisabledStatus.DISABLED
- });
- const disabledDistrict = await TestDataFactory.createTestArea(dataSource, {
- name: '禁用区县',
- level: AreaLevel.DISTRICT,
- parentId: city12.id,
- isDisabled: DisabledStatus.DISABLED
- });
- testAreas = [
- province1, province2, province3,
- city11, city12, city13, city21, city22,
- district101, district102, district103, district201,
- disabledProvince, disabledCity, disabledDistrict
- ];
- });
- describe('GET /areas/provinces', () => {
- it('应该成功获取启用状态的省份列表', async () => {
- const response = await client.provinces.$get({
- query: { page: 1, pageSize: 50 }
- });
- IntegrationTestAssertions.expectStatus(response, 200);
- if (response.status === 200) {
- const data = await response.json();
- // 验证响应数据格式
- expect(data).toHaveProperty('success', true);
- expect(data).toHaveProperty('data');
- expect(data.data).toHaveProperty('provinces');
- expect(data.data).toHaveProperty('pagination');
- // 验证只返回启用状态的省份
- const provinces = data.data.provinces;
- expect(provinces).toHaveLength(3); // 只返回3个启用状态的省份
- // 验证不包含禁用状态的省份
- const disabledProvince = provinces.find((p: any) => p.isDisabled === DisabledStatus.DISABLED);
- expect(disabledProvince).toBeUndefined();
- // 验证分页信息
- expect(data.data.pagination).toEqual({
- page: 1,
- pageSize: 50,
- total: 3,
- totalPages: 1
- });
- }
- });
- it('应该正确处理分页参数', async () => {
- const response = await client.provinces.$get({
- query: { page: 1, pageSize: 2 }
- });
- IntegrationTestAssertions.expectStatus(response, 200);
- if (response.status === 200) {
- const data = await response.json();
- // 验证分页结果
- expect(data.data.provinces).toHaveLength(2);
- expect(data.data.pagination).toEqual({
- page: 1,
- pageSize: 2,
- total: 3,
- totalPages: 2
- });
- }
- });
- });
- describe('GET /areas/cities', () => {
- it('应该成功获取指定省份下启用状态的城市列表', async () => {
- const response = await client.cities.$get({
- query: { provinceId: testAreas[0].id, page: 1, pageSize: 50 }
- });
- IntegrationTestAssertions.expectStatus(response, 200);
- if (response.status === 200) {
- const data = await response.json();
- // 验证响应数据格式
- expect(data).toHaveProperty('success', true);
- expect(data).toHaveProperty('data');
- expect(data.data).toHaveProperty('cities');
- // 验证只返回启用状态的城市
- const cities = data.data.cities;
- expect(cities).toHaveLength(3); // 北京市下有3个启用状态的城市
- // 验证城市数据正确
- const cityNames = cities.map((c: any) => c.name);
- expect(cityNames).toContain('北京市');
- expect(cityNames).toContain('朝阳区');
- expect(cityNames).toContain('海淀区');
- // 验证不包含禁用状态的城市
- const disabledCity = cities.find((c: any) => c.name === '禁用城市');
- expect(disabledCity).toBeUndefined();
- }
- });
- it('应该处理不存在的省份ID', async () => {
- const response = await client.cities.$get({
- query: { provinceId: 999, page: 1, pageSize: 50 }
- });
- IntegrationTestAssertions.expectStatus(response, 200);
- if (response.status === 200) {
- const data = await response.json();
- // 不存在的省份应该返回空数组
- expect(data.data.cities).toHaveLength(0);
- }
- });
- it('应该验证省份ID参数', async () => {
- const response = await client.cities.$get({
- query: { provinceId: 0, page: 1, pageSize: 50 }
- });
- // 参数验证应该返回400错误
- IntegrationTestAssertions.expectStatus(response, 400);
- });
- });
- describe('GET /areas/districts', () => {
- it('应该成功获取指定城市下启用状态的区县列表', async () => {
- // 找到朝阳区城市对象
- const chaoyangCity = testAreas.find(area => area.name === '朝阳区' && area.level === AreaLevel.CITY);
- expect(chaoyangCity).toBeDefined();
- const response = await client.districts.$get({
- query: { cityId: chaoyangCity!.id, page: 1, pageSize: 50 }
- });
- IntegrationTestAssertions.expectStatus(response, 200);
- if (response.status === 200) {
- const data = await response.json();
- // 验证响应数据格式
- expect(data).toHaveProperty('success', true);
- expect(data).toHaveProperty('data');
- expect(data.data).toHaveProperty('districts');
- // 验证只返回启用状态的区县
- const districts = data.data.districts;
- expect(districts).toHaveLength(2); // 朝阳区下有2个启用状态的区县
- // 验证区县数据正确
- const districtNames = districts.map((d: any) => d.name);
- expect(districtNames).toContain('朝阳区');
- expect(districtNames).toContain('西城区');
- // 验证不包含禁用状态的区县
- const disabledDistrict = districts.find((d: any) => d.name === '禁用区县');
- expect(disabledDistrict).toBeUndefined();
- }
- });
- it('应该处理不存在的城市ID', async () => {
- const response = await client.districts.$get({
- query: { cityId: 999, page: 1, pageSize: 50 }
- });
- IntegrationTestAssertions.expectStatus(response, 200);
- if (response.status === 200) {
- const data = await response.json();
- // 不存在的城市应该返回空数组
- expect(data.data.districts).toHaveLength(0);
- }
- });
- it('应该验证城市ID参数', async () => {
- const response = await client.districts.$get({
- query: { cityId: 0, page: 1, pageSize: 50 }
- });
- // 参数验证应该返回400错误
- IntegrationTestAssertions.expectStatus(response, 400);
- });
- });
- describe('过滤禁用状态验证', () => {
- it('应该确保所有API只返回启用状态的区域', async () => {
- // 测试省份API
- const provincesResponse = await client.provinces.$get({
- query: { page: 1, pageSize: 50 }
- });
- IntegrationTestAssertions.expectStatus(provincesResponse, 200);
- const provincesData = await provincesResponse.json();
- // 验证省份不包含禁用状态
- if ('data' in provincesData) {
- const provinces = provincesData.data.provinces;
- const hasDisabledProvince = provinces.some((p: any) => p.isDisabled === DisabledStatus.DISABLED);
- expect(hasDisabledProvince).toBe(false);
- }
- // 测试城市API
- const citiesResponse = await client.cities.$get({
- query: { provinceId: testAreas[0].id, page: 1, pageSize: 50 }
- });
- IntegrationTestAssertions.expectStatus(citiesResponse, 200);
- const citiesData = await citiesResponse.json();
- // 验证城市不包含禁用状态
- if ('data' in citiesData) {
- const cities = citiesData.data.cities;
- const hasDisabledCity = cities.some((c: any) => c.isDisabled === DisabledStatus.DISABLED);
- expect(hasDisabledCity).toBe(false);
- }
- // 测试区县API
- const chaoyangCity = testAreas.find(area => area.name === '朝阳区' && area.level === AreaLevel.CITY);
- const districtsResponse = await client.districts.$get({
- query: { cityId: chaoyangCity!.id, page: 1, pageSize: 50 }
- });
- IntegrationTestAssertions.expectStatus(districtsResponse, 200);
- const districtsData = await districtsResponse.json();
- // 验证区县不包含禁用状态
- if ('data' in districtsData) {
- const districts = districtsData.data.districts;
- const hasDisabledDistrict = districts.some((d: any) => d.isDisabled === DisabledStatus.DISABLED);
- expect(hasDisabledDistrict).toBe(false);
- }
- });
- });
- });
|