Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ celerybeat.pid

# Environments
.env
.flaskend
.venv
env/
venv/
Expand Down
2 changes: 2 additions & 0 deletions .planetsenv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FLASK_ENV=development
FLASK_DEBUG=1
27 changes: 27 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,34 @@
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
import sqlalchemy

from dotenv import load_dotenv
import os
load_dotenv()

db = SQLAlchemy()
migrate = Migrate()

def create_app(test_config=None):
app = Flask(__name__)

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
if not test_config:
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get(
"SQLALCHEMY_DATABASE_URI")
else:
app.config["TESTING"] = True
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get(
"SQLALCHEMY_TEST_DATABASE_URI")
db.init_app(app)
migrate.init_app(app, db)

from app.models.planet import Planet

from .planets import planets_bp
app.register_blueprint(planets_bp)


return app
Empty file added app/models/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions app/models/planet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from app import db

class Planet(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String)
color = db.Column(db.String)
description = db.Column(db.String)
107 changes: 107 additions & 0 deletions app/planets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from flask import Blueprint,jsonify,abort,make_response,request
from app import db
from app.models.planet import Planet


if title_query:
title_query = title_query.filter_by(title=title_query)


planets_bp = Blueprint('planets_bp', __name__, url_prefix='/planets')

@planets_bp.route('', methods=['GET'])
def handle_planet():
planet_query = Planet.query


description_query = request.args.get("description")

if description_query:
planet_query = planet_query.filter_by(description=description_query)
else:
planets = Planet.query.all()

color_query = request.args.get("color")
if color_query:
planet_query = planet_query.filter_by(color=color_query)
else:
planets = Planet.query.all()

name_query = request.args.get("name")
if name_query:
planet_query = planet_query.filter_by(name=name_query)

planets = planet_query.all()


planets_response = []
for planet in planets:
planets_response.append({
"id": planet.id,
"name": planet.name,
"color": planet.color,
"description": planet.description
})

if not planets_response:
return make_response(jsonify(f"There are no {planet_query} planets"))
return jsonify(planets_response)

board_response = []
for board in boards:
board_response.append({
"id": planet.id,
"name": planet.name,
"color": planet.color,
"description": planet.description
})

if not planets_response:
return make_response(jsonify(f"There are no {planet_query} planets"))
return jsonify(planets_response)


@planets_bp.route("/<id>", methods=['GET','PUT','DELETE'])

def handle_1_planet(id):
planet = Planet.query.get(id)


if request.method == "GET":
return{
"id": planet.id,
"name": planet.name,
"color": planet.color,
"description": planet.description
}
elif request.method == "PUT":
request_body = request.get_json()

planet.name = request_body["name"]
planet.color = request_body["color"]
planet.description = request_body["description"]


db.session.commit()
return make_response(f"planet color {planet.color} succesfully updated",200)

elif request.method == "DELETE":
db.session.delete(planet)
db.session.commit()

return make_response(f"planet color {planet.color} succesfully deleted", 200)



@board_bp.route(/title, methods=["GET"])
# GET /task/id
def handle_task(title):
# Query our db to grab the task that has the id we want:

task = Task.query.get(title)

if task.goal_id is not None:
return{"task": task.to_dict_in_goal()}
else:
return {"task": task.to_dict()}

2 changes: 2 additions & 0 deletions app/routes.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
from flask import Blueprint



Empty file added app/tests/__init__.py
Empty file.
56 changes: 56 additions & 0 deletions app/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import pytest
from app import create_app
from app import db
#create a new database session after a request as described below.
from flask.signals import request_finished
from app.models.planet import Planet

# Create test versions of our flask app and database
@pytest.fixture
def app():
app = create_app({"TESTING": True})

#will be invoked after any request is completed
@request_finished.connect_via(app)
def expire_session(sender, response, **extra):
db.session.remove()

with app.app_context():
# sets up database
db.create_all()
yield app

with app.app_context():
db.drop_all()


@pytest.fixture
def client(app):
# depends on app that references another fixture
# holds the reference to the test interface
return app.test_client()

@pytest.fixture
def two_saved_planets(app):
# Arrange
blorp = Planet
{
"id": 2,
"name": 'Blorp',
"color": 'Purple',
"description": "Stinky"
}
florpus = Planet
{
"id": 3,
"name": 'Florpus',
"color": 'Red',
"description": "Shy"
}
db.session.add_all([blorp, florpus])
# Alternatively, we could do
# db.session.add(winston)
# db.session.add(winter)
db.session.commit()


80 changes: 80 additions & 0 deletions app/tests/test_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from app.models.planet import Planet

def test_get_all_planets_with_empty_db_return_empty_list(client):

response = client.get('/planets')
response_body = response.get_json()

assert response_body == []
assert response.status_code == 200

def test_get_one_planet(client,two_saved_planets):

response = client.get('/planets/2')
response_body = response.get_json()

planet2 = {
'id':2,
'name': 'Blorp',
'color': 'Purple',
'description': 'Stinky'
}

assert response.status_code == 200
assert response_body == planet2

def test_no_data_return_failure(client):

response = client.get("/planets/1")
response_body = response.get_json()

assert response.status_code == 404

def test_return_array(client):
# Act
response = client.get("/planets")
response_body = response.get_json()

# Assert
assert response.status_code == 200
assert len(response_body) == 1
assert response_body == [
{
"id": 1,
"name": 'Dink',
"color": 'Green',
"description": 'Fluffy'
},
{
"id": 2,
"name": 'Blorp',
"color": 'Purple',
"description": 'Stinky'
},
{
"id": 3,
"name": 'Florpus',
"color": 'Red',
"description": 'Shy'
}
]

def test_request_body_json(client):
# Act
response = client.post("/planets", json={
"name": "Cripper"
})
response_body = response.get_json()

# Assert
assert response.status_code == 201

assert Planet.query.all() == []




# 1. `GET` `/planets/1` returns a response body that matches our fixture
# 1. `GET` `/planets/1` with no data in test database (no fixture) returns a `404`
# 1. `GET` `/planets` with valid test data (fixtures) returns a `200` with an array including appropriate test data
# 1. `POST` `/planets` with a JSON request body returns a `201`
1 change: 1 addition & 0 deletions migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
45 changes: 45 additions & 0 deletions migrations/alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# A generic, single database configuration.

[alembic]
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false


# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
Loading