test_settings_api.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. """Integration tests for Settings API endpoints.
  2. Tests the full request/response cycle for /api/v1/settings/ endpoints.
  3. """
  4. import pytest
  5. from httpx import AsyncClient
  6. class TestSettingsAPI:
  7. """Integration tests for /api/v1/settings/ endpoints."""
  8. # ========================================================================
  9. # Get settings
  10. # ========================================================================
  11. @pytest.mark.asyncio
  12. @pytest.mark.integration
  13. async def test_get_settings(self, async_client: AsyncClient):
  14. """Verify settings can be retrieved."""
  15. response = await async_client.get("/api/v1/settings/")
  16. assert response.status_code == 200
  17. result = response.json()
  18. # Check for actual settings fields
  19. assert "auto_archive" in result
  20. assert "currency" in result
  21. assert "date_format" in result
  22. @pytest.mark.asyncio
  23. @pytest.mark.integration
  24. async def test_get_settings_has_defaults(self, async_client: AsyncClient):
  25. """Verify default settings values are returned."""
  26. response = await async_client.get("/api/v1/settings/")
  27. assert response.status_code == 200
  28. result = response.json()
  29. # Verify some default values
  30. assert isinstance(result["auto_archive"], bool)
  31. assert isinstance(result["currency"], str)
  32. # ========================================================================
  33. # Update settings
  34. # ========================================================================
  35. @pytest.mark.asyncio
  36. @pytest.mark.integration
  37. async def test_update_auto_archive(self, async_client: AsyncClient):
  38. """Verify auto_archive can be updated."""
  39. # First get current value
  40. response = await async_client.get("/api/v1/settings/")
  41. original = response.json()["auto_archive"]
  42. # Update to opposite value
  43. new_value = not original
  44. response = await async_client.put(
  45. "/api/v1/settings/",
  46. json={"auto_archive": new_value}
  47. )
  48. assert response.status_code == 200
  49. assert response.json()["auto_archive"] == new_value
  50. @pytest.mark.asyncio
  51. @pytest.mark.integration
  52. async def test_update_currency(self, async_client: AsyncClient):
  53. """Verify currency can be updated."""
  54. response = await async_client.put(
  55. "/api/v1/settings/",
  56. json={"currency": "EUR"}
  57. )
  58. assert response.status_code == 200
  59. assert response.json()["currency"] == "EUR"
  60. @pytest.mark.asyncio
  61. @pytest.mark.integration
  62. async def test_update_date_format(self, async_client: AsyncClient):
  63. """Verify date format can be updated."""
  64. response = await async_client.put(
  65. "/api/v1/settings/",
  66. json={"date_format": "eu"}
  67. )
  68. assert response.status_code == 200
  69. assert response.json()["date_format"] == "eu"
  70. @pytest.mark.asyncio
  71. @pytest.mark.integration
  72. async def test_update_time_format(self, async_client: AsyncClient):
  73. """Verify time format can be updated."""
  74. response = await async_client.put(
  75. "/api/v1/settings/",
  76. json={"time_format": "24h"}
  77. )
  78. assert response.status_code == 200
  79. assert response.json()["time_format"] == "24h"
  80. @pytest.mark.asyncio
  81. @pytest.mark.integration
  82. async def test_update_filament_cost(self, async_client: AsyncClient):
  83. """Verify default filament cost can be updated."""
  84. response = await async_client.put(
  85. "/api/v1/settings/",
  86. json={"default_filament_cost": 30.0}
  87. )
  88. assert response.status_code == 200
  89. assert response.json()["default_filament_cost"] == 30.0
  90. @pytest.mark.asyncio
  91. @pytest.mark.integration
  92. async def test_update_energy_cost(self, async_client: AsyncClient):
  93. """Verify energy cost can be updated."""
  94. response = await async_client.put(
  95. "/api/v1/settings/",
  96. json={"energy_cost_per_kwh": 0.20}
  97. )
  98. assert response.status_code == 200
  99. assert response.json()["energy_cost_per_kwh"] == 0.20
  100. @pytest.mark.asyncio
  101. @pytest.mark.integration
  102. async def test_update_multiple_settings(self, async_client: AsyncClient):
  103. """Verify multiple settings can be updated at once."""
  104. response = await async_client.put(
  105. "/api/v1/settings/",
  106. json={
  107. "currency": "GBP",
  108. "date_format": "iso",
  109. "time_format": "12h",
  110. "save_thumbnails": False,
  111. }
  112. )
  113. assert response.status_code == 200
  114. result = response.json()
  115. assert result["currency"] == "GBP"
  116. assert result["date_format"] == "iso"
  117. assert result["time_format"] == "12h"
  118. assert result["save_thumbnails"] is False
  119. @pytest.mark.asyncio
  120. @pytest.mark.integration
  121. async def test_update_spoolman_settings(self, async_client: AsyncClient):
  122. """Verify Spoolman settings can be updated."""
  123. response = await async_client.put(
  124. "/api/v1/settings/",
  125. json={
  126. "spoolman_enabled": True,
  127. "spoolman_url": "http://localhost:7912",
  128. "spoolman_sync_mode": "manual",
  129. }
  130. )
  131. assert response.status_code == 200
  132. result = response.json()
  133. assert result["spoolman_enabled"] is True
  134. assert result["spoolman_url"] == "http://localhost:7912"
  135. assert result["spoolman_sync_mode"] == "manual"
  136. @pytest.mark.asyncio
  137. @pytest.mark.integration
  138. async def test_update_ams_thresholds(self, async_client: AsyncClient):
  139. """Verify AMS threshold settings can be updated."""
  140. response = await async_client.put(
  141. "/api/v1/settings/",
  142. json={
  143. "ams_humidity_good": 35,
  144. "ams_humidity_fair": 55,
  145. "ams_temp_good": 25.0,
  146. "ams_temp_fair": 32.0,
  147. }
  148. )
  149. assert response.status_code == 200
  150. result = response.json()
  151. assert result["ams_humidity_good"] == 35
  152. assert result["ams_humidity_fair"] == 55
  153. assert result["ams_temp_good"] == 25.0
  154. assert result["ams_temp_fair"] == 32.0
  155. @pytest.mark.asyncio
  156. @pytest.mark.integration
  157. async def test_update_notification_language(self, async_client: AsyncClient):
  158. """Verify notification language can be updated."""
  159. response = await async_client.put(
  160. "/api/v1/settings/",
  161. json={"notification_language": "de"}
  162. )
  163. assert response.status_code == 200
  164. assert response.json()["notification_language"] == "de"
  165. # ========================================================================
  166. # Settings persistence tests
  167. # ========================================================================
  168. @pytest.mark.asyncio
  169. @pytest.mark.integration
  170. async def test_settings_persist_after_update(self, async_client: AsyncClient):
  171. """CRITICAL: Verify settings changes persist across requests."""
  172. # Update settings
  173. await async_client.put(
  174. "/api/v1/settings/",
  175. json={"currency": "JPY", "check_updates": False}
  176. )
  177. # Verify persistence in new request
  178. response = await async_client.get("/api/v1/settings/")
  179. result = response.json()
  180. assert result["currency"] == "JPY"
  181. assert result["check_updates"] is False