Coverage for ckanext/udc/tests/graph/test_ckan_field.py: 100%
83 statements
« prev ^ index » next coverage.py v7.7.1, created at 2026-01-19 23:48 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2026-01-19 23:48 +0000
1"""
2Tests for graph/ckan_field.py - CKAN field mapping logic.
4Tests the prepare_data_dict function that applies field name mappings
5to CKAN package dictionaries for use in graph transformations.
6"""
7import pytest
9from ckanext.udc.graph.ckan_field import prepare_data_dict, ckanFieldMapping
12class TestPrepareDataDict:
13 """Test prepare_data_dict function."""
15 def test_basic_field_mapping(self):
16 """Test that basic fields are mapped correctly."""
17 data = {
18 "title_translated": {"en": "My Dataset", "fr": "Mon jeu de données"},
19 "description_translated": {"en": "Description"},
20 "url": "http://example.com/source"
21 }
23 result = prepare_data_dict(data)
25 # Original fields should still be present
26 assert result["title_translated"] == {"en": "My Dataset", "fr": "Mon jeu de données"}
27 assert result["description_translated"] == {"en": "Description"}
28 assert result["url"] == "http://example.com/source"
30 # Mapped fields should be accessible by normalized names
31 assert result["title"] == {"en": "My Dataset", "fr": "Mon jeu de données"}
32 assert result["description"] == {"en": "Description"}
33 assert result["source"] == "http://example.com/source"
35 def test_id_field_with_pkg_name(self):
36 """Test that pkg_name is used for id if available."""
37 data = {
38 "id": "original-id",
39 "pkg_name": "package-name"
40 }
42 result = prepare_data_dict(data)
44 # pkg_name should take precedence for 'id'
45 assert result["id"] == "package-name"
47 def test_id_field_without_pkg_name(self):
48 """Test that id is used when pkg_name is not available."""
49 data = {
50 "id": "original-id"
51 }
53 result = prepare_data_dict(data)
55 assert result["id"] == "original-id"
57 def test_preserves_original_data(self):
58 """Test that original data_dict is not modified."""
59 data = {
60 "name": "my-dataset",
61 "title_translated": {"en": "My Dataset"}
62 }
64 original_data = data.copy()
65 result = prepare_data_dict(data)
67 # Original dict should not be modified
68 assert data == original_data
70 # Result should have new mapped fields
71 assert "title" in result
73 def test_all_mappings_applied(self):
74 """Test that all field mappings are applied."""
75 data = {
76 "title_translated": {"en": "Title"},
77 "description_translated": {"en": "Desc"},
78 "tags_translated": {"en": ["tag1"]},
79 "author": "John Doe",
80 "author_email": "john@example.com",
81 "url": "http://example.com",
82 "version": "1.0"
83 }
85 result = prepare_data_dict(data)
87 assert result["title"] == {"en": "Title"}
88 assert result["description"] == {"en": "Desc"}
89 assert result["tags"] == {"en": ["tag1"]}
90 assert result["author"] == "John Doe"
91 assert result["author_email"] == "john@example.com"
92 assert result["source"] == "http://example.com"
93 assert result["version"] == "1.0"
95 def test_empty_string_values_preserved(self):
96 """Test that empty string values are preserved."""
97 data = {
98 "name": "dataset",
99 "author": ""
100 }
102 result = prepare_data_dict(data)
104 # Empty string should be preserved, not replaced with EMPTY_FIELD
105 assert result["author"] == ""
108class TestCKANFieldMapping:
109 """Test the ckanFieldMapping dictionary."""
111 def test_mapping_values(self):
112 """Test that mapping values are correct."""
113 assert ckanFieldMapping["title"] == "title_translated"
114 assert ckanFieldMapping["description"] == "description_translated"
115 assert ckanFieldMapping["tags"] == "tags_translated"
116 assert ckanFieldMapping["source"] == "url"
119class TestRealWorldScenarios:
120 """Test with real-world-like CKAN package dictionaries."""
122 def test_complete_package_dict(self):
123 """Test with a complete package dictionary."""
124 data = {
125 "name": "housing-data-2025",
126 "title_translated": {
127 "en": "Housing Statistics 2025",
128 "fr": "Statistiques sur le logement 2025"
129 },
130 "description_translated": {
131 "en": "Comprehensive housing data for urban areas",
132 "fr": "Données complètes sur le logement pour les zones urbaines"
133 },
134 "tags_translated": {
135 "en": ["housing", "statistics", "urban"],
136 "fr": ["logement", "statistiques", "urbain"]
137 },
138 "id": "abc-123-def-456",
139 "pkg_name": "housing-data-2025",
140 "author": "Urban Data Centre",
141 "author_email": "data@urbancentre.ca",
142 "url": "http://data.urbancentre.ca/datasets/housing-2025",
143 "version": "1.0"
144 }
146 result = prepare_data_dict(data)
148 # Test all accessors
149 assert result["name"] == "housing-data-2025"
150 assert result["id"] == "housing-data-2025" # pkg_name takes precedence
151 assert result["title"]["en"] == "Housing Statistics 2025"
152 assert result["description"]["fr"] == "Données complètes sur le logement pour les zones urbaines"
153 assert "housing" in result["tags"]["en"]
154 assert result["author"] == "Urban Data Centre"
155 assert result["author_email"] == "data@urbancentre.ca"
156 assert result["source"] == "http://data.urbancentre.ca/datasets/housing-2025"
157 assert result["version"] == "1.0"
159 def test_package_dict_for_update(self):
160 """Test package dict used for update operation."""
161 data = {
162 "pkg_name": "existing-dataset",
163 "id": "old-id-should-not-be-used",
164 "title_translated": {"en": "Updated Title"},
165 "version": "2.0"
166 }
168 result = prepare_data_dict(data)
170 # For updates, pkg_name should be used as id
171 assert result["id"] == "existing-dataset"
172 assert result["title"]["en"] == "Updated Title"
173 assert result["version"] == "2.0"
175 def test_package_dict_with_custom_fields(self):
176 """Test that custom fields (not in mapping) are preserved."""
177 data = {
178 "name": "dataset",
179 "id": "123",
180 "custom_field": "custom_value",
181 "another_field": {"key": "value"}
182 }
184 result = prepare_data_dict(data)
186 # Custom fields should be preserved
187 assert result["custom_field"] == "custom_value"
188 assert result["another_field"] == {"key": "value"}
190 def test_multilingual_fields(self):
191 """Test accessing multilingual fields."""
192 data = {
193 "title_translated": {
194 "en": "English Title",
195 "fr": "Titre français",
196 "es": "Título español"
197 },
198 "description_translated": {
199 "en": "English description",
200 "fr": "Description française"
201 }
202 }
204 result = prepare_data_dict(data)
206 assert result["title"]["en"] == "English Title"
207 assert result["title"]["fr"] == "Titre français"
208 assert result["description"]["en"] == "English description"
210 def test_tags_translated(self):
211 """Test accessing translated tags."""
212 data = {
213 "tags_translated": {
214 "en": ["housing", "transport", "health"],
215 "fr": ["logement", "transport", "santé"]
216 }
217 }
219 result = prepare_data_dict(data)
221 assert len(result["tags"]["en"]) == 3
222 assert "housing" in result["tags"]["en"]
223 assert len(result["tags"]["fr"]) == 3
224 assert "logement" in result["tags"]["fr"]