Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Origin/backend/enforce story translation stage logic #99

Merged

Conversation

jennifer-lu
Copy link
Member

Notion ticket link

Enforce story translation stage logic

Implementation description

  • Raises an exception if a user is not authorized to leave comments or update story translation contents
  • The above is based on the story translation stage and whether the user is a translator or a reviewer
  • For comments (see create_comment in comment_service.py): if the stage is TRANSLATE, translators can leave comments and reviewers cannot; if the stage is REVIEW, reviewers can leave comments and translators cannot; if the stage is PUBLISH, no comments can be left
  • For contents (see update_story_translation_contents in story_service.py): contents can be changed only if the stage is TRANSLATE

Steps to test

  1. Setup Altair as translator (e.g. carlsagan)
  2. Run the following, no exception should come up
    mutation { createComment (commentData: { storyTranslationContentId: 55, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  3. Run the following, exception should be 'You are not authorized to leave comments on this story.'
    mutation { createComment (commentData: { storyTranslationContentId: 25, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  4. Run the following, no exception should come up
    mutation { updateStoryTranslationContents (storyTranslationContents: { id: 55, translationContent: "hi", }) { story { id translationContent } } }
  5. Setup Altair as reviewer (e.g. dwightdeisenhower)
  6. Run the following, exception should be 'Comments cannot be left by reviewers while the story is being translated.'
    mutation { createComment (commentData: { storyTranslationContentId: 55, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  7. Run the following, exception should be 'You are not authorized to leave comments on this story.'
    mutation { createComment (commentData: { storyTranslationContentId: 25, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  8. In the mysql database, update story translation with id=6 to state 'REVIEW' update story_translations set stage = 'REVIEW' where story_id = 6;
  9. Setup Altair as translator
  10. Run the following, exception should be 'Comments cannot be left by translators while the story is being reviewed.'
    mutation { createComment (commentData: { storyTranslationContentId: 55, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  11. Run the following, exception should be 'You are not authorized to leave comments on this story.'
    mutation { createComment (commentData: { storyTranslationContentId: 25, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  12. Run the following, exception should be 'Story translation contents cannot be changed while the story is being reviewed.'
    mutation { updateStoryTranslationContents (storyTranslationContents: { id: 55, translationContent: "hi", }) { story { id translationContent } } }
  13. Setup Altair as reviewer
  14. Run the following, no exception should come up
    mutation { createComment (commentData: { storyTranslationContentId: 55, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  15. Run the following, exception should be 'You are not authorized to leave comments on this story.'
    mutation { createComment (commentData: { storyTranslationContentId: 25, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  16. Setup Altair as translator
  17. Run the following, exception should be 'Comments cannot be left after the story has been published.'
    mutation { createComment (commentData: { storyTranslationContentId: 55, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  18. Run the following, exception should be 'You are not authorized to leave comments on this story.'
    mutation { createComment (commentData: { storyTranslationContentId: 25, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  19. Run the following, exception should be 'Story translation contents cannot be changed after the story has been published.'
    mutation { updateStoryTranslationContents (storyTranslationContents: { id: 55, translationContent: "hi", }) { story { id translationContent } } }
  20. Setup Altair as reviewer
  21. Run the following, exception should be 'Comments cannot be left after the story has been published.'
    mutation { createComment (commentData: { storyTranslationContentId: 55, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }
  22. Run the following, exception should be 'You are not authorized to leave comments on this story.'
    mutation { createComment (commentData: { storyTranslationContentId: 25, content: "", }) { ok comment { id storyTranslationContentId userId commentIndex time resolved content } } }

What should reviewers focus on?

  • Logic is correct and works as expected (see last two points of implementation)
  • Exception messages are correct

Checklist

  • My PR name is descriptive and in imperative tense
  • My commit messages are descriptive and in imperative tense. My commits are atomic and trivial commits are squashed or fixup'd into non-trivial commits
  • For backend changes, I have run the appropriate linters: docker exec -it planet-read_py-backend_1 /bin/bash -c "black . && isort --profile black ." and I have generated new migrations: flask db migrate -m "<your message>"
  • I have requested a review from the PL, as well as other devs who have background knowledge on this PR or who will be building on top of this PR

Copy link
Contributor

@gaoxk gaoxk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! everything worked for me while testing. Rebase onto main branch, work on the feedback, and let me know when it's ready for re-review!

Comment.story_translation_content_id
== comment["story_translation_content_id"]
user_id = get_user_id_from_request()
new_comment = Comment(**comment)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20-37 should be wrapped in a try statement (see how it was previously wrapped)

story_translation_translator_id = story_translation.translator_id
story_translation_reviewer_id = story_translation.reviewer_id

is_translator = user_id == str(story_translation_translator_id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than wrap str() around story_translation_translator_id and story_translation_reviewer_id, can you wrap get_user_id_from_request() with int() on line 20 and leave a comment to remove it when get_user_id_from_request() is updated to return ints? example comment

new_comment = Comment(**comment)
new_comment.user_id = user_id

story_translation_content = StoryTranslationContent.query.filter_by(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! this works, but getting story_translation_content and getting story_translation on line 29 are two database queries. Can you try using only 1 database query? You'll need to join StoryTranslation and StoryTranslationContent together.

self.logger.error(
"Failed to update story translation content. Reason = {reason}".format(
reason=(reason if reason else str(error))
story_translation_content = StoryTranslationContent.query.filter_by(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto comment about wrapping this in a try statement. You should always wrap any database interactions with try statements, because they could always fall through if the database has issues!

seed_db.sh Outdated
@@ -1,45 +1,45 @@
# ***** How to Use: *****
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a result of the linter?

@jennifer-lu jennifer-lu force-pushed the origin/backend/enforce-story-translation-stage-logic branch from 96d0a66 to 1dec0b1 Compare September 22, 2021 02:57
Copy link
Contributor

@gaoxk gaoxk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! feel free to merge after addressing nits. let me know if you have any questions about the nit :shipit:
(((A relevant stackoverflow thread you might find interesting)))


max = (
db.session.query(func.max(Comment.comment_index))
story_translation = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice query! nit: I believe db.session.query(StoryTranslation).join(.... could be rewritten as StoryTranslation.query.join(.... I think the latter option is more clear

db.session.bulk_update_mappings(
StoryTranslationContent, story_translation_contents
story_translation = (
db.session.query(StoryTranslation)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto comment

story_translation = StoryTranslationContent.query.filter_by(
id=story_translation_content.id
).first()
story_translation = StoryTranslationContent.query.filter_by(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto comment

Copy link
Member Author

@jennifer-lu jennifer-lu Sep 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I leave this one because it's in the deprecated function?

@jennifer-lu jennifer-lu merged commit 0dc9b88 into main Sep 23, 2021
@jennifer-lu jennifer-lu deleted the origin/backend/enforce-story-translation-stage-logic branch September 23, 2021 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants