def test_timestamps(webdriver, flask_app, dbconn): """Test setting of timestamps.""" # initialize init_tests(webdriver, flask_app, dbconn) # create an article create_article({"title": "My Article"}) results = get_search_results() assert len(results) == 1 article_sr = results[0] article_id = article_sr.get_attribute("testing--article_id") # check its timestamps row = get_article_row(dbconn, article_id, ["time_created", "time_updated"]) assert row[0] assert row[1] is None # update the article edit_article(article_sr, {"title": "My Article (updated)"}) # check its timestamps row2 = get_article_row(dbconn, article_id, ["time_created", "time_updated"]) assert row2[0] == row[0] assert row2[1] > row2[0]
def test_timestamps(webdriver, flask_app, dbconn): """Test setting of timestamps.""" # initialize init_tests(webdriver, flask_app, dbconn) # create a publication create_publication({"name": "My Publication"}) results = get_search_results() assert len(results) == 1 pub_sr = results[0] pub_id = pub_sr.get_attribute("testing--pub_id") # check its timestamps row = get_publication_row(dbconn, pub_id, ["time_created", "time_updated"]) assert row[0] assert row[1] is None # update the publication edit_publication(pub_sr, {"name": "My Publication (updated)"}) # check its timestamps row2 = get_publication_row(dbconn, pub_id, ["time_created", "time_updated"]) assert row2[0] == row[0] assert row2[1] > row2[0]
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 click_on_author( sr, expected_author, expected_sr ): authors = find_children( ".authors .author", sr ) assert len(authors) == 1 assert authors[0].text == expected_author authors[0].click() wait_for( 2, lambda: get_search_result_names() == expected_sr ) return get_search_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 test_clean_html( webdriver, flask_app, dbconn ): """Test cleaning HTML content.""" # initialize init_tests( webdriver, flask_app, dbconn ) replace = [ "[\u00ab\u00bb\u201c\u201d\u201e\u201f foo\u2014bar \u2018\u2019\u201a\u201b\u2039\u203a]", "[\"\"\"\"\"\" foo - bar '''''']" ] # create a publisher with HTML content create_publisher( { "name": "name: <span onclick='boo!'> <b>bold</b> <xxx>xxx</xxx> <i>italic</i> {}".format( replace[0] ), "description": "bad stuff here: <script>HCF</script> {}".format( replace[0] ) }, toast_type="warning" ) # check that the HTML was cleaned sr = check_search_result( None, _check_sr, [ "name: bold xxx italic {}".format( replace[1] ), "bad stuff here: {}".format( replace[1] ), None ] ) assert find_child( ".name", sr ).get_attribute( "innerHTML" ) \ == "name: <span> <b>bold</b> xxx <i>italic</i> {}</span>".format( replace[1] ) assert check_toast( "warning", "Some values had HTML cleaned up.", contains=True ) # update the publisher with new HTML content edit_publisher( sr, { "name": "<div onclick='...'>updated</div>" }, toast_type="warning" ) results = get_search_results() assert len(results) == 1 wait_for( 2, lambda: find_child( ".name", sr ).text == "updated" ) assert check_toast( "warning", "Some values had HTML cleaned up.", contains=True )
def check_results(expected_url, expected_title, expected_sr): wait_for(2, lambda: check_title(expected_title)) assert get_url() == "{}/{}".format( url_stem, expected_url) if expected_url else url_stem results = get_search_results() assert get_search_result_names(results) == expected_sr return results
def test_parent_publisher(webdriver, flask_app, dbconn): """Test setting an article's parent publication.""" # initialize init_tests(webdriver, flask_app, dbconn, fixtures="parents.json") def check_result(sr, expected_parent): #pylint: disable=too-many-return-statements # check that the parent publication was updated in the UI elem = find_child(".header .publication", sr) if expected_parent: if elem.text != "{}".format(expected_parent[1]): return None else: if elem is not None: return None # check that the parent publication was updated in the database 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)) if expected_parent: if article["pub_id"] != expected_parent[0]: return None else: if article["pub_id"] is not None: return None # check that the parent publication was updated in the UI results = do_search('"My Article"') assert len(results) == 1 sr = results[0] elem = find_child(".header .publication", sr) if expected_parent: if elem.text != "{}".format(expected_parent[1]): return None else: if elem is not None: return None return sr # create an article with no parent publication create_article({"title": "My Article"}) results = get_search_results() assert len(results) == 1 sr = wait_for(2, lambda: check_result(results[0], None)) # change the article to have a publication edit_article(sr, {"publication": "ASL Journal"}) sr = wait_for(2, lambda: check_result(sr, (1, "ASL Journal"))) # change the article back to having no publication edit_article(sr, {"publication": "(none)"}) sr = wait_for(2, lambda: check_result(sr, None))
def test_parent_publisher(webdriver, flask_app, dbconn): """Test setting a publication's parent publisher.""" # initialize init_tests(webdriver, flask_app, dbconn, fixtures="parents.json") def check_result(sr, expected_parent): #pylint: disable=too-many-return-statements # check that the parent publisher was updated in the UI elem = find_child(".header .publisher", sr) if expected_parent: if elem.text != "{}".format(expected_parent[1]): return None else: if elem is not None: return None # check that the parent publisher was updated in the database 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)) if expected_parent: if pub["publ_id"] != expected_parent[0]: return None else: if pub["publ_id"] is not None: return None # check that the parent publisher was updated in the UI results = do_search('"MMP News"') assert len(results) == 1 sr = results[0] elem = find_child(".header .publisher", sr) if expected_parent: if elem.text != "{}".format(expected_parent[1]): return None else: if elem is not None: return None return sr # create a publication with no parent publisher create_publication({"name": "MMP News"}) results = get_search_results() assert len(results) == 1 sr = wait_for(2, lambda: check_result(results[0], None)) # change the publication to have a publisher edit_publication(sr, {"publisher": "Multiman Publishing"}) sr = wait_for(2, lambda: check_result(sr, (1, "Multiman Publishing"))) # change the publication back to having no publisher edit_publication(sr, {"publisher": "(none)"}) sr = wait_for(2, lambda: check_result(sr, None))
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 do_test( create, edit, refresh ): # create a new object webdriver.refresh() create() results = get_search_results() assert len(results) == 1 sr = results[0] # add images to the object # NOTE: We're testing that images in an object already on-screen is updated correctly. fname = os.path.join( os.path.split(__file__)[0], "fixtures/images/1.gif" ) description = 'foo <img src="/images/app.png" style="height:2em;" class="preview"> bar' edit( sr, fname, description ) _check_previewable_images( sr ) # refresh the object # NOTE: We're testing that images in an object loaded afresh is set up correctly. webdriver.refresh() wait_for( 2, lambda: find_child( "#search-form" ) ) results = refresh() assert len(results) == 1 _check_previewable_images( results[0] )
def test_images(webdriver, flask_app, dbconn): #pylint: disable=too-many-statements """Test article images.""" # initialize init_tests(webdriver, flask_app, dbconn, max_image_upload_size=2 * 1024) article_sr = article_id = None def check_image(expected): # check the image in the article's search result def check_sr_image(): img = find_child("img.image", article_sr) if expected: expected_url = flask_app.url_for("get_image", image_type="article", image_id=article_id) image_url = img.get_attribute("src").split("?")[0] return image_url == expected_url else: return not img wait_for(2, check_sr_image) # check the image in the article's config select_sr_menu_option(article_sr, "edit") dlg = wait_for_elem(2, "#article-form") if expected: # make sure there is an image img = find_child(".row.image img.image", dlg) image_url = img.get_attribute("src") assert "/images/article/{}".format(article_id) in image_url # make sure the "remove image" icon is visible btn = find_child(".row.image .remove-image", dlg) assert btn.is_displayed() # make sure the article's image is correct resp = urllib.request.urlopen(image_url).read() assert resp == open(expected, "rb").read() else: # make sure there is no image img = find_child(".row.image img.image", dlg) assert img.get_attribute("src").endswith("/images/placeholder.png") # make sure the "remove image" icon is hidden btn = find_child(".row.image .remove-image", dlg) assert not btn.is_displayed() # make sure the article's image is not available url = flask_app.url_for("get_image", image_type="article", image_id=article_id) try: resp = urllib.request.urlopen(url) assert False, "Should never get here!" except urllib.error.HTTPError as ex: assert ex.code == 404 find_child(".cancel", dlg).click() # create an article with no image create_article({"title": "Test Article"}) results = get_search_results() assert len(results) == 1 article_sr = results[0] article_id = article_sr.get_attribute("testing--article_id") check_image(None) # add an image to the article fname = os.path.join(os.path.split(__file__)[0], "fixtures/images/1.gif") edit_article(article_sr, {"image": fname}) check_image(fname) # change the article's image fname = os.path.join(os.path.split(__file__)[0], "fixtures/images/2.gif") edit_article(article_sr, {"image": fname}) check_image(fname) # remove the article's image edit_article(article_sr, {"image": None}) check_image(None) # try to upload an image that's too large select_sr_menu_option(article_sr, "edit") dlg = wait_for_elem(2, "#article-form") data = base64.b64encode(5000 * b" ") data = "{}|{}".format("too-big.png", data.decode("ascii")) send_upload_data(data, lambda: find_child(".row.image img.image", dlg).click()) check_error_msg("The file must be no more than 2 KB in size.")
def click_on_tag( tag, expected ): tag.click() wait_for( 2, lambda: get_search_result_names() == expected ) return get_search_results()
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 == {}