+ table_name = 'place_classtype_{}_{}'.format(phrase_class, phrase_type)
+
+ with temp_db_conn.cursor() as temp_db_cursor:
+ temp_db_cursor.execute('CREATE TABLE {}()'.format(table_name))
+
+ special_phrases_importer._grant_access_to_webuser(phrase_class, phrase_type)
+
+ assert check_grant_access(temp_db_conn, def_config.DATABASE_WEBUSER, phrase_class, phrase_type)
+
+def test_create_place_classtype_table_and_indexes(
+ temp_db_conn, def_config, placex_table,
+ special_phrases_importer):
+ """
+ Test that _create_place_classtype_table_and_indexes()
+ create the right place_classtype tables and place_id indexes
+ and centroid indexes and grant access to the web user
+ for the given set of pairs.
+ """
+ pairs = set([('class1', 'type1'), ('class2', 'type2')])
+
+ special_phrases_importer._create_place_classtype_table_and_indexes(pairs)
+
+ for pair in pairs:
+ assert check_table_exist(temp_db_conn, pair[0], pair[1])
+ assert check_placeid_and_centroid_indexes(temp_db_conn, pair[0], pair[1])
+ assert check_grant_access(temp_db_conn, def_config.DATABASE_WEBUSER, pair[0], pair[1])
+
+def test_process_xml_content(temp_db_conn, def_config, special_phrases_importer, word_table,
+ getorcreate_amenity_funcs, getorcreate_amenityoperator_funcs):
+ """
+ Test that _process_xml_content() process the given xml content right
+ by executing the right SQL functions for amenities and
+ by returning the right set of pairs.
+ """
+ class_test = 'aerialway'
+ type_test = 'zip_line'
+
+ #Converted output set to a dict for easy assert further.
+ results = dict(special_phrases_importer._process_xml_content(get_test_xml_wiki_content(), 'en'))
+
+ assert check_amenities_with_op(temp_db_conn)
+ assert check_amenities_without_op(temp_db_conn)
+ assert results[class_test] and type_test in results.values()
+
+def test_remove_non_existent_phrases_from_db(special_phrases_importer, default_phrases,
+ temp_db_conn):
+ """
+ Check for the remove_non_existent_phrases_from_db() method.
+
+ It should removed entries from the word table which are contained
+ in the words_phrases_to_delete set and not those also contained
+ in the words_phrases_still_exist set.
+
+ place_classtype tables contained in table_phrases_to_delete should
+ be deleted.
+ """
+ with temp_db_conn.cursor() as temp_db_cursor:
+ to_delete_phrase_tuple = ('normalized_word', 'class', 'type', 'near')
+ to_keep_phrase_tuple = (
+ 'normalized_word_exists', 'class_exists', 'type_exists', 'near'
+ )
+ special_phrases_importer.words_phrases_to_delete = {
+ to_delete_phrase_tuple,
+ to_keep_phrase_tuple
+ }
+ special_phrases_importer.words_phrases_still_exist = {
+ to_keep_phrase_tuple
+ }
+ special_phrases_importer.table_phrases_to_delete = {
+ 'place_classtype_testclasstypetable_to_delete'
+ }
+
+ query_words = 'SELECT word, class, type, operator FROM word;'
+ query_tables = """
+ SELECT table_name
+ FROM information_schema.tables
+ WHERE table_schema='public'
+ AND table_name like 'place_classtype_%';
+ """
+
+ special_phrases_importer._remove_non_existent_phrases_from_db()
+
+ temp_db_cursor.execute(query_words)
+ words_result = temp_db_cursor.fetchall()
+ temp_db_cursor.execute(query_tables)
+ tables_result = temp_db_cursor.fetchall()
+ assert len(words_result) == 1 and words_result[0] == [
+ 'normalized_word_exists', 'class_exists', 'type_exists', 'near'
+ ]
+ assert (len(tables_result) == 1 and
+ tables_result[0][0] == 'place_classtype_testclasstypetable_to_keep'
+ )
+
+def test_import_from_wiki(monkeypatch, temp_db_conn, def_config, special_phrases_importer, placex_table,
+ getorcreate_amenity_funcs, getorcreate_amenityoperator_funcs, word_table):
+ """
+ Check that the main import_from_wiki() method is well executed.
+ It should create the place_classtype table, the place_id and centroid indexes,
+ grand access to the web user and executing the SQL functions for amenities.
+ It should also update the database well by deleting or preserving existing entries
+ of the database.
+ """
+ #Add some data to the database before execution in order to test
+ #what is deleted and what is preserved.
+ with temp_db_conn.cursor() as temp_db_cursor:
+ temp_db_cursor.execute("""
+ INSERT INTO word VALUES(99999, ' animal shelter', 'animal shelter',
+ 'amenity', 'animal_shelter', null, 0, null);
+
+ INSERT INTO word VALUES(99999, ' wrong_lookup_token', 'wrong_normalized_word',
+ 'wrong_class', 'wrong_type', null, 0, 'near');
+
+ CREATE TABLE place_classtype_amenity_animal_shelter();
+ CREATE TABLE place_classtype_wrongclass_wrongtype();""")
+
+ monkeypatch.setattr('nominatim.tools.special_phrases.SpecialPhrasesImporter._get_wiki_content', mock_get_wiki_content)
+ special_phrases_importer.import_from_wiki(['en'])
+
+ class_test = 'aerialway'
+ type_test = 'zip_line'
+
+ assert check_table_exist(temp_db_conn, class_test, type_test)
+ assert check_placeid_and_centroid_indexes(temp_db_conn, class_test, type_test)
+ assert check_grant_access(temp_db_conn, def_config.DATABASE_WEBUSER, class_test, type_test)
+ assert check_amenities_with_op(temp_db_conn)
+ assert check_amenities_without_op(temp_db_conn)
+ assert check_table_exist(temp_db_conn, 'amenity', 'animal_shelter')
+ assert not check_table_exist(temp_db_conn, 'wrong_class', 'wrong_type')
+
+ #Format (query, should_return_something_bool) use to easily execute all asserts
+ queries_tests = set()
+
+ #Used to check that the correct phrase already in the word table before is still there.
+ query_correct_word = "SELECT * FROM word WHERE word = 'animal shelter'"
+ queries_tests.add((query_correct_word, True))
+
+ #Used to check if wrong phrase was deleted from the word table of the database.
+ query_wrong_word = "SELECT word FROM word WHERE word = 'wrong_normalized_word'"
+ queries_tests.add((query_wrong_word, False))
+
+ #Used to check that correct place_classtype table already in the datase before is still there.
+ query_existing_table = """
+ SELECT table_name
+ FROM information_schema.tables
+ WHERE table_schema='public'
+ AND table_name = 'place_classtype_amenity_animal_shelter';
+ """
+ queries_tests.add((query_existing_table, True))
+
+ #Used to check that wrong place_classtype table was deleted from the database.
+ query_wrong_table = """
+ SELECT table_name
+ FROM information_schema.tables
+ WHERE table_schema='public'
+ AND table_name = 'place_classtype_wrongclass_wrongtype';
+ """
+ queries_tests.add((query_wrong_table, False))
+
+ with temp_db_conn.cursor() as temp_db_cursor:
+ for query in queries_tests:
+ temp_db_cursor.execute(query[0])
+ if (query[1] == True):
+ assert temp_db_cursor.fetchone()
+ else:
+ assert not temp_db_cursor.fetchone()
+
+def mock_get_wiki_content(lang):
+ """
+ Mock the _get_wiki_content() method to return
+ static xml test file content.
+ """
+ return get_test_xml_wiki_content()
+
+def get_test_xml_wiki_content():
+ """
+ return the content of the static xml test file.
+ """
+ xml_test_content_path = (TEST_BASE_DIR / 'testdata' / 'special_phrases_test_content.txt').resolve()
+ with open(xml_test_content_path) as xml_content_reader:
+ return xml_content_reader.read()
+
+def check_table_exist(temp_db_conn, phrase_class, phrase_type):
+ """
+ Verify that the place_classtype table exists for the given
+ phrase_class and phrase_type.
+ """
+ table_name = 'place_classtype_{}_{}'.format(phrase_class, phrase_type)