Skip to content

Bumblebee-JennyXu#27

Open
jennylearncoding wants to merge 4 commits intoAda-C23:mainfrom
jennylearncoding:main
Open

Bumblebee-JennyXu#27
jennylearncoding wants to merge 4 commits intoAda-C23:mainfrom
jennylearncoding:main

Conversation

@jennylearncoding
Copy link

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.

Your implementation looks good overall! Please review my comments, and let me know if you have any questions.

db.session.add(new_task)
db.session.commit()

Choose a reason for hiding this comment

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

🔎 When adding files, be sure to check whether any unintentional changes were added.


# Assert
assert response.status_code == 404
assert response_body == {"message": "Task id 1 is not found."}

Choose a reason for hiding this comment

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

Checking for the "not found" message is the main behavior we want to verify. If we were particularly paranoid, we might also check that no record was surreptitiously added to the database. This is less of a concern for the other "not found" tests, since they wouldn't involve any logic that could conceivably add a new record, but since PUT replaces data, it could be the case that an implementer might have added logic to create the record if it were missing. That is, they could treat a PUT to a nonexistent record as a request to create that particular record.

Again, that's not a requirement, but it is something to keep in mind.


# Assert
assert response.status_code == 404
assert response_body == {"message": "Task id 1 is not found."}

Choose a reason for hiding this comment

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

Checking for the "not found" message is again the main behavior we want to verify. And even though this technically changes data, I'd be less likely to check that a record had been added as a result. Unlike the PUT request, which should include all necessary data to make a Task, this endpoint really doesn't have enough information, so it would have been very difficult to assume the endpoint should create the requested Task.

Comment on lines +84 to +92
response = client.put("/goals/1", json={
"title": "Updated Goal Title",})

assert response.status_code == 204

query = db.select(Goal).where(Goal.id == 1)
goal = db.session.scalar(query)

assert goal.title == "Updated Goal Title"

Choose a reason for hiding this comment

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

👍 Comparing this test with the Task update test gives us an idea of what we should verify here. After performing the PUT, we need to confirm both the response (204 No Content) and check that the change has actually occurred in the database.

# Assert
assert response.status_code == 404
assert response_body == {"message": "Goal id 1 is not found."}
assert db.session.scalars(db.select(Goal)).all() == []

Choose a reason for hiding this comment

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

🔎 It would be particularly surprising for the attempt to delete an unknown Goal to result in a Goal record being added to the database. So there's no need to confirm that the database is still empty.


goals_bp = Blueprint("goals_bp", __name__, url_prefix = "/goals")

@goals_bp.get("")

Choose a reason for hiding this comment

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

👍 Your Goal CRUD routes are consistent with your Task CRUD routes. Check the Task feedback for anything that could apply here.

Comment on lines +22 to +23
if self.goal:
task_dict["goal_id"] = self.goal_id

Choose a reason for hiding this comment

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

👍 Nice logic to add the goal data to the task dictionary only when it's present.

Comment on lines +80 to +84
goal.tasks.clear()

for task_id in task_ids:
task = validate_model(Task, task_id)
task.goal_id = goal.id

Choose a reason for hiding this comment

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

Since we need to validate each Task id anyway, if we stored the resulting tasks in a list, the replacement of the tasks for the goal could be accomplished using the tasks property as

    goal.tasks = tasks

which avoids the need to manually clear the goal association from the existing tasks.

@goals_bp.get("/<goal_id>/tasks")
def get_tasks_by_goal(goal_id):
goal = validate_model(Goal, goal_id)
response = {"id": goal.id, "title": goal.title, "tasks": [task.to_dict() for task in goal.tasks]}

Choose a reason for hiding this comment

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

Notice that the id and title keys here are the same as for a regular Goal GET, for which we wrote the to_dict helper. Here, we could use our to_dict to get the regular result dictionary, and then add in the tasks key with the loaded task data.

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.

👍 Thanks for the update!

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