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

Tigers - Paje B #128

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

Tigers - Paje B #128

wants to merge 4 commits into from

Conversation

Paje-Bishop
Copy link

No description provided.

Copy link

@chimerror chimerror left a comment

Choose a reason for hiding this comment

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

Good Work!

While I made a few comments about some relatively minor repetition, naming, and style issues, this code correctly implements the specification, is cleanly written, and is very readable. And thus good enough for Green!

"id": self.task_id,
"title": self.title,
"description": self.description,
"is_complete": bool(self.completed_at),

Choose a reason for hiding this comment

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

I like this use of bool here. There's a few different ways to convert completed_at but this one is probably the most succinct. Not that succinctness is always a virtue, especially when it impacts readability (which it does not in your case). But here it's nice.

Comment on lines +12 to +27
def format_task(self):
return {
"id": self.task_id,
"title": self.title,
"description": self.description,
"is_complete": bool(self.completed_at),
}

def format_task_goal(self):
return {
"id": self.task_id,
"goal_id": self.goal_id,
"title": self.title,
"description": self.description,
"is_complete": bool(self.completed_at),
}

Choose a reason for hiding this comment

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

But this repetition between format_task_goal and format_task is not as nice. Rather than having two methods, keep in mind that keys (and their values) can be added to Python dictionaries after initialization. So you can do the adding of the "goal_id" key in an if block:

    def format_task(self):
        task_dict = {
            "id": self.task_id,
            "title": self.title,
            "description": self.description,
            "is_complete": bool(self.completed_at),
        }

        if self.goal_id:
            task_dict["goal_id"] = self.goal_id

        return task_dict

and avoid the repetition.

Comment on lines +10 to +18
PATH = "https://slack.com/api/chat.postMessage"
parameters = {"channel": "task-notifications", "text": message}

requests.post(
PATH,
params=parameters,
headers={"Authorization": os.environ.get("SLACKBOT_API_KEY")},
)

Choose a reason for hiding this comment

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

Nice helper function!

Comment on lines +61 to +62
return {"details": "Invalid data"}, 400

Choose a reason for hiding this comment

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

Good job using get here so you don't get the KeyError if you had used the indexing brackets (request_body["title"], for example).

Comment on lines +105 to +107
{"details": f'Task {task_id} "{task.title}" successfully deleted'}
)

Choose a reason for hiding this comment

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

Not really a need for make_response here as we're not doing something like changing what the status code is. So we can just return this dictionary you've created as you do on line 95 above.

Choose a reason for hiding this comment

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

I see a few other places where this is true, but I'll just point it out this once and not repeat myself.

Comment on lines +120 to +125
"id": task.task_id,
"title": task.title,
"description": task.description,
"is_complete": (bool(task.completed_at)),
}

Choose a reason for hiding this comment

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

I had a comment pointing out that format_task could have been used here, and while that's true, this could have been a downside to my suggestion that you combine format_task_goal when the Task returned contains a "goal_id" key (and thus possibly fail a test not expecting that key).

This could justify a separate format_task_goal... However, in most cases, we would still expect the "goal_id" key to be returned when doing this update. It's not so much that we have a reason to not show that key as part of the task, it's more that we didn't have that key during the earlier waves, but now we do.

Either way, I still think the cleanest way I would implement is still handling in my suggested format_task, as well as using it as a helper method here. In that way, format_task is defining what format we always return a task in, and that stays the same across endpoints.

Choose a reason for hiding this comment

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

The use of format_task also applies to update_task_as_incomplete down below.

goal.title = request_body["title"]
db.session.commit()

return make_response({"goal": {"id": goal.goal_id, "title": goal.title}})

Choose a reason for hiding this comment

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

Like my comment on missed format_task opportunities, format_goal could have been used here.

Choose a reason for hiding this comment

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

And other places, but I'll not repeat myself.

@@ -2,7 +2,7 @@
import pytest


@pytest.mark.skip(reason="No way to test this feature yet")
#@pytest.mark.skip(reason="No way to test this feature yet")

Choose a reason for hiding this comment

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

Minor style preference: Just delete these unneeded decorators rather than commenting them out. They are mainly there as scaffolding code, and now that the code works, we can remove them.

Comment on lines 87 to +111
def test_update_goal(client, one_goal):
raise Exception("Complete test")
# Act
# ---- Complete Act Here ----
response = client.put("/goals/1", json={
"title": "Updating my goals"
})

response_body = response.get_json()

# Assert
# ---- Complete Assertions Here ----
# assertion 1 goes here
assert response.status_code == 200
# assertion 2 goes here
assert "goal" in response_body
# assertion 3 goes here
assert response_body == {
"goal": {
"id": 1,
"title": "Updating my goals",
}
}
# ---- Complete Assertions Here ----
goal = Goal.query.get(1)
assert goal.title == "Updating my goals"

Choose a reason for hiding this comment

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

Good test design!

Comment on lines +147 to +150
response_body = response.get_json()
assert response.status_code == 404

raise Exception("Complete test with assertion about response body")
# *****************************************************************
# **Complete test with assertion about response body***************
# *****************************************************************
assert response_body == {"error": "Item #1 cannot be found"}
assert Goal.query.all() == []

Choose a reason for hiding this comment

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

This is also good test design, especially checking the DB and not just response.

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