def test_search_articles( webdriver, flask_app, dbconn ): """Test searching articles.""" # initialize init_tests( webdriver, flask_app, dbconn ) # test searching article titles/subtitles/snippets _do_test_searches( ["low","some","game"], [] ) create_article( { "title": "Hit 'Em High, Or Hit 'Em Low", "subtitle": "Some things about light mortars you might like to know", "snippet": "Light mortars in ASL can be game winners." } ) _do_test_searches( ["low","some","game"], ["Hit 'Em High, Or Hit 'Em Low"] ) # edit the article sr = find_search_result( "Hit 'Em High, Or Hit 'Em Low" ) edit_article( sr, { "title": "Hit 'Em Hard", "subtitle": "Where it hurts!", "snippet": "Always the best way to do things." } ) _do_test_searches( ["low","some","game"], [] ) _do_test_searches( ["hard","hurt","best"], ["Hit 'Em Hard"] ) # delete the article sr = find_search_result( "Hit 'Em Hard" ) select_sr_menu_option( sr, "delete" ) check_ask_dialog( "Delete this article?", "ok" ) _do_test_searches( ["hard","hurt","best"], [] )
def test_delete_article(webdriver, flask_app, dbconn): """Test deleting articles.""" # initialize init_tests(webdriver, flask_app, dbconn, fixtures="articles.json") # start to delete an article, but cancel the operation article_name = "Smoke Gets In Your Eyes" results = do_search(SEARCH_ALL_ARTICLES) result_names = get_search_result_names(results) sr = find_search_result(article_name, results) select_sr_menu_option(sr, "delete") check_ask_dialog(("Delete this article?", article_name), "cancel") # check that search results are unchanged on-screen results2 = get_search_results() assert results2 == results # check that the search results are unchanged in the database results3 = do_search(SEARCH_ALL_ARTICLES) assert get_search_result_names(results3) == result_names # delete the article sr = find_search_result(article_name, results3) select_sr_menu_option(sr, "delete") set_toast_marker("info") check_ask_dialog(("Delete this article?", article_name), "ok") wait_for(2, lambda: check_toast("info", "The article was deleted.")) # check that search result was removed on-screen wait_for(2, lambda: article_name not in get_search_result_names()) # check that the search result was deleted from the database results = do_search(SEARCH_ALL_ARTICLES) assert article_name not in get_search_result_names(results)
def test_search_publishers( webdriver, flask_app, dbconn ): """Test searching publishers.""" # initialize init_tests( webdriver, flask_app, dbconn ) # test searching publisher names/descriptions _do_test_searches( ["hill","original"], [] ) create_publisher( { "name": "Avalon Hill", "description": "The original ASL vendor." } ) _do_test_searches( ["hill","original"], ["Avalon Hill"] ) # edit the publisher sr = find_search_result( "Avalon Hill" ) edit_publisher( sr, { "name": "Avalon Mountain", "description": "The first ASL vendor." } ) _do_test_searches( ["hill","original"], [] ) _do_test_searches( ["mountain","first"], ["Avalon Mountain"] ) # delete the publisher sr = find_search_result( "Avalon Mountain" ) select_sr_menu_option( sr, "delete" ) check_ask_dialog( "Delete this publisher?", "ok" ) _do_test_searches( ["hill","original","mountain","first"], [] )
def test_search_publications( webdriver, flask_app, dbconn ): """Test searching publications.""" # initialize init_tests( webdriver, flask_app, dbconn ) # test searching publication names/descriptions _do_test_searches( ["journal","good"], [] ) create_publication( { "name": "ASL Journal", "description": "A pretty good magazine." } ) _do_test_searches( ["journal","good"], ["ASL Journal"] ) # edit the publication sr = find_search_result( "ASL Journal" ) edit_publication( sr, { "name": "ASL Magazine", "description": "Not a bad magazine." } ) _do_test_searches( ["journal","good"], [] ) _do_test_searches( ["magazine","bad"], ["ASL Magazine"] ) # delete the publication sr = find_search_result( "ASL Magazine" ) select_sr_menu_option( sr, "delete" ) check_ask_dialog( "Delete this publication?", "ok" ) _do_test_searches( ["journal","good","magazine","bad"], [] )
def do_test(pub_name, expected_warning, expected_articles): # initialize load_fixtures(session, "cascading-deletes-2.json") results = do_search(SEARCH_ALL) # delete the specified publication sr = find_search_result(pub_name, results) select_sr_menu_option(sr, "delete") check_ask_dialog( ("Delete this publication?", pub_name, expected_warning), "ok") def check_results(): results = wait_for(2, lambda: get_results(len(expected_articles))) assert set(results) == set(expected_articles) def get_results(expected_len): # NOTE: The UI will remove anything that has been deleted, so we need to # give it a bit of time to finish doing this. try: results = get_search_result_names() except StaleElementReferenceException: return None results = [r for r in results if r.startswith("article")] if len(results) == expected_len: return results return None # check that deleted associated articles were removed from the UI check_results() # check that associated articles were removed from the database results = do_search(SEARCH_ALL_ARTICLES) check_results()
def test_delete_publication(webdriver, flask_app, dbconn): """Test deleting publications.""" # initialize init_tests(webdriver, flask_app, dbconn, fixtures="publications.json") # start to delete a publication, but cancel the operation article_title = "ASL Journal (2)" results = do_search(SEARCH_ALL_PUBLICATIONS) result_names = get_search_result_names(results) sr = find_search_result(article_title, results) select_sr_menu_option(sr, "delete") check_ask_dialog(("Delete this publication?", article_title), "cancel") # check that search results are unchanged on-screen results2 = get_search_results() assert results2 == results # check that the search results are unchanged in the database results3 = do_search(SEARCH_ALL_PUBLICATIONS) assert get_search_result_names(results3) == result_names # delete the publication sr = find_search_result(article_title, results3) select_sr_menu_option(sr, "delete") set_toast_marker("info") check_ask_dialog(("Delete this publication?", article_title), "ok") wait_for(2, lambda: check_toast("info", "The publication was deleted.")) # check that search result was removed on-screen wait_for(2, lambda: article_title not in get_search_result_names()) # check that the search result was deleted from the database results = do_search(SEARCH_ALL_PUBLICATIONS) assert article_title not in get_search_result_names(results)
def do_test( publ_name, expected_warning, expected_deletions ): # initialize load_fixtures( session, "cascading-deletes-1.json" ) results = do_search( SEARCH_ALL ) # delete the specified publisher sr = find_search_result( publ_name, results ) select_sr_menu_option( sr, "delete" ) check_ask_dialog( ( "Delete this publisher?", publ_name, expected_warning ), "ok" ) # check that deleted associated publications/articles were removed from the UI def check_publications(): check_results( "publication", [ "2", "3", "4", "5a", "5b", "6a", "6b", "7a", "7b", "8a", "8b" ], expected_deletions ) def check_articles(): check_results( "article", [ "3", "4a", "4b", "6a", "7a", "7b", "8a.1", "8a.2", "8b.1", "8b.2" ], expected_deletions ) check_publications() check_articles() # check that associated publications/articles were removed from the database results = do_search( SEARCH_ALL ) check_publications() check_articles()
def test_publication_lists( webdriver, flask_app, dbconn ): """Test showing publications that belong a publisher.""" # initialize init_tests( webdriver, flask_app, dbconn, fixtures="publishers.json" ) def check_publications( results, expected ): for publ_name,pub_name in expected.items(): publ_sr = find_search_result( publ_name, results ) pubs = find_child( ".collapsible", publ_sr ) if pub_name: # check that the publication appears in the publisher's search result assert find_child( ".caption", pubs ).text == "Publications:" pubs = find_children( "li", pubs ) assert len(pubs) == 1 assert pubs[0].text == pub_name else: # check that the publisher has no associated publications assert pubs is None # check that the publishers have no publications associated with them results = do_search( SEARCH_ALL_PUBLISHERS ) publ_name1, publ_name2 = "Avalon Hill", "Multiman Publishing" check_publications( results, { publ_name1: None, publ_name2: None } ) # create a publication that has no parent publisher create_publication( { "name": "no parent" } ) check_publications( results, { publ_name1: None, publ_name2: None } ) # create a publication that has a parent publisher pub_name = "test publication" create_publication( { "name": pub_name, "publisher": publ_name1 } ) check_publications( results, { publ_name1: pub_name, publ_name2: None } ) # move the publication to another publisher pub_sr = find_search_result( pub_name ) edit_publication( pub_sr, { "publisher": publ_name2 } ) check_publications( results, { publ_name1: None, publ_name2: pub_name } ) # change the publication to have no parent publisher edit_publication( pub_sr, { "publisher": "(none)" } ) check_publications( results, { publ_name1: None, publ_name2: None } ) # move the publication back to a publisher edit_publication( pub_sr, { "publisher": publ_name1 } ) check_publications( results, { publ_name1: pub_name, publ_name2: None } ) # delete the publication select_sr_menu_option( pub_sr, "delete" ) check_ask_dialog( ( "Delete this publication?", pub_name ), "ok" ) check_publications( results, { publ_name1: None, publ_name2: None } )
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
def test_article_lists(webdriver, flask_app, dbconn): """Test showing articles that belong to a publication.""" # initialize init_tests(webdriver, flask_app, dbconn, fixtures="publications.json") def check_articles(results, expected): for pub_name, article_title in expected.items(): pub_sr = find_search_result(pub_name, results) articles = find_child(".collapsible", pub_sr) if article_title: # check that the article appears in the publication's search result assert find_child(".caption", articles).text == "Articles:" articles = find_children("li", articles) assert len(articles) == 1 assert articles[0].text == article_title # check that the "edit publication" dialog is correct select_sr_menu_option(pub_sr, "edit") dlg = find_child(".MuiDialog-root") articles = find_children(".articles li", dlg) assert len(articles) == 1 assert articles[0].text == article_title find_child("button.cancel", dlg).click() else: # check that the publication has no associated articles assert articles is None # check that the "edit publication" dialog is correct select_sr_menu_option(pub_sr, "edit") dlg = find_child(".MuiDialog-root") articles = find_children(".articles", dlg) assert len(articles) == 0 find_child("button.cancel", dlg).click() # check that the publications have no articles associated with them results = do_search(SEARCH_ALL_PUBLICATIONS) pub_name1, pub_name2 = "ASL Journal (1)", "MMP News" check_articles(results, {pub_name1: None, pub_name2: None}) # create an article that has no parent publication create_article({"title": "no parent"}) check_articles(results, {pub_name1: None, pub_name2: None}) # create an article that has a parent publication article_title = "test article" create_article({"title": article_title, "publication": pub_name1}) check_articles(results, {pub_name1: article_title, pub_name2: None}) # move the article to another publication article_sr = find_search_result(article_title) edit_article(article_sr, {"publication": pub_name2}) check_articles(None, {pub_name1: None, pub_name2: article_title}) # change the article to have no parent publication edit_article(article_sr, {"publication": "(none)"}) check_articles(None, {pub_name1: None, pub_name2: None}) # move the article back into a publication edit_article(article_sr, {"publication": pub_name1}) check_articles(None, {pub_name1: article_title, pub_name2: None}) # delete the article select_sr_menu_option(article_sr, "delete") check_ask_dialog(("Delete this article?", article_title), "ok") check_articles(None, {pub_name1: None, pub_name2: None})
def test_db_report(webdriver, flask_app, dbconn): """Test the database report.""" # initialize init_tests(webdriver, flask_app, dbconn, fixtures="db-report.json") # check the initial report row_counts, links, dupe_images, image_sizes = _get_db_report() assert row_counts == { "publishers": 2, "publications": 3, "articles": 5, "authors": 3, "scenarios": 2 } assert links == { "publishers": [2, []], "publications": [2, []], "articles": [2, []], } assert dupe_images == [] assert image_sizes == {} # add some images do_search(SEARCH_ALL) publ_sr = find_search_result("Avalon Hill", wait=2) fname = os.path.join(os.path.split(__file__)[0], "fixtures/images/1.gif") edit_publisher(publ_sr, {"image": fname}) results = get_search_results() pub_sr = find_search_result("ASL Journal (1)", results) fname = os.path.join(os.path.split(__file__)[0], "fixtures/images/2.gif") edit_publication(pub_sr, {"image": fname}) article_sr = find_search_result("ASLJ article 1", results) fname = os.path.join(os.path.split(__file__)[0], "fixtures/images/3.gif") edit_article(article_sr, {"image": fname}) article_sr = find_search_result("ASLJ article 2", results) fname = os.path.join(os.path.split(__file__)[0], "fixtures/images/3.gif") edit_article(article_sr, {"image": fname}) # check the updated report row_counts, _, dupe_images, image_sizes = _get_db_report() assert row_counts == { "publishers": 2, "publisher_images": 1, "publications": 3, "publication_images": 1, "articles": 5, "article_images": 2, "authors": 3, "scenarios": 2 } assert dupe_images == [[ "f0457ea742376e76ff276ce62c7a8540", "/images/article/100", ("ASLJ article 1", "/article/100"), ("ASLJ article 2", "/article/101"), ]] assert image_sizes == { "publishers": [ ("Avalon Hill", "/publisher/1", "/images/publisher/1"), ], "publications": [ ("ASL Journal (1)", "/publication/10", "/images/publication/10"), ], "articles": [ ("ASLJ article 1", "/article/100", "/images/article/100"), ("ASLJ article 2", "/article/101", "/images/article/101"), ] } # delete all the publishers (and associated objects), then check the updated report do_search(SEARCH_ALL) publ_sr = find_search_result("Avalon Hill", wait=2) select_sr_menu_option(publ_sr, "delete") check_ask_dialog("Delete this publisher?", "ok") results = get_search_results() publ_sr = find_search_result("Multiman Publishing", results) select_sr_menu_option(publ_sr, "delete") check_ask_dialog("Delete this publisher?", "ok") row_counts, links, dupe_images, image_sizes = _get_db_report() assert row_counts == { "publishers": 0, "publications": 0, "articles": 0, "authors": 3, "scenarios": 2 } assert links == { "publishers": [0, []], "publications": [0, []], "articles": [0, []], } assert dupe_images == [] assert image_sizes == {}