Coverage for tests/test.py: 100%

52 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-27 17:09 -0400

1from copy import deepcopy 

2import pytest 

3import pydantic 

4from src.overturetoosm.places import ( 

5 ConfidenceError, 

6 UnmatchedError, 

7 process_geojson, 

8 process_props, 

9) 

10import src.overturetoosm.objects as objects 

11import src.overturetoosm.utils as utils 

12 

13clean = { 

14 "name": "Primary Name", 

15 "brand": "Brand Name", 

16 "brand:wikidata": "Q123", 

17 "addr:street_address": "123 Main St", 

18 "addr:city": "City", 

19 "addr:postcode": "12345", 

20 "addr:state": "State", 

21 "addr:country": "Country", 

22 "phone": "+1234567890", 

23 "website": "https://example.com", 

24 "source": "dataset1 via overturetoosm", 

25 "office": "lawyer", 

26 "lawyer": "notary", 

27 "contact:facebook": "www.facebook.com/example", 

28} 

29 

30 

31@pytest.fixture 

32def geojson_dict(): 

33 return { 

34 "type": "FeatureCollection", 

35 "features": [ 

36 { 

37 "type": "Feature", 

38 "geometry": {"type": "Point", "coordinates": [-1, 1]}, 

39 "properties": { 

40 "id": "123", 

41 "version": 1, 

42 "update_time": "2022-01-01T00:00:00Z", 

43 "sources": [ 

44 { 

45 "property": "property1", 

46 "dataset": "dataset1", 

47 "record_id": "record1", 

48 "confidence": 0.8, 

49 } 

50 ], 

51 "names": { 

52 "primary": "Primary Name", 

53 "common": "Common Name", 

54 "rules": "Rules Name", 

55 }, 

56 "brand": { 

57 "wikidata": "Q123", 

58 "names": { 

59 "primary": "Brand Name", 

60 "common": "Common Name", 

61 "rules": "Rules Name", 

62 }, 

63 }, 

64 "categories": { 

65 "main": "notary_public", 

66 "alternate": ["alternate_category1", "alternate_category2"], 

67 }, 

68 "confidence": 0.8, 

69 "websites": ["https://example.com"], 

70 "socials": ["www.facebook.com/example"], 

71 "phones": ["+1234567890"], 

72 "addresses": [ 

73 { 

74 "freeform": "123 Main St", 

75 "locality": "City", 

76 "postcode": "12345", 

77 "region": "State", 

78 "country": "Country", 

79 } 

80 ], 

81 }, 

82 } 

83 ], 

84 } 

85 

86 

87@pytest.fixture 

88def props_dict(): 

89 return { 

90 "id": "123", 

91 "version": 1, 

92 "update_time": "2022-01-01T00:00:00Z", 

93 "sources": [ 

94 { 

95 "property": "property1", 

96 "dataset": "dataset1", 

97 "record_id": "record1", 

98 "confidence": 0.8, 

99 } 

100 ], 

101 "names": { 

102 "primary": "Primary Name", 

103 "common": "Common Name", 

104 "rules": "Rules Name", 

105 }, 

106 "brand": { 

107 "wikidata": "Q123", 

108 "names": { 

109 "primary": "Brand Name", 

110 "common": "Common Name", 

111 "rules": "Rules Name", 

112 }, 

113 }, 

114 "categories": { 

115 "main": "notary_public", 

116 "alternate": ["alternate_category1", "alternate_category2"], 

117 }, 

118 "confidence": 0.8, 

119 "websites": ["https://example.com"], 

120 "socials": ["www.facebook.com/example"], 

121 "phones": ["+1234567890"], 

122 "addresses": [ 

123 { 

124 "freeform": "123 Main St", 

125 "locality": "City", 

126 "postcode": "12345", 

127 "region": "State", 

128 "country": "Country", 

129 } 

130 ], 

131 } 

132 

133 

134def test_place_props(props_dict: dict): 

135 """Test that all properties are processed correctly""" 

136 new_props = process_props(props_dict) 

137 assert new_props == clean 

138 

139 

140def test_low_confidence(props_dict): 

141 """Test that properties with low confidence are not processed""" 

142 with pytest.raises(ConfidenceError): 

143 process_props(props_dict, confidence=0.9) 

144 

145 

146def test_confidence(props_dict): 

147 """Test that invalid properties are not processed""" 

148 props_dict["confidence"] = -0.1 

149 with pytest.raises(pydantic.ValidationError): 

150 process_props(props_dict) 

151 

152 

153def test_unmatched_error(props_dict): 

154 """Test that invalid properties are not processed""" 

155 props_dict["categories"]["main"] = "invalid_category" 

156 with pytest.raises(UnmatchedError): 

157 process_props(props_dict, unmatched="error") 

158 

159 

160def test_unmatched_ignore(props_dict): 

161 """Test that invalid properties are not processed""" 

162 props_dict["categories"]["main"] = "invalid_category" 

163 cl = deepcopy(clean) 

164 del cl["office"] 

165 del cl["lawyer"] 

166 assert process_props(props_dict, unmatched="ignore") == cl 

167 

168 

169def test_unmatched_force(props_dict): 

170 """Test that invalid properties are not processed""" 

171 cat = "invalid_category" 

172 props_dict["categories"]["main"] = cat 

173 cl = deepcopy(clean) 

174 del cl["office"] 

175 del cl["lawyer"] 

176 cl["type"] = cat 

177 assert process_props(props_dict, unmatched="force") == cl 

178 

179 

180def test_place_geojson(geojson_dict): 

181 """Test that all properties are processed correctly""" 

182 assert process_geojson(geojson_dict) == { 

183 "type": "FeatureCollection", 

184 "features": [ 

185 { 

186 "type": "Feature", 

187 "geometry": {"type": "Point", "coordinates": [-1, 1]}, 

188 "properties": clean, 

189 } 

190 ], 

191 } 

192 

193 

194def test_place_geojson_error(geojson_dict): 

195 """Test that all properties are processed correctly when error flag is set""" 

196 copy = deepcopy(geojson_dict) 

197 copy["features"][0]["properties"]["categories"]["main"] = "invalid_category" 

198 print(copy) 

199 assert process_geojson(geojson_dict, unmatched="error") == { 

200 "type": "FeatureCollection", 

201 "features": [ 

202 { 

203 "type": "Feature", 

204 "geometry": {"type": "Point", "coordinates": [-1, 1]}, 

205 "properties": clean, 

206 } 

207 ], 

208 } 

209 

210 

211def test_util_source() -> None: 

212 source_1 = objects.Sources( 

213 **{"property": "property1", "dataset": "dataset1", "confidence": 0.8} 

214 ) 

215 source_2 = objects.Sources( 

216 **{"property": "property2", "dataset": "dataset2", "confidence": 0.8} 

217 ) 

218 

219 assert ( 

220 utils.source_statement([source_1, source_2]) 

221 == "dataset1, dataset2 via overturetoosm" 

222 )