from typing import Any import pytest from backfill.models import Job, Manifest @pytest.mark.parametrize( "job, expected", [ pytest.param( {"job_type": "attach_and_detach", "keys": ["car", "piano"]}, {"job_type": "attach_and_detach", "keys": ["car", "piano"]}, id="valid job with keys and job_type", ), pytest.param( {"job_type": "attach_and_detach", "keys": [" car ", " piano "]}, {"job_type": "attach_and_detach", "keys": ["car", "piano"]}, id="valid job with keys that have extra whitespace", ), pytest.param( {"job_type": "attach_and_detach", "keys": [""]}, {"job_type": "attach_and_detach", "keys": [""]}, id="valid job with empty string key", ), pytest.param( {"job_type": "attach_and_detach", "keys": []}, {"job_type": "attach_and_detach", "keys": []}, id="valid job with empty list of keys", ), pytest.param( {"job_type": "attach_and_detach", "keys": "not a list"}, ValueError, id="invalid job with non-list keys", ), pytest.param( {"dogs": ["nugget", "waffles"]}, ValueError, id="invalid job with incorrect field", ), pytest.param( {"keys": ["car", "piano"]}, ValueError, id="job_type is required", ), pytest.param({}, ValueError, id="invalid job with no keys"), pytest.param("", ValueError, id="invalid job is not dict"), ], ) def test_job_model_validate(job: dict[str, Any], expected: Any) -> None: if expected is ValueError: with pytest.raises(ValueError): Job.model_validate(job) else: actual = Job.model_validate(job) assert actual == Job(**expected) @pytest.mark.parametrize( "manifest, expected", [ pytest.param( { "bucket": "dev-mybucket", "jobs": [{"job_type": "attach_and_detach", "keys": ["car", "piano"]}], }, { "bucket": "dev-mybucket", "jobs": [{"job_type": "attach_and_detach", "keys": ["car", "piano"]}], }, id="valid manifest with dev bucket", ), pytest.param( { "bucket": " qa-mybucket ", "jobs": [{"job_type": "attach_and_detach", "keys": ["car ", " piano"]}], }, { "bucket": "qa-mybucket", "jobs": [{"job_type": "attach_and_detach", "keys": ["car", "piano"]}], }, id="valid manifest with bucket name with extra whitespace", ), pytest.param( { "bucket": "prod-mybucket", "jobs": [ {"job_type": "attach_and_detach", "keys": ["car", "piano"]}, {"job_type": "attach_and_detach", "keys": ["house"]}, ], }, { "bucket": "prod-mybucket", "jobs": [ {"job_type": "attach_and_detach", "keys": ["car", "piano"]}, {"job_type": "attach_and_detach", "keys": ["house"]}, ], }, id="valid manifest with bucket and multiple jobs", ), pytest.param( {"bucket": "uat-mybucket", "jobs": []}, {"bucket": "uat-mybucket", "jobs": []}, id="valid manifest with empty jobs", ), pytest.param( { "bucket": "invalid-mybucket", "jobs": [{"job_type": "attach_and_detach", "keys": ["car", "piano"]}], }, ValueError, id="invalid manifest with invalid bucket prefix", ), ], ) def test_manifest_model_validate(manifest: dict[str, Any], expected: Any) -> None: if expected is ValueError: with pytest.raises(ValueError): Manifest.model_validate(manifest) else: actual = Manifest.model_validate(manifest) assert actual == Manifest(**expected)