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

Accelerate - Janice Lichtman #7

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Accelerate - Janice Lichtman #7

wants to merge 13 commits into from

Conversation

J-C-L
Copy link

@J-C-L J-C-L commented Jun 15, 2021

No description provided.

Copy link

@anselrognlie anselrognlie left a comment

Choose a reason for hiding this comment

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

Great job!

The provided tests and your additional tests are all passing. You did a really nice job refactoring the routes and helpers, and the code is very readable throughout.

You've done a great job of starting to address some of the repetitiveness of CRUD code with your helpers and json serialization code. There are a couple places where we can make even more progress, especially around error handling/validation. Making use of exceptions or decorators could lead to an even more streamlined implementation!

It's great to see the thought you put into the optional features you added.

Nice work!

def create_app(test_config=None):
app = Flask(__name__)
app.url_map.strict_slashes = False

Choose a reason for hiding this comment

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

👍

Nice way to set this across all your routes!

Comment on lines +33 to +34
import app.routes.task_routes as task_routes
import app.routes.goal_routes as goal_routes

Choose a reason for hiding this comment

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

The as should only be required if we need to rename the module to something else (like to create an alias). We should be able to do either

    import app.routes.task_routes
    import app.routes.goal_routes

or

    from app.routes import task_routes
    from app.routes import goal_routes

# This fixture creates 2 tasks with
# the same title
@pytest.fixture
def duplicate_title_tasks(app):

Choose a reason for hiding this comment

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

👍

Nice custom fixture to use for testing that your title filtering can properly return multiple results!

@@ -3,4 +3,12 @@


class Goal(db.Model):
goal_id = db.Column(db.Integer, primary_key=True)
id = db.Column(db.Integer, primary_key=True)

Choose a reason for hiding this comment

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

👍

I fully support this renaming!

title = db.Column(db.String)
tasks = db.relationship('Task', backref='goal', lazy=True)

def to_json(self):

Choose a reason for hiding this comment

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

Great decision to bring this helper into the model!

search_title_query = request.args.get("search_title")
if sort_query:
if sort_query == "asc":
tasks = Task.query.order_by(Task.title).all()

Choose a reason for hiding this comment

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

Rather than calling SqlAlchemy stuff directly from the routes, one thing we can consider is to make class helper methods to represent the operations we expect to perform. This forms a more self-documenting interface about what operations we expect to perform. This also follows the Law of Demeter.

We could make helper equivalents of things like get, order_by, filter_by, and all. Really, any of the query methods.

@@ -0,0 +1,91 @@
from app import db

Choose a reason for hiding this comment

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

👍

This all looks good, but consider how the feedback I provided on Task could apply here as well.

from app.models.task import Task
import datetime

def test_create_task_with_valid_datetime_string(client):

Choose a reason for hiding this comment

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

👍

Nice coverage for the date format tests

assert response.status_code == 400
assert response_text == "ASC is not a valid sort parameter. Please use sort=asc or sort=desc."

def test_task_to_json_no_goal(one_task):

Choose a reason for hiding this comment

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

👍

Nice unit tests for your task serialization code.

assert task_json["is_complete"] == task.is_complete()
assert task_json.get("goal_id") == task.goal_id

def test_get_tasks_search_by_title_that_exists(client, three_tasks):

Choose a reason for hiding this comment

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

👍

Nice test coverage for title filtering

Comment on lines +82 to +85
task = Task.query.get(id)
goal_response.tasks.append(task)

db.session.add(goal_response)

Choose a reason for hiding this comment

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

Since goal_response came from the DB already, we don't need to add it into the session. We should also be sure to validate the lookup of the individual tasks. What if one of them couldn't be found?

Also, what would happen if the goal previously had some tasks set. Do we want to add the new tasks to the existing tasks? Do we want to replace them and sever any prior task → goal relationships? What behavior is implemented here?

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