def _check_tags( flask_app, expected ): #pylint: disable=too-many-locals """Check the tags in the UI and database.""" # get the complete list of expected tags expected_available = set() for tags in expected.values(): expected_available.update( tags ) def check_tags( sr ): name = get_search_result_names( [sr] )[ 0 ] tags = [ t.text for t in find_children( ".tag", sr ) ] if tags == expected[name]: return name return None # check the tags in the UI results = get_search_results() assert set( get_search_result_names( results ) ) == set( expected.keys() ) for sr in results: # check the tags in the search result name = wait_for( 2, lambda sr=sr: check_tags( sr ) ) # check the tags in the publication/article select_sr_menu_option( sr, "edit" ) dlg = wait_for_elem( 2, ".modal-form" ) select = ReactSelect( find_child( ".row.tags .react-select", dlg ) ) assert select.get_multiselect_values() == expected[ name ] # check that the list of available tags is correct # NOTE: We don't bother checking the tag order here. assert set( select.get_multiselect_choices() ) == expected_available.difference( expected[name] ) # close the dialog find_child( "button.cancel", dlg ).click() def fixup_tags( tags ): return [] if tags is None else tags # check the tags in the database for sr in results: if sr.text.startswith( "publication" ): pub_id = sr.get_attribute( "testing--pub_id" ) url = flask_app.url_for( "get_publication", pub_id=pub_id ) pub = json.load( urllib.request.urlopen( url ) ) assert expected[ pub["pub_name"] ] == fixup_tags( pub["pub_tags"] ) elif sr.text.startswith( "article" ): article_id = sr.get_attribute( "testing--article_id" ) url = flask_app.url_for( "get_article", article_id=article_id ) article = json.load( urllib.request.urlopen( url ) ) assert expected[ article["article_title"] ] == fixup_tags( article["article_tags"] )
def _update_values(dlg, vals): """Update an article's values in the form.""" for key, val in vals.items(): if key == "image": if val: change_image(dlg, val) else: remove_image(dlg) elif key in ("publication", "publisher"): row = find_child(".row.{}".format(key), dlg) select = ReactSelect(find_child(".react-select", row)) if not select.select.is_displayed(): key2 = "publisher" if key == "publication" else "publication" row2 = find_child(".row.{}".format(key2), dlg) find_child("label.parent-mode", row2).click() wait_for(2, select.select.is_displayed) select.select_by_name(val) elif key in ["authors", "scenarios", "tags"]: select = ReactSelect( find_child(".row.{} .react-select".format(key), dlg)) select.update_multiselect_values(*val) else: if key == "snippet": sel = ".row.snippet textarea" elif key == "pageno": sel = "input.pageno" else: sel = ".row.{} input".format(key) set_elem_text(find_child(sel, dlg), val)
def _update_values(dlg, vals): """Update a publication's values in the form.""" for key, val in vals.items(): if key == "image": if val: change_image(dlg, val) else: remove_image(dlg) elif key == "name": elem = find_child(".row.name .react-select input", dlg) set_elem_text(elem, val) elem.send_keys(Keys.RETURN) elif key == "publisher": select = ReactSelect( find_child(".row.publisher .react-select", dlg)) select.select_by_name(val) elif key == "tags": select = ReactSelect(find_child(".row.tags .react-select", dlg)) select.update_multiselect_values(*val) else: if key == "edition": sel = "input.edition" elif key == "description": sel = ".row.description textarea" else: sel = ".row.{} input".format(key) set_elem_text(find_child(sel, dlg), val)
def _check_scenarios(flask_app, all_scenarios, expected): """Check the scenarios of the test articles.""" # update the complete list of scenarios # NOTE: Unlike tags, scenarios remain in the database even if no-one is referencing them, # so we need to track them over the life of the entire series of tests. for scenarios in expected: all_scenarios.update(scenarios) def check_scenarios(sr_name, expected): sr = find_search_result(sr_name) sr_scenarios = [s.text for s in find_children(".scenario", sr)] if sr_scenarios == expected: return sr return None # check the scenarios in the UI for article_no, expected_scenarios in enumerate(expected): # check the scenarios in the article's search result sr_name = "article {}".format(1 + article_no) sr = wait_for( 2, lambda n=sr_name, e=expected_scenarios: check_scenarios(n, e)) # check the scenarios in the article's config select_sr_menu_option(sr, "edit") dlg = wait_for_elem(2, "#article-form") select = ReactSelect(find_child(".row.scenarios .react-select", dlg)) assert select.get_multiselect_values() == expected_scenarios # check that the list of available scenarios is correct assert select.get_multiselect_choices() == \ sorted( all_scenarios.difference( expected_scenarios ), key=lambda s: s.lower() ) # close the dialog find_child("button.cancel", dlg).click() # check the scenarios in the database url = flask_app.url_for("get_scenarios") scenarios = json.load(urllib.request.urlopen(url)) assert set(_make_scenario_display_name(a) for a in scenarios.values()) == all_scenarios
def _update_values(dlg, vals): """Update an article's values in the form.""" for key, val in vals.items(): if key == "image": if val: change_image(dlg, val) else: remove_image(dlg) elif key == "publication": select = ReactSelect( find_child(".row.publication .react-select", dlg)) select.select_by_name(val) elif key in ["authors", "scenarios", "tags"]: select = ReactSelect( find_child(".row.{} .react-select".format(key), dlg)) select.update_multiselect_values(*val) else: if key == "snippet": sel = ".row.snippet textarea" elif key == "pageno": sel = "input.pageno" else: sel = ".row.{} input".format(key) set_elem_text(find_child(sel, dlg), val)
def update_multiselect(elem, vals): select = ReactSelect(find_parent_by_class(elem, "react-select")) select.update_multiselect_values(*vals)
def update_react_select(elem, val): select = ReactSelect(find_parent_by_class(elem, "react-select")) select.select_by_name(val)
def test_publisher_articles(webdriver, flask_app, dbconn): #pylint: disable=too-many-statements """Test articles that are associated with a publisher (not publication).""" # initialize init_tests(webdriver, flask_app, dbconn, fixtures="publisher-articles.json") def check_parent_in_sr(sr, pub, publ): """Check the article's parent publication/publisher in a search result.""" if pub: elem = wait_for(2, lambda: find_child(".header a.publication", sr)) assert elem.is_displayed() assert elem.text == pub assert re.search(r"^http://.+?/publication/\d+", elem.get_attribute("href")) elif publ: elem = wait_for(2, lambda: find_child(".header a.publisher", sr)) assert elem.is_displayed() assert elem.text == publ assert re.search(r"^http://.+?/publisher/\d+", elem.get_attribute("href")) else: assert False, "At least one publication/publisher must be specified." def check_parent_in_dlg(dlg, pub, publ): """Check the article's parent publication/publication in the edit dialog.""" if pub: select = find_child(".row.publication .react-select", dlg) assert select.is_displayed() assert select.text == pub elif publ: select = find_child(".row.publisher .react-select", dlg) assert select.is_displayed() assert select.text == publ else: assert False, "At least one publication/publisher must be specified." # create an article associated with LFT create_article({"title": "test article", "publisher": "Le Franc Tireur"}) results = wait_for(2, get_search_results) assert len(results) == 1 sr = results[0] check_parent_in_sr(sr, None, "Le Franc Tireur") # open the article's dialog select_sr_menu_option(sr, "edit") dlg = wait_for_elem(2, "#article-form") check_parent_in_dlg(dlg, None, "Le Franc Tireur") # change the article to be associated with an MMP publication find_child(".row.publisher label.parent-mode").click() select = wait_for_elem(2, ".row.publication .react-select") ReactSelect(select).select_by_name("MMP News") find_child("button.ok", dlg).click() results = wait_for(2, get_search_results) assert len(results) == 1 sr = results[0] check_parent_in_sr(sr, "MMP News", None) # open the article's dialog select_sr_menu_option(sr, "edit") dlg = wait_for_elem(2, "#article-form") check_parent_in_dlg(dlg, "MMP News", None) # change the article to be associated with MMP (publisher) find_child(".row.publication label.parent-mode").click() select = wait_for_elem(2, ".row.publisher .react-select") ReactSelect(select).select_by_name("Multiman Publishing") find_child("button.ok", dlg).click() results = wait_for(2, get_search_results) assert len(results) == 1 sr = results[0] check_parent_in_sr(sr, None, "Multiman Publishing") # show the MMP publisher results = do_search("multiman") assert len(results) == 1 sr = results[0] collapsibles = find_children(".collapsible", sr) assert len(collapsibles) == 2 items = find_children("li a", collapsibles[1]) assert len(items) == 1 item = items[0] assert item.text == "test article" assert re.search(r"^http://.+?/article/\d+", item.get_attribute("href")) # delete the MMP publisher # NOTE: There are 2 MMP articles, the one that is in the "MMP News" publication, # and the test article we created above that is associated with the publisher. select_sr_menu_option(sr, "delete") check_ask_dialog( ("Delete this publisher?", "2 articles will also be deleted"), "ok") query = dbconn.execute("SELECT count(*) FROM article") assert query.scalar() == 0