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

1""" 

2Tests for graph/ckan_field.py - CKAN field mapping logic. 

3 

4Tests the prepare_data_dict function that applies field name mappings 

5to CKAN package dictionaries for use in graph transformations. 

6""" 

7import pytest 

8 

9from ckanext.udc.graph.ckan_field import prepare_data_dict, ckanFieldMapping 

10 

11 

12class TestPrepareDataDict: 

13 """Test prepare_data_dict function.""" 

14 

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 } 

22 

23 result = prepare_data_dict(data) 

24 

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" 

29 

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" 

34 

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 } 

41 

42 result = prepare_data_dict(data) 

43 

44 # pkg_name should take precedence for 'id' 

45 assert result["id"] == "package-name" 

46 

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 } 

52 

53 result = prepare_data_dict(data) 

54 

55 assert result["id"] == "original-id" 

56 

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 } 

63 

64 original_data = data.copy() 

65 result = prepare_data_dict(data) 

66 

67 # Original dict should not be modified 

68 assert data == original_data 

69 

70 # Result should have new mapped fields 

71 assert "title" in result 

72 

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 } 

84 

85 result = prepare_data_dict(data) 

86 

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" 

94 

95 def test_empty_string_values_preserved(self): 

96 """Test that empty string values are preserved.""" 

97 data = { 

98 "name": "dataset", 

99 "author": "" 

100 } 

101 

102 result = prepare_data_dict(data) 

103 

104 # Empty string should be preserved, not replaced with EMPTY_FIELD 

105 assert result["author"] == "" 

106 

107 

108class TestCKANFieldMapping: 

109 """Test the ckanFieldMapping dictionary.""" 

110 

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" 

117 

118 

119class TestRealWorldScenarios: 

120 """Test with real-world-like CKAN package dictionaries.""" 

121 

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 } 

145 

146 result = prepare_data_dict(data) 

147 

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" 

158 

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 } 

167 

168 result = prepare_data_dict(data) 

169 

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" 

174 

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 } 

183 

184 result = prepare_data_dict(data) 

185 

186 # Custom fields should be preserved 

187 assert result["custom_field"] == "custom_value" 

188 assert result["another_field"] == {"key": "value"} 

189 

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 } 

203 

204 result = prepare_data_dict(data) 

205 

206 assert result["title"]["en"] == "English Title" 

207 assert result["title"]["fr"] == "Titre français" 

208 assert result["description"]["en"] == "English description" 

209 

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 } 

218 

219 result = prepare_data_dict(data) 

220 

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"] 

225