This is a Tic-Tac-Toe API built using Flask for the backend and SQLite for the database. The API allows users to register, log in, create a new game, update the game's move data, and declare a winner.
- Features
- Tech Stack
- Installation
- Running the Application
- Running the test suite
- API Endpoints
- Takehome prompt
- User Registration and Authentication
- Create Games
- Stores the moves in the game
- Declare a winner
- Track wins per user
- Backend: Flask
- Database: SQLite
- Testing tool: pytest
This project uses venv
- Python 3.8+
- SQLite
-
Clone the repository:
-
Create a virtual environment and activate it:
python -m venv venv . .venv/bin/activate
-
Install dependencies:
python -m pip install -r requirements.txt
-
Spin up a SQLite DB based on the preconfigured schema:
python -m flask init-db
- Start the Flask server:
python -m flask run
- Run the pytest test suite using this command:
Note: if you have trouble with this command, make sure you've activated venv
python -m pytest
- URL:
/ping
- Method:
GET
- Request Body: {}
- Response Status & Body:
200
on success{ "message": "pong!" }
- URL:
/auth/register
- Method:
POST
- Request Body:
{ "username": "your_username", "password": "your_password" }
- Response Status & Body:
201 Created
on success{ "message": "success message", "user": { "id": "user_id", "username": "your_username", "wins": "number of wins for the user. should be 0 when you register" }
400 Bad Request
if username already exists or fields are missing{ "message": "error message" }
- URL:
/auth/login
- Method:
POST
- Request Body:
{ "username": "your_username", "password": "your_password" }
- Response Status & Body:
200 OK
on success{ "status": "success status", "token": "JWT needed for future requests. 30 min expiration", "user": { "id": "your user id", "username": "your username", "wins": "user's number of wins" } }
401 Unauthorized
if credentials are incorrect{ "status": "error status" }
- URL:
/game
- Method:
POST
- Request Header:
{ "Authorization": "JWT issued from login" }
- Request Body:
{ }
- Response:
200 OK
withgame_id
- URL:
/game/move
- Method:
POST
- Request Header:
{ "Authorization": "JWT issued from login" }
- Request Body:
{ "game_id": "game_id", "move": "location of the move on the board (int 0-8)" }
- Response Status & Body:
200 OK
on success400 Bad Request
if the request content is invalid, the game has a winner already, or the move is invalid
{ "game_id": "game_id", "board": "game_id", "winner": "returns the winning user X/O or None if there is no winner" }
Currently, the API has no backend tests and your task is to write tests in Pytest for code coverage.
Files have been added to the ./tests/
directory where you can write tests. Here are the requirements:
- We are asking you to write both unit tests and integration/functional/API tests. Show us that you can do both!
- You must use Pytest. We use that framework here at Wisp.
- You may make updates to the
conftest.py
file, write your own test helpers, or add additional dependencies (e.g., Factory Boy). - In general, try to avoid refactoring any of the API code except in cases where it makes testing the code easier.
- Limit yourself to 2 hours of work. That means you should prioritize key features that should have test coverage! Don't worry too much about getting to 100% coverage. We care more about the quality of your work than your quantity.
Please submit your test code as a Pull Request.
- Within the PR, please include:
- Any decisions you made and your reasoning. Examples:
- Refactored the "Make Move" endpoint because...
- Added a new dependency because...
- Any test cases you couldn't get to, but would like to in the future.
- Any decisions you made and your reasoning. Examples:
Once you open your PR, reach back out to the hiring manager for review.
We’ll review your code submission for the following:
- Functionality: Do the tests cover relevant functional areas, are they are flaky, and are they performant.
- Test find-ability, organization and maintainability.
- General coding practices including naming, code structure, and readability.