test_create.py
1 """Integration tests for the custom extra fields system.""" 2 3 import json 4 from datetime import datetime, timezone 5 6 import httpx 7 import pytest 8 9 from ..conftest import URL, assert_httpx_success, assert_lists_compatible 10 11 12 def test_add_text_field(): 13 """Test adding a text field for spools.""" 14 result = httpx.post( 15 f"{URL}/api/v1/field/spool/mytextfield", 16 json={ 17 "name": "My text field", 18 "field_type": "text", 19 "default_value": json.dumps("Hello World"), 20 }, 21 ) 22 assert_httpx_success(result) 23 24 # Clean up 25 result = httpx.delete(f"{URL}/api/v1/field/spool/mytextfield") 26 assert_httpx_success(result) 27 28 29 def test_add_text_field_filament(): 30 """Test adding a text field for filaments.""" 31 result = httpx.post( 32 f"{URL}/api/v1/field/filament/mytextfield", 33 json={ 34 "name": "My text field", 35 "field_type": "text", 36 "default_value": json.dumps("Hello World"), 37 }, 38 ) 39 assert_httpx_success(result) 40 41 # Clean up 42 result = httpx.delete(f"{URL}/api/v1/field/filament/mytextfield") 43 assert_httpx_success(result) 44 45 46 def test_add_text_field_vendor(): 47 """Test adding a text field for vendors.""" 48 result = httpx.post( 49 f"{URL}/api/v1/field/vendor/mytextfield", 50 json={ 51 "name": "My text field", 52 "field_type": "text", 53 "default_value": json.dumps("Hello World"), 54 }, 55 ) 56 assert_httpx_success(result) 57 58 # Clean up 59 result = httpx.delete(f"{URL}/api/v1/field/vendor/mytextfield") 60 assert_httpx_success(result) 61 62 63 def test_add_integer_field(): 64 """Test adding an integer field for spools.""" 65 result = httpx.post( 66 f"{URL}/api/v1/field/spool/myintegerfield", 67 json={ 68 "name": "My integer field", 69 "unit": "mm", 70 "field_type": "integer", 71 "default_value": json.dumps(42), 72 }, 73 ) 74 assert_httpx_success(result) 75 76 # Clean up 77 result = httpx.delete(f"{URL}/api/v1/field/spool/myintegerfield") 78 assert_httpx_success(result) 79 80 81 def test_add_integer_range_field(): 82 """Test adding an integer range field for spools.""" 83 result = httpx.post( 84 f"{URL}/api/v1/field/spool/myintegerrangefield", 85 json={ 86 "name": "My integer range field", 87 "field_type": "integer_range", 88 "default_value": json.dumps([0, 100]), 89 }, 90 ) 91 assert_httpx_success(result) 92 93 # Clean up 94 result = httpx.delete(f"{URL}/api/v1/field/spool/myintegerrangefield") 95 assert_httpx_success(result) 96 97 98 def test_add_float_field(): 99 """Test adding a float field for spools.""" 100 result = httpx.post( 101 f"{URL}/api/v1/field/spool/myfloatfield", 102 json={ 103 "name": "My float field", 104 "field_type": "float", 105 "default_value": json.dumps(3.14), 106 }, 107 ) 108 assert_httpx_success(result) 109 110 # Clean up 111 result = httpx.delete(f"{URL}/api/v1/field/spool/myfloatfield") 112 assert_httpx_success(result) 113 114 115 def test_add_float_range_field(): 116 """Test adding a float range field for spools.""" 117 result = httpx.post( 118 f"{URL}/api/v1/field/spool/myfloatrangefield", 119 json={ 120 "name": "My float range field", 121 "field_type": "float_range", 122 "default_value": json.dumps([0.0, 1.0]), 123 }, 124 ) 125 assert_httpx_success(result) 126 127 # Clean up 128 result = httpx.delete(f"{URL}/api/v1/field/spool/myfloatrangefield") 129 assert_httpx_success(result) 130 131 132 def test_add_datetime_field(): 133 """Test adding a datetime field for spools.""" 134 result = httpx.post( 135 f"{URL}/api/v1/field/spool/mydatetimefield", 136 json={ 137 "name": "My datetime field", 138 "field_type": "datetime", 139 "default_value": json.dumps(datetime.now(timezone.utc).isoformat()), 140 }, 141 ) 142 assert_httpx_success(result) 143 144 # Clean up 145 result = httpx.delete(f"{URL}/api/v1/field/spool/mydatetimefield") 146 assert_httpx_success(result) 147 148 149 def test_add_boolean_field(): 150 """Test adding a boolean field for spools.""" 151 result = httpx.post( 152 f"{URL}/api/v1/field/spool/mybooleanfield", 153 json={ 154 "name": "My boolean field", 155 "field_type": "boolean", 156 "default_value": json.dumps(True), # noqa: FBT003 157 }, 158 ) 159 assert_httpx_success(result) 160 161 # Clean up 162 result = httpx.delete(f"{URL}/api/v1/field/spool/mybooleanfield") 163 assert_httpx_success(result) 164 165 166 @pytest.mark.parametrize( 167 "multi_choice", 168 [True, False], 169 ) 170 def test_add_choice_field(multi_choice: bool): # noqa: FBT001 171 """Test adding a choice field for spools.""" 172 result = httpx.post( 173 f"{URL}/api/v1/field/spool/mychoicefield", 174 json={ 175 "name": "My choice field", 176 "field_type": "choice", 177 "choices": ["foo", "bar", "baz"], 178 "default_value": json.dumps(["foo"]) if multi_choice else json.dumps("foo"), 179 "multi_choice": multi_choice, 180 }, 181 ) 182 assert_httpx_success(result) 183 184 # Clean up 185 result = httpx.delete(f"{URL}/api/v1/field/spool/mychoicefield") 186 assert_httpx_success(result) 187 188 189 def test_add_text_field_invalid_data(): 190 """Test adding a text field with invalid default value.""" 191 result = httpx.post( 192 f"{URL}/api/v1/field/spool/mytextfield", 193 json={ 194 "name": "My text field", 195 "field_type": "text", 196 "default_value": json.dumps(42), 197 }, 198 ) 199 assert result.status_code == 400 200 assert result.json()["message"] == "Default value is not valid: Value is not a string." 201 202 203 def test_add_choice_field_without_multi_choice(): 204 """Test adding a choice field without multi_choice set.""" 205 result = httpx.post( 206 f"{URL}/api/v1/field/spool/mychoicefield", 207 json={ 208 "name": "My choice field", 209 "field_type": "choice", 210 "choices": ["foo", "bar", "baz"], 211 "default_value": json.dumps("foo"), 212 }, 213 ) 214 assert result.status_code == 400 215 assert result.json()["message"] == "Multi choice must be set for field type choice." 216 217 218 def test_add_choice_field_invalid_choices(): 219 """Test adding a choice field with invalid choices.""" 220 result = httpx.post( 221 f"{URL}/api/v1/field/spool/mychoicefield", 222 json={ 223 "name": "My choice field", 224 "field_type": "choice", 225 "choices": ["foo", "bar", "baz", {"foo": "bar"}], 226 "default_value": json.dumps(["foo"]), 227 "multi_choice": True, 228 }, 229 ) 230 assert result.status_code == 422 231 232 233 def test_add_choice_field_invalid_default_value(): 234 """Test adding a choice field with invalid default value.""" 235 result = httpx.post( 236 f"{URL}/api/v1/field/spool/mychoicefield", 237 json={ 238 "name": "My choice field", 239 "field_type": "choice", 240 "choices": ["foo", "bar", "baz"], 241 "default_value": json.dumps(42), 242 "multi_choice": False, 243 }, 244 ) 245 assert result.status_code == 400 246 assert result.json()["message"] == "Default value is not valid: Value is not a string." 247 248 249 def test_add_choice_field_no_choices(): 250 """Test adding a choice field without choices set.""" 251 result = httpx.post( 252 f"{URL}/api/v1/field/spool/mychoicefield", 253 json={ 254 "name": "My choice field", 255 "field_type": "choice", 256 "default_value": json.dumps("foo"), 257 "multi_choice": True, 258 }, 259 ) 260 assert result.status_code == 400 261 assert result.json()["message"] == "Choices must be set for field type choice." 262 263 264 def test_update_existing_field(): 265 """Test updating an existing field.""" 266 result = httpx.post( 267 f"{URL}/api/v1/field/spool/mytextfield", 268 json={ 269 "name": "My text field", 270 "field_type": "text", 271 "default_value": json.dumps("Hello World"), 272 }, 273 ) 274 assert_httpx_success(result) 275 276 result = httpx.post( 277 f"{URL}/api/v1/field/spool/mytextfield", 278 json={ 279 "name": "My text field", 280 "field_type": "text", 281 "default_value": json.dumps("Goodbye World"), 282 }, 283 ) 284 assert_httpx_success(result) 285 286 # Verify that the default value was updated, and that it is still the only field 287 result = httpx.get(f"{URL}/api/v1/field/spool") 288 assert_httpx_success(result) 289 assert_lists_compatible( 290 result.json(), 291 [ 292 { 293 "name": "My text field", 294 "key": "mytextfield", 295 "field_type": "text", 296 "default_value": json.dumps("Goodbye World"), 297 }, 298 ], 299 sort_key="key", 300 ) 301 302 # Clean up 303 result = httpx.delete(f"{URL}/api/v1/field/spool/mytextfield") 304 assert_httpx_success(result) 305 306 307 def test_update_field_change_field_type(): 308 """Test updating an existing field and changing the field type, should not be allowed.""" 309 result = httpx.post( 310 f"{URL}/api/v1/field/spool/mytextfield", 311 json={ 312 "name": "My text field", 313 "field_type": "text", 314 "default_value": json.dumps("Hello World"), 315 }, 316 ) 317 assert_httpx_success(result) 318 319 result = httpx.post( 320 f"{URL}/api/v1/field/spool/mytextfield", 321 json={ 322 "name": "My text field", 323 "field_type": "integer", 324 "default_value": json.dumps(42), 325 }, 326 ) 327 assert result.status_code == 400 328 assert result.json()["message"] == "Field type cannot be changed." 329 330 # Clean up 331 result = httpx.delete(f"{URL}/api/v1/field/spool/mytextfield") 332 assert_httpx_success(result) 333 334 335 def test_update_field_add_choice(): 336 """Test updating an existing field and adding a choice, should be allowed.""" 337 result = httpx.post( 338 f"{URL}/api/v1/field/spool/mychoicefield", 339 json={ 340 "name": "My choice field", 341 "field_type": "choice", 342 "choices": ["foo", "bar", "baz"], 343 "default_value": json.dumps(["foo"]), 344 "multi_choice": True, 345 }, 346 ) 347 assert_httpx_success(result) 348 349 result = httpx.post( 350 f"{URL}/api/v1/field/spool/mychoicefield", 351 json={ 352 "name": "My choice field", 353 "field_type": "choice", 354 "choices": ["foo", "bar", "baz", "qux"], 355 "default_value": json.dumps(["foo"]), 356 "multi_choice": True, 357 }, 358 ) 359 assert_httpx_success(result) 360 361 # Clean up 362 result = httpx.delete(f"{URL}/api/v1/field/spool/mychoicefield") 363 assert_httpx_success(result) 364 365 366 def test_update_field_remove_choice(): 367 """Test updating an existing field and removing a choice, should not be allowed.""" 368 result = httpx.post( 369 f"{URL}/api/v1/field/spool/mychoicefield", 370 json={ 371 "name": "My choice field", 372 "field_type": "choice", 373 "choices": ["foo", "bar", "baz"], 374 "default_value": json.dumps(["foo"]), 375 "multi_choice": True, 376 }, 377 ) 378 assert_httpx_success(result) 379 380 result = httpx.post( 381 f"{URL}/api/v1/field/spool/mychoicefield", 382 json={ 383 "name": "My choice field", 384 "field_type": "choice", 385 "choices": ["foo", "baz"], 386 "default_value": json.dumps(["foo"]), 387 "multi_choice": True, 388 }, 389 ) 390 assert result.status_code == 400 391 assert result.json()["message"] == "Cannot remove existing choices." 392 393 # Clean up 394 result = httpx.delete(f"{URL}/api/v1/field/spool/mychoicefield") 395 assert_httpx_success(result) 396 397 398 def test_update_field_change_multi_choice(): 399 """Test updating an existing field and changing the multi_choice setting, should not be allowed.""" 400 result = httpx.post( 401 f"{URL}/api/v1/field/spool/mychoicefield", 402 json={ 403 "name": "My choice field", 404 "field_type": "choice", 405 "choices": ["foo", "bar", "baz"], 406 "default_value": json.dumps(["foo"]), 407 "multi_choice": True, 408 }, 409 ) 410 assert_httpx_success(result) 411 412 result = httpx.post( 413 f"{URL}/api/v1/field/spool/mychoicefield", 414 json={ 415 "name": "My choice field", 416 "field_type": "choice", 417 "choices": ["foo", "bar", "baz"], 418 "default_value": json.dumps("foo"), 419 "multi_choice": False, 420 }, 421 ) 422 assert result.status_code == 400 423 assert result.json()["message"] == "Multi choice cannot be changed." 424 425 # Clean up 426 result = httpx.delete(f"{URL}/api/v1/field/spool/mychoicefield") 427 assert_httpx_success(result)