# 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
)