-
Notifications
You must be signed in to change notification settings - Fork 18
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
Feat/scaffold UI test user on demand #2286
Merged
Merged
Changes from 12 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
9b3c5d1
initial commit
andrewleith 7352db5
feat: create and destroy test users on demand
andrewleith de7d5b9
Merge branch 'main' into feat/scaffold-ui-test-user-on-demand
andrewleith 5f5eb9f
chore(config): add some hardcoded UUIDs for cypress related items
andrewleith cfe8719
feat(cypress api): update create_test_user route:
andrewleith 00dc686
feat(cypress api): update cleanup_stale_users route:
andrewleith 6d1acba
chore: formatting
andrewleith 7704b89
chore(format): formatting files I haven't touched :(
andrewleith 0dd0721
chore: formatting
andrewleith 7417e0e
chore: formatting
andrewleith 9bb10ae
chore: formatting
andrewleith 33e2ca7
chore: update docstrings; enhance exception handling
andrewleith 490e666
fix(cypress api): use service id from config
andrewleith ae3be90
chore: add more cypress values to config
andrewleith 17b4a2b
feat(cypress api): dont pass password around since its already a secr…
andrewleith 425e156
feat(cypress data): migration to create cypress service, permissions,…
andrewleith 3be6c6c
Merge branch 'main' into feat/scaffold-ui-test-user-on-demand
andrewleith f4c313a
feat(create_test_user): update delete logic to be more complete; para…
andrewleith 74dd85d
chore: formatting
andrewleith 0b1584a
Merge branch 'main' into feat/scaffold-ui-test-user-on-demand
andrewleith 9608861
chore: remove unreachable code
andrewleith b3f9d5d
task: add config values for testing
andrewleith 09d027c
feat(auth): add separate auth mechanism for ui testing
andrewleith dd93318
chore: add tests
andrewleith e4ed50a
chore: formatting
andrewleith b38cb7a
chore: fix tests
andrewleith 0afb435
chore: remove unused code
andrewleith 4e4027d
Merge branch 'main' into feat/scaffold-ui-test-user-on-demand
andrewleith 350649c
chore: fix migration due to incoming migrations
andrewleith 1cdb7ea
Merge branch 'main' into feat/scaffold-ui-test-user-on-demand
andrewleith 0a31d2c
chore: re-number migrations due to merge
andrewleith c0f4456
task: pass new secret `CYPRESS_USER_PW_SECRET` into CI
andrewleith 6518911
chore: add some debugging to the workflow
andrewleith 56f8cb2
task: debug workflow
andrewleith 911b957
fix(workflow): put the env statement in the right place
andrewleith bbfdb84
chore: fix workflow
andrewleith baeb377
chore: add __init__.py in `tests/app/cypress` folder to make tests work
andrewleith 7dc741f
Plz [review] !
andrewleith 1bf62de
chore: fix incorrect descriptions
andrewleith 18458ad
fix: correct typo in function name
andrewleith a566d52
fix: use cds domain instead of gov.uk
andrewleith d3d877c
chore: fix failing test
andrewleith 15d248a
Merge branch 'main' into feat/scaffold-ui-test-user-on-demand
andrewleith File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
""" | ||
This module will be used by the cypress tests to create users on the fly whenever a test suite is run, and clean | ||
them up periodically to keep the data footprint small. | ||
""" | ||
|
||
import hashlib | ||
import uuid | ||
from datetime import datetime, timedelta | ||
|
||
from flask import Blueprint, current_app, jsonify, request | ||
|
||
from app import db | ||
from app.dao.services_dao import dao_add_user_to_service | ||
from app.dao.templates_dao import dao_update_template | ||
from app.dao.users_dao import save_model_user | ||
from app.errors import register_errors | ||
from app.models import LoginEvent, Permission, Service, ServiceUser, Template, TemplateHistory, TemplateRedacted, User, VerifyCode | ||
|
||
cypress_blueprint = Blueprint("cypress", __name__) | ||
register_errors(cypress_blueprint) | ||
|
||
|
||
@cypress_blueprint.route("/create_user/<email_name>", methods=["POST"]) | ||
def create_test_user(email_name): | ||
""" | ||
Create a test user for Notify UI testing. | ||
|
||
Args: | ||
email_name (str): The name to be used in the email address of the test user. | ||
|
||
Returns: | ||
dict: A dictionary containing the serialized user information. | ||
""" | ||
if current_app.config["NOTIFY_ENVIRONMENT"] == "production": | ||
return jsonify(message="Forbidden"), 403 | ||
|
||
try: | ||
data = request.get_json() | ||
password = data.get("password") | ||
except Exception: | ||
return jsonify(message="Invalid JSON"), 400 | ||
|
||
try: | ||
# Create the user | ||
data = { | ||
"id": uuid.uuid4(), | ||
"name": "Notify UI testing account", | ||
"email_address": f"notify-ui-tests+{email_name}@cds-snc.ca", | ||
"password": hashlib.sha256((password + current_app.config["DANGEROUS_SALT"]).encode("utf-8")).hexdigest(), | ||
|
||
"mobile_number": "9025555555", | ||
"state": "active", | ||
"blocked": False, | ||
} | ||
|
||
user = User(**data) | ||
save_model_user(user) | ||
|
||
# add user to cypress service w/ full permissions | ||
service = Service.query.filter_by(id="5c8a0501-2aa8-433a-ba51-cefb8063ab93").first() | ||
permissions = [] | ||
for p in [ | ||
"manage_users", | ||
"manage_templates", | ||
"manage_settings", | ||
"send_texts", | ||
"send_emails", | ||
"send_letters", | ||
"manage_api_keys", | ||
"view_activity", | ||
]: | ||
permissions.append(Permission(permission=p)) | ||
|
||
dao_add_user_to_service(service, user, permissions=permissions) | ||
|
||
except Exception: | ||
return jsonify(message="Error creating user"), 400 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider logging the exception details here to help with debugging. |
||
|
||
return jsonify(user.serialize()), 201 | ||
|
||
|
||
def _destroy_test_user(email_name): | ||
CYPRESS_TEST_USER_ID = current_app.config["CYPRESS_TEST_USER_ID"] | ||
|
||
user = User.query.filter_by(email_address=f"notify-ui-tests+{email_name}@cds-snc.ca").first() | ||
|
||
if not user: | ||
return | ||
|
||
try: | ||
# update the created_by field for each template to use id CYPRESS_TEST_USER_ID | ||
templates = Template.query.filter_by(created_by=user).all() | ||
for template in templates: | ||
template.created_by_id = CYPRESS_TEST_USER_ID | ||
dao_update_template(template) | ||
|
||
# update the created_by field for each template to use id CYPRESS_TEST_USER_ID | ||
history_templates = TemplateHistory.query.filter_by(created_by=user).all() | ||
for templateh in history_templates: | ||
templateh.created_by_id = CYPRESS_TEST_USER_ID | ||
db.session.add(templateh) | ||
|
||
# update the created_by field for each template_redacted to use id CYPRESS_TEST_USER_ID | ||
redacted_templates = TemplateRedacted.query.filter_by(updated_by=user).all() | ||
for templater in redacted_templates: | ||
templater.updated_by_id = CYPRESS_TEST_USER_ID | ||
db.session.add(templater) | ||
|
||
# Update services create by this user to use CYPRESS_TEST_USER_ID | ||
services = Service.query.filter_by(created_by=user).all() | ||
for service in services: | ||
service.created_by_id = CYPRESS_TEST_USER_ID | ||
db.session.add(service) | ||
|
||
# remove all the login events for this user | ||
LoginEvent.query.filter_by(user=user).delete() | ||
|
||
# remove all permissions for this user | ||
Permission.query.filter_by(user=user).delete() | ||
|
||
# remove user_to_service entries | ||
ServiceUser.query.filter_by(user_id=user.id).delete() | ||
|
||
# remove verify codes | ||
VerifyCode.query.filter_by(user=user).delete() | ||
|
||
# remove the user | ||
User.query.filter_by(email_address=f"notify-ui-tests+{email_name}@cds-snc.ca").delete() | ||
|
||
except Exception: | ||
db.session.rollback() | ||
|
||
|
||
@cypress_blueprint.route("/cleanup", methods=["GET"]) | ||
def cleanup_stale_users(): | ||
""" | ||
Endpoint for cleaning up stale users. This endpoint will only be used internally by the Cypress tests. | ||
|
||
This endpoint is responsible for removing stale testing users from the database. | ||
Stale users are identified as users whose email addresses match the pattern "%notify-ui-tests+%@cds-snc.ca%" and whose creation time is older than three hours ago. | ||
|
||
If this is accessed from production, it will return a 403 Forbidden response. | ||
|
||
Returns: | ||
A JSON response with a success message if the cleanup is successful, or an error message if an exception occurs during the cleanup process. | ||
""" | ||
if current_app.config["NOTIFY_ENVIRONMENT"] == "production": | ||
return jsonify(message="Forbidden"), 403 | ||
|
||
try: | ||
three_hours_ago = datetime.utcnow() - timedelta(hours=3) | ||
users = User.query.filter( | ||
User.email_address.like("%notify-ui-tests+%@cds-snc.ca%"), User.created_at < three_hours_ago | ||
).all() | ||
|
||
# loop through users and call destroy_user on each one | ||
for user in users: | ||
user_email = user.email_address.split("+")[1].split("@")[0] | ||
_destroy_test_user(user_email) | ||
|
||
db.session.commit() | ||
except Exception: | ||
return jsonify(message="Error cleaning up"), 500 | ||
|
||
return jsonify(message="Zeds dead, baby"), 201 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love this addition + the Cypress auth, I'll be sure to move the utility method from that PR in here too!