import json from pathlib import Path from tempfile import TemporaryDirectory from types import SimpleNamespace from unittest.mock import patch from django.conf import settings from django.core.management import call_command from django.test import SimpleTestCase, override_settings from apps.am.models import Area from apps.am.views import AreaViewSet from apps.utils.swagger import ChineseSwaggerAutoSchema, swagger_schema_file class ChineseSwaggerAutoSchemaTests(SimpleTestCase): def make_schema(self, view, method="GET"): schema = ChineseSwaggerAutoSchema.__new__(ChineseSwaggerAutoSchema) schema.view = view schema.method = method schema.path = "/am/area/" schema.overrides = {} schema.operation_keys = ("am", "area", "list") schema._sch = SimpleNamespace(get_description=lambda path, method: "") return schema def test_crud_summary_uses_model_chinese_name(self): view = SimpleNamespace(queryset=Area.objects.all(), action="list") schema = self.make_schema(view) summary, description = schema.get_summary_and_description() self.assertEqual(summary, "查询地图区域列表") self.assertEqual(description, "查询地图区域列表") def test_explicit_summary_takes_priority(self): view = SimpleNamespace(queryset=Area.objects.all(), action="list") schema = self.make_schema(view) schema.overrides = { "operation_summary": "区域自定义查询", "operation_description": "自定义说明", } summary, description = schema.get_summary_and_description() self.assertEqual(summary, "区域自定义查询") self.assertEqual(description, "自定义说明") def test_custom_action_with_english_model_name_has_chinese_hint(self): model = SimpleNamespace( __doc__="", __name__="Dataset", _meta=SimpleNamespace(verbose_name="dataset"), ) queryset = SimpleNamespace(model=model) view = SimpleNamespace(queryset=queryset, action="base") schema = self.make_schema(view) summary, _ = schema.get_summary_and_description() self.assertEqual(summary, "Dataset接口:base") def test_tag_uses_chinese_business_module_name(self): view = SimpleNamespace(queryset=Area.objects.all(), action="list") schema = self.make_schema(view) self.assertEqual(schema.get_tags(("am", "area", "list")), ["区域与准入管理"]) def test_filter_parameter_uses_model_field_labels(self): view = SimpleNamespace(queryset=Area.objects.all(), action="list") schema = self.make_schema(view) description = schema._get_parameter_description( "manager__name__contains", Area, ) self.assertIn("区域负责人", description) self.assertIn("包含", description) def test_swagger_queryset_skips_permission_data_lookup(self): view = AreaViewSet(basename="area") view.action = "list" view.swagger_fake_view = True with patch("apps.utils.viewsets.get_user_perms_map") as permission_lookup: queryset = view.get_queryset() self.assertIs(queryset.model, Area) permission_lookup.assert_not_called() class SwaggerSettingsTests(SimpleTestCase): def test_swagger_supports_jwt_authorization_header(self): from django.conf import settings bearer = settings.SWAGGER_SETTINGS["SECURITY_DEFINITIONS"]["Bearer"] self.assertEqual(bearer["type"], "apiKey") self.assertEqual(bearer["name"], "Authorization") self.assertEqual(bearer["in"], "header") def test_swagger_ui_uses_static_schema(self): from django.conf import settings self.assertEqual(settings.SWAGGER_SETTINGS["SPEC_URL"], "schema-swagger-json") self.assertEqual(settings.REDOC_SETTINGS["SPEC_URL"], "schema-swagger-json") class BuildSwaggerCommandTests(SimpleTestCase): def test_command_writes_valid_utf8_schema(self): schema = { "swagger": "2.0", "info": {"title": "中文文档"}, "paths": {"/demo/": {"get": {}}}, } def generate_schema(command_name, output_file, **options): self.assertEqual(command_name, "generate_swagger") self.assertEqual(output_file, "-") options["stdout"].write(json.dumps(schema, ensure_ascii=False)) with TemporaryDirectory(dir=settings.BASE_DIR) as directory: target = Path(directory) / "swagger.json" with override_settings(SWAGGER_SCHEMA_PATH=str(target)): with patch( "apps.utils.management.commands.build_swagger.call_command", side_effect=generate_schema, ): call_command("build_swagger", verbosity=0) content = target.read_text(encoding="utf-8") self.assertIn("中文文档", content) self.assertEqual(json.loads(content), schema) with override_settings(SWAGGER_SCHEMA_PATH=str(target)): response = swagger_schema_file(SimpleNamespace()) body = b"".join(response.streaming_content) response.close() self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(body), schema)