from io import StringIO from django.core.cache import cache from django.core.management import call_command from django.test import TestCase, override_settings from django.utils import timezone from rest_framework.test import APIClient from api_v1.models import AppVersion from flower.app_version import APP_VERSION_CACHE_KEY class AppVersionAPITest(TestCase): def setUp(self): cache.delete(APP_VERSION_CACHE_KEY) self.client = APIClient() def tearDown(self): cache.delete(APP_VERSION_CACHE_KEY) @override_settings( APP_LATEST_VERSION_MAJOR=1, APP_LATEST_VERSION_MINOR=2, APP_LATEST_VERSION_BUILD=345, APP_DOWNLOAD_URL="https://example.com/app.apk", APP_FORCE_UPDATE=True, APP_PUBLISH_DATE="2026-07-08", ) def test_app_version_api_returns_settings_payload_without_auth(self): response = self.client.get("/api/app-version/") self.assertEqual(response.status_code, 200) self.assertEqual( response.data, { "latest_version": { "major": 1, "minor": 2, "build": 345, }, "download_url": "https://example.com/app.apk", "force": True, "publish_date": "2026-07-08", "message": "", }, ) def test_app_version_api_returns_current_model_version(self): AppVersion.objects.create( major=1, minor=0, build=100, download_url="https://example.com/old.apk", publish_date="2026-07-01", message="旧版本", ) AppVersion.objects.create( major=2, minor=0, build=200, download_url="https://example.com/current.apk", force=True, publish_date="2026-07-08", message="请更新到最新版本", is_current=True, ) response = self.client.get("/api/app-version/") self.assertEqual(response.status_code, 200) self.assertEqual(response.data["latest_version"], {"major": 2, "minor": 0, "build": 200}) self.assertEqual(response.data["download_url"], "https://example.com/current.apk") self.assertEqual(response.data["force"], True) self.assertEqual(response.data["publish_date"], "2026-07-08") self.assertEqual(response.data["message"], "请更新到最新版本") def test_app_version_api_returns_newest_model_version_when_no_current(self): AppVersion.objects.create( major=1, minor=0, build=100, download_url="https://example.com/old.apk", publish_date="2026-07-01", ) AppVersion.objects.create( major=1, minor=1, build=110, download_url="https://example.com/new.apk", publish_date="2026-07-02", message="最新创建版本", ) response = self.client.get("/api/app-version/") self.assertEqual(response.status_code, 200) self.assertEqual(response.data["latest_version"], {"major": 1, "minor": 1, "build": 110}) self.assertEqual(response.data["download_url"], "https://example.com/new.apk") self.assertEqual(response.data["message"], "最新创建版本") def test_app_version_current_flag_is_mutually_exclusive(self): first = AppVersion.objects.create( major=1, minor=0, build=100, download_url="https://example.com/first.apk", is_current=True, ) second = AppVersion.objects.create( major=2, minor=0, build=200, download_url="https://example.com/second.apk", is_current=True, ) first.refresh_from_db() second.refresh_from_db() self.assertFalse(first.is_current) self.assertTrue(second.is_current) def test_set_app_version_command_updates_cached_api_payload_with_defaults(self): output = StringIO() call_command( "set_app_version", "--major", "2", "--minor", "5", "--build", "1001", "--download-url", "https://example.com/latest.apk", stdout=output, ) response = self.client.get("/api/app-version/") self.assertEqual(response.status_code, 200) self.assertEqual(response.data["latest_version"], {"major": 2, "minor": 5, "build": 1001}) self.assertEqual(response.data["download_url"], "https://example.com/latest.apk") self.assertEqual(response.data["force"], False) self.assertEqual(response.data["publish_date"], timezone.localdate().isoformat()) self.assertEqual(response.data["message"], "") self.assertIn("'build': 1001", output.getvalue()) def test_set_app_version_command_accepts_force_and_publish_date(self): output = StringIO() call_command( "set_app_version", "--major", "2", "--minor", "6", "--build", "1002", "--download-url", "https://example.com/force.apk", "--force", "--publish-date", "2026-07-01", "--message", "强制升级说明", stdout=output, ) response = self.client.get("/api/app-version/") self.assertEqual(response.status_code, 200) self.assertEqual(response.data["latest_version"], {"major": 2, "minor": 6, "build": 1002}) self.assertEqual(response.data["download_url"], "https://example.com/force.apk") self.assertEqual(response.data["force"], True) self.assertEqual(response.data["publish_date"], "2026-07-01") self.assertEqual(response.data["message"], "强制升级说明")