Total Complexity | 78 |
Total Lines | 363 |
Duplicated Lines | 25.07 % |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like TestOptimizationsMocked often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # -*- coding: utf-8 -*- |
||
41 | class TestOptimizationsMocked(MockerResourceWithNetworkClient): |
||
42 | |||
43 | resource_module = M |
||
44 | |||
45 | def test_create(self): |
||
46 | |||
47 | sample_response_data = load_json( |
||
48 | # '..', '..', '..', |
||
49 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
50 | 'create_response.json' |
||
51 | ) |
||
52 | |||
53 | self.set_response(data=sample_response_data) |
||
54 | |||
55 | o = Optimization() |
||
56 | o.algorithm_type = AlgorithmTypeEnum.TSP |
||
57 | o.state = OptimizationStateEnum.MATRIX_PROCESSING |
||
58 | o.optimization_factor = OptimizationFactorEnum.DISTANCE |
||
59 | o.route_datetime = datetime.datetime(2016, 6, 17) |
||
60 | |||
61 | r = Optimizations(api_key='test') |
||
62 | res = r.create(o) |
||
63 | |||
64 | # log.debug(self.mock_fluent_request_class.mock_calls) |
||
65 | # call(), |
||
66 | # call().method('POST'), |
||
67 | # call().url('https://www.route4me.com//api.v4/optimization_problem.php'), |
||
68 | # call().qs(None), |
||
69 | # call().json({'links': {}, 'parameters': {'algorithm_type': 1}}), |
||
70 | # call().user_agent('requests/2.18.3 (Linux 4.8.0-53-generic) Route4Me-Python-SDK/0.1.0 CPython/3.5.2'), |
||
71 | # call().header('Route4Me-User-Agent', 'requests/2.18.3 (Linux 4.8.0-53-generic) ..'), |
||
72 | # call().accept('application/json'), |
||
73 | # call().header('Route4Me-Api-Key', 'test'), |
||
74 | # call().qs({'format': 'json', 'api_key': 'test'}), |
||
75 | # call().send(), |
||
76 | # call().send().json() |
||
77 | |||
78 | # ---------- |
||
79 | # assertions |
||
80 | mock_freq = self.last_request() |
||
81 | mock_freq.method.assert_called_with('POST') |
||
82 | mock_freq.url.assert_called_with( |
||
83 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
84 | ) |
||
85 | mock_freq.json.assert_called_with(dict(o)) |
||
86 | |||
87 | # assertions on response |
||
88 | assert isinstance(res, Optimization) |
||
89 | assert res.ID == '1EDB78F63556D99336E06A13A34CF139' |
||
90 | assert res.name == 'Fri, 17 Jun 2016 08:21:59 +0000 UTC' |
||
91 | assert res.algorithm_type == AlgorithmTypeEnum.TSP |
||
92 | assert res.state == OptimizationStateEnum.MATRIX_PROCESSING |
||
93 | assert res.optimization_factor == OptimizationFactorEnum.DISTANCE |
||
94 | assert res.member_id == 1 |
||
95 | assert res.vehicle_id is None |
||
96 | assert res.device_id is None |
||
97 | |||
98 | assert res.route_datetime == datetime.datetime(2016, 6, 17, tzinfo=pytz.utc) |
||
99 | |||
100 | def test_create_with_callback(self): |
||
101 | |||
102 | sample_response_data = load_json( |
||
103 | # '..', '..', '..', |
||
104 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
105 | 'create_response.json' |
||
106 | ) |
||
107 | |||
108 | self.set_response(data=sample_response_data) |
||
109 | |||
110 | o = Optimization() |
||
111 | o.algorithm_type = AlgorithmTypeEnum.TSP |
||
112 | o.state = OptimizationStateEnum.MATRIX_PROCESSING |
||
113 | o.optimization_factor = OptimizationFactorEnum.DISTANCE |
||
114 | |||
115 | r = Optimizations(api_key='test') |
||
116 | res = r.create( |
||
117 | optimization_data=o, |
||
118 | optimized_callback_url='https://callback.route4me.com/callback?q=1' |
||
119 | ) |
||
120 | |||
121 | # ---------- |
||
122 | # assertions |
||
123 | |||
124 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
125 | # call(), |
||
126 | # call().method('POST'), |
||
127 | # call().url('https://www.route4me.com/api.v4/optimization_problem.php'), |
||
128 | # call().qs({'optimized_callback_url': 'https://callback.route4me.com/callback?q=1'}), |
||
129 | # call().json({'links': {}, 'parameters': {'store_route': True, 'algorithm_type': 1, |
||
130 | # 'route_max_duration': 86400, 'optimize': 'Distance'}, 'state': 2, 'addresses': []}), |
||
131 | # call().user_agent('requests/2.18.3 (Linux 4.8.0-53-generic) Route4Me-Python-SDK/0.1.0 CPython/3.5.2'), |
||
132 | # call().header('Route4Me-Agent', |
||
133 | # 'requests/2.18.3 (Linux 4.8.0-53-generic) Route4Me-Python-SDK/0.1.0 CPython/3.5.2'), |
||
134 | # call().header('Route4Me-Agent-Release', '0.1.0-dev.5'), |
||
135 | # call().header('Route4Me-Agent-Commit', None), |
||
136 | # call().header('Route4Me-Agent-Build', None), |
||
137 | # call().accept('application/json'), |
||
138 | # call().header('Route4Me-Api-Key', 'test'), |
||
139 | # call().qs({'api_key': 'test', 'format': 'json'}), |
||
140 | # call().send(), |
||
141 | # call().send().json() |
||
142 | |||
143 | mock_freq = self.last_request() |
||
144 | mock_freq.method.assert_called_with('POST') |
||
145 | mock_freq.url.assert_called_with( |
||
146 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
147 | ) |
||
148 | mock_freq.json.assert_called_with(dict(o)) |
||
149 | mock_freq.qs.assert_any_call({ |
||
150 | 'optimized_callback_url': 'https://callback.route4me.com/callback?q=1', |
||
151 | }) |
||
152 | |||
153 | # assertions on response |
||
154 | assert isinstance(res, Optimization) |
||
155 | assert res.ID == '1EDB78F63556D99336E06A13A34CF139' |
||
156 | |||
157 | View Code Duplication | def test_get(self): |
|
|
|||
158 | |||
159 | sample_response_data = load_json( |
||
160 | # '..', '..', '..', |
||
161 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
162 | 'get_response.json' |
||
163 | ) |
||
164 | |||
165 | self.set_response(data=sample_response_data) |
||
166 | |||
167 | r = Optimizations(api_key='test') |
||
168 | res = r.get('07372F2CF3814EC6DFFAFE92E22771AA') |
||
169 | |||
170 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
171 | |||
172 | # ---------- |
||
173 | # assertions |
||
174 | mock_freq = self.last_request() |
||
175 | mock_freq.method.assert_called_with('GET') |
||
176 | mock_freq.url.assert_called_with( |
||
177 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
178 | ) |
||
179 | mock_freq.qs.assert_any_call({ |
||
180 | 'optimization_problem_id': '07372F2CF3814EC6DFFAFE92E22771AA' |
||
181 | }) |
||
182 | assert not mock_freq.json.called |
||
183 | assert not mock_freq.data.called |
||
184 | |||
185 | # assertions on response |
||
186 | assert isinstance(res, Optimization) |
||
187 | assert res.ID == '07372F2CF3814EC6DFFAFE92E22771AA' |
||
188 | assert res.name == 'Sunday 10th of April 2016 01:20 AM (+03:00)' |
||
189 | assert res.algorithm_type == AlgorithmTypeEnum.CVRP_TW_SD |
||
190 | assert res.state == OptimizationStateEnum.OPTIMIZED |
||
191 | assert res.optimization_factor == OptimizationFactorEnum.TIME |
||
192 | assert res.member_id == 44143 |
||
193 | assert res.vehicle_id is None |
||
194 | assert res.device_id is None |
||
195 | assert res.round_trip is True |
||
196 | |||
197 | log.debug(res) |
||
198 | assert isinstance(res.addresses, list) |
||
199 | assert len(res.addresses) > 0 |
||
200 | a0 = res.addresses[0] |
||
201 | assert isinstance(a0, Address) |
||
202 | assert a0.ID == 154456307 |
||
203 | |||
204 | View Code Duplication | def test_list_no_states(self): |
|
205 | |||
206 | sample_response_data = load_json( |
||
207 | # '..', '..', '..', |
||
208 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
209 | 'list_response.json' |
||
210 | ) |
||
211 | |||
212 | self.set_response(data=sample_response_data) |
||
213 | |||
214 | r = Optimizations(api_key='test') |
||
215 | res = r.list() |
||
216 | |||
217 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
218 | |||
219 | # ---------- |
||
220 | # assertions |
||
221 | mock_freq = self.last_request() |
||
222 | mock_freq.method.assert_called_with('GET') |
||
223 | mock_freq.url.assert_called_with( |
||
224 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
225 | ) |
||
226 | mock_freq.qs.assert_any_call({}) |
||
227 | |||
228 | assert not mock_freq.json.called |
||
229 | assert not mock_freq.data.called |
||
230 | |||
231 | # assertions on response |
||
232 | assert isinstance(res, list) |
||
233 | assert isinstance(res, PagedList) |
||
234 | assert res.total == 447 |
||
235 | assert res.limit is None |
||
236 | assert res.offset is None |
||
237 | |||
238 | res0 = res[0] |
||
239 | assert isinstance(res0, Optimization) |
||
240 | assert res0.ID == '7EC3FC88737C29E93A54E88243ACBC77' |
||
241 | assert res0.name == 'Fri, 20 May 2016 12:43:46 +0000 UTC' |
||
242 | assert res0.algorithm_type == AlgorithmTypeEnum.CVRP_TW_SD |
||
243 | assert res0.state == OptimizationStateEnum.INITIAL |
||
244 | assert res0.optimization_factor == OptimizationFactorEnum.DISTANCE |
||
245 | assert res0.member_id == 1 |
||
246 | assert res0.vehicle_id is None |
||
247 | assert res0.device_id is None |
||
248 | assert res0.round_trip is True |
||
249 | |||
250 | def test_list_with_states(self): |
||
251 | |||
252 | sample_response_data = load_json( |
||
253 | # '..', '..', '..', |
||
254 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
255 | 'list_response.json' |
||
256 | ) |
||
257 | |||
258 | self.set_response(data=sample_response_data) |
||
259 | |||
260 | r = Optimizations(api_key='test') |
||
261 | res = r.list(states=[OptimizationStateEnum.INITIAL, OptimizationStateEnum.OPTIMIZED]) |
||
262 | |||
263 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
264 | |||
265 | # ---------- |
||
266 | # assertions |
||
267 | mock_freq = self.last_request() |
||
268 | mock_freq.method.assert_called_with('GET') |
||
269 | mock_freq.url.assert_called_with( |
||
270 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
271 | ) |
||
272 | mock_freq.qs.assert_any_call({ |
||
273 | 'state': '1,4' |
||
274 | }) |
||
275 | |||
276 | assert not mock_freq.json.called |
||
277 | assert not mock_freq.data.called |
||
278 | |||
279 | # assertions on response |
||
280 | assert isinstance(res, list) |
||
281 | assert isinstance(res, PagedList) |
||
282 | assert res.total == 447 |
||
283 | assert res.limit is None |
||
284 | assert res.offset is None |
||
285 | |||
286 | res0 = res[0] |
||
287 | assert isinstance(res0, Optimization) |
||
288 | |||
289 | def test_update(self): |
||
290 | |||
291 | sample_response_data = load_json( |
||
292 | # '..', '..', '..', |
||
293 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
294 | 'reoptimization_response.json' |
||
295 | ) |
||
296 | |||
297 | sample_optimization_data = load_json( |
||
298 | # '..', '..', '..', |
||
299 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
300 | 'reoptimization_request.json' |
||
301 | ) |
||
302 | |||
303 | self.set_response(data=sample_response_data) |
||
304 | |||
305 | ep = Optimizations(api_key='test') |
||
306 | res = ep.update( |
||
307 | ID='07372F2CF3814EC6DFFAFE92E22771AA', |
||
308 | optimization_data=sample_optimization_data, |
||
309 | ) |
||
310 | |||
311 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
312 | |||
313 | # ---------- |
||
314 | # assertions |
||
315 | mock_freq = self.last_request() |
||
316 | mock_freq.method.assert_called_with('PUT') |
||
317 | mock_freq.url.assert_called_with( |
||
318 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
319 | ) |
||
320 | mock_freq.qs.assert_any_call({ |
||
321 | 'optimization_problem_id': '07372F2CF3814EC6DFFAFE92E22771AA', |
||
322 | 'reoptimize': '0', |
||
323 | }) |
||
324 | mock_freq.json.assert_called_with(sample_optimization_data) |
||
325 | assert not mock_freq.data.called |
||
326 | |||
327 | # assertions on response |
||
328 | assert isinstance(res, Optimization) |
||
329 | assert res.ID == '07372F2CF3814EC6DFFAFE92E22771AA' |
||
330 | assert res.name == 'Sunday 10th of April 2016 01:20 AM (+03:00)' |
||
331 | assert res.algorithm_type == AlgorithmTypeEnum.CVRP_TW_SD |
||
332 | assert res.state == OptimizationStateEnum.INITIAL |
||
333 | assert res.optimization_factor == OptimizationFactorEnum.TIME |
||
334 | assert res.member_id == 44143 |
||
335 | assert res.vehicle_id is None |
||
336 | assert res.device_id is None |
||
337 | assert res.round_trip is True |
||
338 | |||
339 | def test_remove(self): |
||
340 | |||
341 | sample_response_data = load_json( |
||
342 | |||
343 | # '..', '..', '..', |
||
344 | 'submodules', 'route4me-api-data-examples', 'Optimizations', |
||
345 | 'remove_response.json' |
||
346 | ) |
||
347 | |||
348 | self.set_response(data=sample_response_data) |
||
349 | |||
350 | opt_id = 'DE62B03510AB5A6A876093F30F6C7BF5' |
||
351 | r = Optimizations(api_key='test') |
||
352 | res = r.remove(ID=opt_id) |
||
353 | |||
354 | # log.debug(self.mock_fluent_request_class.mock_calls) |
||
355 | |||
356 | # ---------- |
||
357 | # assertions |
||
358 | mock_freq = self.last_request() |
||
359 | mock_freq.method.assert_called_with('DELETE') |
||
360 | mock_freq.url.assert_called_with( |
||
361 | 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
362 | ) |
||
363 | mock_freq.qs.assert_any_call({ |
||
364 | 'optimization_problem_id': opt_id |
||
365 | }) |
||
366 | mock_freq.json.assert_called_once_with(None) |
||
367 | |||
368 | assert not mock_freq.data.called |
||
369 | |||
370 | assert res is True |
||
371 | # assertions on response |
||
372 | |||
373 | def test_remove_failed(self): |
||
374 | |||
375 | self.set_response(data=None) |
||
376 | |||
377 | opt_id = 'DE62B03510AB5A6A876093F30F6C7BF5' |
||
378 | r = Optimizations(api_key='test') |
||
379 | |||
380 | with pytest.raises(Route4MeApiError) as exc_info: |
||
381 | r.remove(ID=opt_id) |
||
382 | |||
383 | log.debug(self.mock_fluent_request_class.mock_calls) |
||
384 | |||
385 | exc = exc_info.value |
||
386 | assert exc is not None |
||
387 | |||
388 | # TODO: implement this! |
||
389 | # assert exc.method == 'DELETE' |
||
390 | # assert exc.url == 'https://www.route4me.com/api.v4/optimization_problem.php' |
||
391 | |||
392 | def test_reoptimize(self): |
||
393 | |||
394 | self.set_response(data={}) |
||
395 | |||
396 | ep = Optimizations(api_key='test') |
||
397 | |||
398 | with mock.patch.object(ep, 'update') as mock_update: |
||
399 | ep.reoptimize(ID='07372F2CF3814EC6DFFAFE92E22771AA') |
||
400 | |||
401 | mock_update.assert_called_once_with( |
||
402 | ID='07372F2CF3814EC6DFFAFE92E22771AA', |
||
403 | reoptimize=True |
||
404 | ) |
||
405 |