From 49c608186c204c8274a70309ddced47a660eedea Mon Sep 17 00:00:00 2001 From: Taka Date: Wed, 17 Nov 2021 18:29:33 +1100 Subject: [PATCH] Allow publisher articles to have a publication date. --- ...7_allow_articles_to_have_a_publication_.py | 28 ++++++++ asl_articles/articles.py | 7 +- asl_articles/models.py | 1 + .../fixtures/publisher-article-dates.json | 11 +++ asl_articles/tests/test_articles.py | 72 +++++++++++++++++-- web/src/ArticleSearchResult.js | 15 +++- web/src/ArticleSearchResult2.js | 64 ++++++++++------- 7 files changed, 164 insertions(+), 34 deletions(-) create mode 100644 alembic/versions/702eeb219037_allow_articles_to_have_a_publication_.py create mode 100644 asl_articles/tests/fixtures/publisher-article-dates.json diff --git a/alembic/versions/702eeb219037_allow_articles_to_have_a_publication_.py b/alembic/versions/702eeb219037_allow_articles_to_have_a_publication_.py new file mode 100644 index 0000000..d42cd21 --- /dev/null +++ b/alembic/versions/702eeb219037_allow_articles_to_have_a_publication_.py @@ -0,0 +1,28 @@ +"""Allow articles to have a publication date. + +Revision ID: 702eeb219037 +Revises: a33edb7272a2 +Create Date: 2021-11-16 20:41:37.454305 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '702eeb219037' +down_revision = 'a33edb7272a2' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('article', sa.Column('article_date', sa.String(length=100), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('article', 'article_date') + # ### end Alembic commands ### diff --git a/asl_articles/articles.py b/asl_articles/articles.py index 619bdeb..e95a524 100644 --- a/asl_articles/articles.py +++ b/asl_articles/articles.py @@ -19,7 +19,7 @@ from asl_articles.utils import get_request_args, clean_request_args, clean_tags, _logger = logging.getLogger( "db" ) -_FIELD_NAMES = [ "*article_title", "article_subtitle", "article_snippet", "article_pageno", +_FIELD_NAMES = [ "*article_title", "article_subtitle", "article_date", "article_snippet", "article_pageno", "article_url", "article_tags", "pub_id", "publ_id" ] @@ -51,6 +51,7 @@ def get_article_vals( article, deep ): "article_subtitle": article.article_subtitle, "article_image_id": article.article_id if article.article_image else None, "article_authors": [ get_author_vals( a.parent_author ) for a in authors ], + "article_date": article.article_date, "article_snippet": article.article_snippet, "article_pageno": article.article_pageno, "article_url": article.article_url, @@ -94,6 +95,8 @@ def create_article(): # create the new article vals[ "time_created" ] = datetime.datetime.now() + if not vals.get( "publ_id" ): + vals.pop( "article_date", None ) article = Article( **vals ) db.session.add( article ) db.session.flush() @@ -223,6 +226,8 @@ def update_article(): _set_seqno( article, vals["pub_id"] ) vals[ "time_updated" ] = datetime.datetime.now() apply_attrs( article, vals ) + if not vals.get( "publ_id" ): + article.article_date = None _save_authors( article ) _save_scenarios( article ) _save_image( article ) diff --git a/asl_articles/models.py b/asl_articles/models.py index 2268725..41d196f 100644 --- a/asl_articles/models.py +++ b/asl_articles/models.py @@ -63,6 +63,7 @@ class Article( db.Model ): article_id = db.Column( db.Integer, primary_key=True ) article_title = db.Column( db.String(200), nullable=False ) article_subtitle = db.Column( db.String(200) ) + article_date = db.Column( db.String(100) ) # nb: this is just a display string article_snippet = db.Column( db.String(5000) ) article_seqno = db.Column( db.Integer ) article_pageno = db.Column( db.String(20) ) diff --git a/asl_articles/tests/fixtures/publisher-article-dates.json b/asl_articles/tests/fixtures/publisher-article-dates.json new file mode 100644 index 0000000..5853f80 --- /dev/null +++ b/asl_articles/tests/fixtures/publisher-article-dates.json @@ -0,0 +1,11 @@ +{ + +"publisher": [ + { "publ_id": 1, "publ_name": "Avalon Hill" } +], + +"publication": [ + { "pub_id": 20, "pub_name": "ASL Journal", "publ_id": 1 } +] + +} diff --git a/asl_articles/tests/test_articles.py b/asl_articles/tests/test_articles.py index 07e57ab..0957980 100644 --- a/asl_articles/tests/test_articles.py +++ b/asl_articles/tests/test_articles.py @@ -484,6 +484,61 @@ def test_publisher_articles( webdriver, flask_app, dbconn ): #pylint: disable=to # --------------------------------------------------------------------- +def test_publisher_article_dates( webdriver, flask_app, dbconn ): + """Test "published" dates for publisher articles.""" + + # initialize + init_tests( webdriver, flask_app, dbconn, disable_constraints=False, fixtures="publisher-article-dates.json" ) + + # initialize + article_title, article_date = "test article", "1st January, 2000" + article_sr = None + + def check_article_date( has_date ): + # check the article's publication date + def do_check(): + elem = find_child( ".article_date", article_sr ) + article_id = article_sr.get_attribute( "testing--article_id" ) + row = get_article_row( dbconn, article_id, ["article_date"] ) + if has_date: + return elem.text == article_date and row[0] == article_date + else: + return not elem and not row[0] + wait_for( 2, do_check ) + + # create an article associated with a publication + create_article( { + "title": article_title, + "publication": "ASL Journal", + "snippet": "This is a test article.", + "pageno": 42, + "authors": [ "+Joe Blow" ] + } ) + article_sr = wait_for( 2, lambda: find_search_result( article_title ) ) + check_article_date( False ) + + # change the article to be associated with a publisher + edit_article( article_sr, { + "publisher": "Avalon Hill" + }, expected_constraints = [ + "The article date was not specified." + ], accept_constraints=True ) + check_article_date( False ) + + # give the article a published date + edit_article( article_sr, { + "article_date": article_date + } ) + check_article_date( True ) + + # change the article back to the publication + edit_article( article_sr, { + "publication": "ASL Journal" + } ) + check_article_date( False ) + +# --------------------------------------------------------------------- + def test_unicode( webdriver, flask_app, dbconn ): """Test Unicode content.""" @@ -636,7 +691,10 @@ def test_article_ratings( webdriver, flask_app, dbconn ): # --------------------------------------------------------------------- -def create_article( vals, toast_type="info", expected_error=None, expected_constraints=None, dlg=None ): +def create_article( vals, toast_type="info", + expected_error=None, expected_constraints=None, accept_constraints=False, + dlg=None +): """Create a new article.""" # initialize @@ -656,7 +714,9 @@ def create_article( vals, toast_type="info", expected_error=None, expected_const return dlg # nb: the dialog is left on-screen elif expected_constraints: # we were expecting constraint warnings, confirm them - check_constraint_warnings( "Do you want to create this article?", expected_constraints, "cancel" ) + check_constraint_warnings( "Do you want to create this article?", + expected_constraints, "ok" if accept_constraints else "cancel" + ) return dlg # nb: the dialog is left on-screen else: # we were expecting the create to work, confirm this @@ -668,7 +728,9 @@ def create_article( vals, toast_type="info", expected_error=None, expected_const # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def edit_article( sr, vals, toast_type="info", expected_error=None, expected_constraints=None ): #pylint: disable=too-many-branches +def edit_article( sr, vals, toast_type="info", + expected_error=None, expected_constraints=None, accept_constraints=False +): #pylint: disable=too-many-branches """Edit a article's details.""" # initialize @@ -690,7 +752,9 @@ def edit_article( sr, vals, toast_type="info", expected_error=None, expected_con return dlg # nb: the dialog is left on-screen elif expected_constraints: # we were expecting constraint warnings, confirm them - check_constraint_warnings( "Do you want to update this article?", expected_constraints, "cancel" ) + check_constraint_warnings( "Do you want to update this article?", + expected_constraints, "ok" if accept_constraints else "cancel" + ) return dlg # nb: the dialog is left on-screen else: # we were expecting the update to work, confirm this diff --git a/web/src/ArticleSearchResult.js b/web/src/ArticleSearchResult.js index 3693479..e073fe3 100644 --- a/web/src/ArticleSearchResult.js +++ b/web/src/ArticleSearchResult.js @@ -140,9 +140,18 @@ export class ArticleSearchResult extends React.Component
- { authors.length > 0 &&
By {makeCommaList(authors)}
} - { scenarios.length > 0 &&
Scenarios: {makeCommaList(scenarios)}
} - { tags.length > 0 &&
Tags: {tags}
} + { authors.length > 0 && +
By {makeCommaList(authors)}
+ } + { this.props.data.article_date && +
{this.props.data.article_date}
+ } + { scenarios.length > 0 && +
Scenarios: {makeCommaList(scenarios)}
+ } + { tags.length > 0 && +
Tags: {tags}
+ }
) ; } diff --git a/web/src/ArticleSearchResult2.js b/web/src/ArticleSearchResult2.js index f2b77fa..0c4c8d8 100644 --- a/web/src/ArticleSearchResult2.js +++ b/web/src/ArticleSearchResult2.js @@ -22,16 +22,19 @@ export class ArticleSearchResult2 let parentMode = vals.publ_id ? "publisher" : "publication" ; let publicationParentRowRef = null ; let publisherParentRowRef = null ; + let articleDateRef = null ; function onPublicationParent() { parentMode = "publication" ; publicationParentRowRef.style.display = "flex" ; publisherParentRowRef.style.display = "none" ; + articleDateRef.style.display = "none" ; refs.pub_id.focus() ; } function onPublisherParent() { parentMode = "publisher" ; publicationParentRowRef.style.display = "none" ; publisherParentRowRef.style.display = "flex" ; + articleDateRef.style.display = "flex" ; refs.publ_id.focus() ; } @@ -154,6 +157,7 @@ export class ArticleSearchResult2 // prepare the form content /* eslint-disable jsx-a11y/img-redundant-alt */ const content =
+
-
- refs.article_title=r} /> -
-
- refs.article_subtitle=r} /> -
-
publicationParentRowRef=r} > - - refs.article_pageno=r} title="Page number." /> -
-
publisherParentRowRef=r} > - - refs.article_title=r} /> +
+
+ refs.article_subtitle=r} /> +
+
publicationParentRowRef=r} > + + refs.article_pageno=r} title="Page number." /> +
+
publisherParentRowRef=r} > + + refs.article_date=r} /> +
+