# Copyright(C) 2018 Phyks
#
# This file is part of woob.
#
# woob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# woob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with woob. If not, see <http://www.gnu.org/licenses/>.
import itertools
from collections import Counter
from woob.capabilities.base import empty
from woob.capabilities.housing import POSTS_TYPES
[docs]class HousingTest:
"""
Testing class to standardize the housing modules tests.
"""
# Fields to be checked for values across all items in housings list
FIELDS_ALL_HOUSINGS_LIST = [
"id",
"type",
"advert_type",
"house_type",
"url",
"title",
"area",
"cost",
"currency",
"utilities",
"date",
"location",
"station",
"text",
"phone",
"rooms",
"bedrooms",
"DPE",
"GES",
"details",
]
# Fields to be checked for at least one item in housings list
FIELDS_ANY_HOUSINGS_LIST = ["photos"]
# Fields to be checked for values across all items when querying
# individually
FIELDS_ALL_SINGLE_HOUSING = [
"id",
"url",
"type",
"advert_type",
"house_type",
"title",
"area",
"cost",
"currency",
"utilities",
"date",
"location",
"station",
"text",
"phone",
"rooms",
"bedrooms",
"DPE",
"GES",
"details",
]
# Fields to be checked for values at least once for all items when querying
# individually
FIELDS_ANY_SINGLE_HOUSING = ["photos"]
# Some backends cannot distinguish between rent and furnished rent for
# single housing post. Set this to True if this is the case.
DO_NOT_DISTINGUISH_FURNISHED_RENT = False
[docs] def assertNotEmpty(self, obj, field):
self.assertFalse(empty(getattr(obj, field)), 'Field "%s" is empty and should not be.' % field)
[docs] def check_housing_lists(self, query, max_results=20):
results = list(itertools.islice(self.backend.search_housings(query), max_results))
self.assertGreater(len(results), 0)
for field in self.FIELDS_ANY_HOUSINGS_LIST:
self.assertTrue(any(not empty(getattr(x, field)) for x in results), 'Missing a "%s" field.' % field)
for x in results:
if "type" in self.FIELDS_ALL_HOUSINGS_LIST:
if self.DO_NOT_DISTINGUISH_FURNISHED_RENT and query.type in [
POSTS_TYPES.RENT,
POSTS_TYPES.FURNISHED_RENT,
]:
self.assertIn(x.type, [POSTS_TYPES.RENT, POSTS_TYPES.FURNISHED_RENT])
else:
self.assertEqual(x.type, query.type)
if "advert_type" in self.FIELDS_ALL_HOUSINGS_LIST:
self.assertIn(x.advert_type, query.advert_types)
if "house_type" in self.FIELDS_ALL_HOUSINGS_LIST:
self.assertIn(x.house_type, query.house_types)
for field in self.FIELDS_ALL_HOUSINGS_LIST:
self.assertNotEmpty(x, field)
if not empty(x.cost):
self.assertNotEmpty(x, "price_per_meter")
for photo in x.photos:
self.assertRegex(photo.url, r"^http(s?)://")
return results
[docs] def check_single_housing_all(self, housing, type, house_type, advert_type):
for field in self.FIELDS_ALL_SINGLE_HOUSING:
self.assertNotEmpty(housing, field)
if "type" in self.FIELDS_ALL_SINGLE_HOUSING:
if self.DO_NOT_DISTINGUISH_FURNISHED_RENT and type in [POSTS_TYPES.RENT, POSTS_TYPES.FURNISHED_RENT]:
self.assertIn(housing.type, [POSTS_TYPES.RENT, POSTS_TYPES.FURNISHED_RENT])
else:
self.assertEqual(housing.type, type)
if "house_type" in self.FIELDS_ALL_SINGLE_HOUSING:
if not empty(house_type):
self.assertEqual(housing.house_type, house_type)
else:
self.assertNotEmpty(housing, "house_type")
if "advert_type" in self.FIELDS_ALL_SINGLE_HOUSING:
self.assertEqual(housing.advert_type, advert_type)
[docs] def check_single_housing_any(self, housing, counter):
for field in self.FIELDS_ANY_SINGLE_HOUSING:
if not empty(getattr(housing, field)):
counter[field] += 1
for photo in housing.photos:
self.assertRegex(photo.url, r"^http(s?)://")
return counter
[docs] def check_against_query(self, query, max_results=20):
# Check housing listing results
results = self.check_housing_lists(query, max_results)
# Check mandatory fields in all housings
housing = self.backend.fillobj(results[0], self.FIELDS_ANY_SINGLE_HOUSING + self.FIELDS_ALL_SINGLE_HOUSING)
self.check_single_housing_all(housing, results[0].type, results[0].house_type, results[0].advert_type)
# Check fields that should appear in at least one housing
counter = Counter()
counter = self.check_single_housing_any(housing, counter)
for result in results[1:]:
if all(counter[field] > 0 for field in self.FIELDS_ANY_SINGLE_HOUSING):
break
housing = self.backend.fillobj(result, self.FIELDS_ANY_SINGLE_HOUSING + self.FIELDS_ALL_SINGLE_HOUSING)
counter = self.check_single_housing_any(housing, counter)
for field in self.FIELDS_ANY_SINGLE_HOUSING:
self.assertGreater(counter[field], 0, 'Optional field "%s" should appear at least once.' % field)