Our task list API should be able to work with an entity called Task
.
Tasks are entities that describe a task a user wants to complete. They contain a:
- title to name the task
- description to hold details about the task
- an optional datetime that the task is completed on
Our goal for this wave is to be able to create, read, update, and delete different tasks.
There should be a Task
model that lives in app/models/task.py
.
Tasks should contain these attributes. Feel free to change the name of the task_id
column if you would like. The tests require the remaining columns to be named exactly as title
, description
, and completed_at
.
task_id
: a primary key for each tasktitle
: text to name the taskdescription
: text to describe the taskcompleted_at
: a datetime that has the date that a task is completed on. Can be nullable, and contain a null value. A task with anull
value forcompleted_at
has not been completed.
- SQLAlchemy's column type for text is
db.String
. The column type for datetime isdb.DateTime
. - SQLAlchemy supports nullable columns with specific syntax.
- Don't forget to run:
flask db init
once during setupflask db migrate
every time there's a change in models, in order to generate migrationsflask db upgrade
to run all generated migrations
- We can assume that the value of each task's
completed_at
attribute will beNone
, until wave 3. (Read below for examples) - We can assume that the API will designate
is_complete
asfalse
, until wave 3. (Read below for examples)
The following are required routes for wave 1. Feel free to implement the routes in any order within this wave.
- Pay attention to the exact shape of the expected JSON. Double-check nested data structures and the names of the keys for any mispellings.
- That said, remember that dictionaries do not have an implied order. This is still true in JSON with objects. When you make Postman requests, the order of the key/value pairings within the response JSON object does not need to match the order specified in this document. (The term "object" in JSON is analagous to "dictionary" in Python.)
- Use the tests in
tests/test_wave_01.py
to guide your implementation. - You may feel that there are missing tests and missing edge cases considered in this wave. This is intentional.
- You have fulfilled wave 1 requirements if all of the wave 1 tests pass.
- You are free to add additional features, as long as the wave 1 tests still pass. However, we recommend that you consider the future waves, first.
- Some tests use a fixture named
one_task
that is defined intests/conftest.py
. This fixture saves a specific task to the test database.
As a client, I want to be able to make a POST
request to /tasks
with the following HTTP request body
{
"title": "A Brand New Task",
"description": "Test Description",
"completed_at": null
}
and get this response:
201 CREATED
{
"task": {
"id": 1,
"title": "A Brand New Task",
"description": "Test Description",
"is_complete": false
}
}
so that I know I successfully created a Task that is saved in the database.
As a client, I want to be able to make a GET
request to /tasks
when there is at least one saved task and get this response:
200 OK
[
{
"id": 1,
"title": "Example Task Title 1",
"description": "Example Task Description 1",
"is_complete": false
},
{
"id": 2,
"title": "Example Task Title 2",
"description": "Example Task Description 2",
"is_complete": false
}
]
As a client, I want to be able to make a GET
request to /tasks
when there are zero saved tasks and get this response:
200 OK
[]
As a client, I want to be able to make a GET
request to /tasks/1
when there is at least one saved task and get this response:
200 OK
{
"task": {
"id": 1,
"title": "Example Task Title 1",
"description": "Example Task Description 1",
"is_complete": false
}
}
As a client, I want to be able to make a GET
request to /tasks/1
when there are no matching tasks and get this response:
404 Not Found
No response body.
As a client, I want to be able to make a PUT
request to /tasks/1
when there is at least one saved task with this request body:
{
"title": "Updated Task Title",
"description": "Updated Test Description",
"completed_at": null
}
and get this response:
200 OK
{
"task": {
"id": 1,
"title": "Updated Task Title",
"description": "Updated Test Description",
"is_complete": false
}
}
As a client, I want to be able to make a PUT
request to /tasks/1
when there are no matching tasks with this request body:
{
"title": "Updated Task Title",
"description": "Updated Test Description",
"completed_at": null
}
and get this response:
404 Not Found
No response body
As a client, I want to be able to make a DELETE
request to /tasks/1
when there is at least one saved task and get this response:
200 OK
{
"details": "Task 1 \"Go on my daily walk 🏞\" successfully deleted"
}
As a client, I want to be able to make a DELETE
request to /tasks/1
when there are no matching tasks and get this response:
404 Not Found
No response body.
As a client, I want to be able to make a POST
request to /tasks
with the following HTTP request body
{
"description": "Test Description",
"completed_at": null
}
and get this response:
400 Bad Request
{
"details": "Invalid data"
}
so that I know I did not create a Task that is saved in the database.
If the HTTP request is missing description
, we should also get this response:
400 Bad Request
{
"details": "Invalid data"
}
If the HTTP request is missing completed_at
, we should also get this response:
400 Bad Request
{
"details": "Invalid data"
}