forked from AdaGold/back-end-inspiration-board
-
Notifications
You must be signed in to change notification settings - Fork 36
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
Kunzite - Gabby Y, Amber S, Areeg J, Angelica Y #13
Open
gnyoung
wants to merge
30
commits into
Ada-C19:main
Choose a base branch
from
gnyoung:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
def6a09
Complete backend setup
gnyoung b7bd2bb
Replaced routes.py with boards.py and cards.py
arejib 890c33a
Created and registered Blueprints for boards and cards
arejib 8f97d3b
added seed board and seed card without linking just created the files
langyee1 001bd88
Merge branch 'main' of https://github.com/gnyoung/back-end-inspiratio…
langyee1 1a08c46
created boards validation and enter beginning tests
Maashad 88ad783
Add relationship between Board and Card models
gnyoung d3c2f44
add class methods
Maashad f94ffb2
created working endpoint for post board
Maashad 314be03
Add POST and GET routes for Card
gnyoung d28acbd
working get_one_board route
Maashad 38ac449
Add class decorator to Board method
gnyoung 82f08a7
working get_one_board route
Maashad c4497a7
working route for delete_one_board
Maashad a7c7736
create endpoint for read_all_boards
Maashad 76f4401
HOT FIX updated create_app to include test_config positional argument
Maashad 20b356f
delete routes ok
langyee1 ea5d1e3
Merge branch 'main' of https://github.com/gnyoung/back-end-inspiratio…
langyee1 801351e
Added PATCH request to cards_routes
arejib 7196b45
Refactor and write tests for Card routes
gnyoung a4b8f2a
Added fixture to conftest.py and corresponding test for PATCH route
arejib 55cac89
connected seed card with seed commit
langyee1 6593ff1
Cleaned up formatting
arejib 04a089c
Refactor cards endpoint
gnyoung 26b2e95
Merge branch 'main' of github.com:gnyoung/back-end-inspiration-board
gnyoung 75c5215
delete all boards route added
Maashad 8b66e6a
added delete all cards route
Maashad 9e232e2
changed naming in cards delete and patch
langyee1 1905b10
missing tests for board added
langyee1 5e35bf2
Connect to render db
gnyoung File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
from flask import Blueprint, request, jsonify, make_response, abort | ||
from app import db | ||
from app.models.board import Board | ||
from app.models.card import Card | ||
from sqlalchemy.types import DateTime | ||
from sqlalchemy.sql.functions import now | ||
from app.routes_helpers import validate_model | ||
import requests, json | ||
import os | ||
|
||
boards_bp = Blueprint("boards", __name__, url_prefix="/boards") | ||
|
||
@boards_bp.route("", methods=["POST"]) | ||
def create_board(): | ||
request_body = request.get_json() | ||
|
||
is_valid_board_title = "title" in request_body | ||
is_valid_board_owner = "owner" in request_body | ||
if not is_valid_board_title: | ||
abort(make_response({"details": "Please include title"}, 400)) | ||
if not is_valid_board_owner: | ||
abort(make_response({"details": "Please include owner"}, 400)) | ||
|
||
new_board = Board.board_from_dict(request_body) | ||
|
||
db.session.add(new_board) | ||
db.session.commit() | ||
|
||
return make_response(jsonify(f"{new_board} successfully created!"), 201) | ||
|
||
@boards_bp.route("", methods=["GET"]) | ||
def read_all_boards(): | ||
boards = Board.query.all() | ||
boards_response = [board.board_to_dict() for board in boards] | ||
|
||
return jsonify(boards_response) | ||
|
||
@boards_bp.route("/<board_id>", methods=["GET"]) | ||
def read_one_board(board_id): | ||
board = validate_model(Board, board_id) | ||
|
||
response_body = { | ||
"board": board.board_to_dict() | ||
} | ||
|
||
return jsonify(response_body) | ||
|
||
@boards_bp.route("/<board_id>", methods=["DELETE"]) | ||
def delete_one_board(board_id): | ||
board = validate_model(Board, board_id) | ||
|
||
response_body = { | ||
"details": f"Board {board.id} \"{board.title}\" successfully deleted" | ||
} | ||
|
||
db.session.delete(board) | ||
db.session.commit() | ||
|
||
return jsonify(response_body) | ||
|
||
@boards_bp.route("", methods=["DELETE"]) | ||
def delete_all_boards(): | ||
boards = Board.query.all() | ||
for board in boards: | ||
db.session.delete(board) | ||
db.session.commit() | ||
|
||
return make_response(jsonify("All boards successfully deleted!"), 200) | ||
|
||
@boards_bp.route("/<board_id>/cards", methods=["POST"]) | ||
def create_one_card_for_board(board_id): | ||
board = validate_model(Board, board_id) | ||
|
||
request_body = request.get_json() | ||
|
||
card = Card.query.get(request_body["id"]) | ||
board.cards.append(card) | ||
|
||
db.session.add(board) | ||
db.session.commit() | ||
|
||
return make_response({ | ||
"id": board.id, | ||
"card_id": request_body["id"]}, 201) | ||
|
||
@boards_bp.route("/<board_id>/cards", methods=["GET"]) | ||
def get_cards_for_one_board(board_id): | ||
board = validate_model(Board, board_id) | ||
|
||
cards = board.cards | ||
|
||
cards_list = [card.card_to_dict() for card in cards] | ||
|
||
return make_response({ | ||
"id": board.id, | ||
"title": board.title, | ||
"cards": cards_list}, 200) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from flask import Blueprint, request, jsonify, make_response | ||
from app import db | ||
from app.models.card import Card | ||
from app.routes_helpers import validate_model | ||
|
||
cards_bp = Blueprint("cards", __name__, url_prefix="/cards") | ||
|
||
@cards_bp.route("", methods=["POST"]) | ||
def create_card(): | ||
request_body = request.get_json() | ||
|
||
new_card = Card.card_from_dict(request_body) | ||
|
||
db.session.add(new_card) | ||
db.session.commit() | ||
|
||
new_card_id = new_card.id | ||
|
||
return make_response(jsonify({"id": new_card_id, "message": "Card successfully created"}), 201) | ||
|
||
@cards_bp.route("", methods=["GET"]) | ||
def read_all_cards(): | ||
cards = Card.query.all() | ||
|
||
cards_response = [card.card_to_dict() for card in cards] | ||
|
||
return make_response(jsonify(cards_response), 200) | ||
|
||
@cards_bp.route("/<card_id>", methods=["DELETE"]) | ||
def delete_one_card(card_id): | ||
card = validate_model(Card, card_id) | ||
|
||
response_body = { | ||
"details": f"Card {card.id} \"{card.message}\" successfully deleted" | ||
} | ||
|
||
db.session.delete(card) | ||
db.session.commit() | ||
|
||
return jsonify(response_body) | ||
|
||
@cards_bp.route("", methods=["DELETE"]) | ||
def delete_all_cards(): | ||
cards = Card.query.all() | ||
for card in cards: | ||
db.session.delete(card) | ||
db.session.commit() | ||
|
||
return make_response(jsonify("All cards successfully deleted!"), 200) | ||
|
||
@cards_bp.route("/<card_id>", methods=["PATCH"]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this isn't a general purpose PATCH method, consider adding an additional qualifier to the end (like the mark (in)complete endpoints in task list) @cards_bp.route("/<card_id>/like", methods=["PATCH"]) |
||
def increase_like_count(card_id): | ||
card = validate_model(Card, card_id) | ||
|
||
card.likes_count += 1 | ||
|
||
db.session.commit() | ||
return make_response(card.card_to_dict(), 200) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,22 @@ | ||
from app import db | ||
|
||
class Board(db.Model): | ||
id = db.Column(db.Integer, primary_key=True, autoincrement=True) | ||
title = db.Column(db.String) | ||
owner = db.Column(db.String) | ||
cards = db.relationship("Card", back_populates="board") | ||
|
||
@classmethod | ||
def board_from_dict(cls, board_data): | ||
new_board = Board(title=board_data["title"], owner=board_data["owner"]) | ||
|
||
return new_board | ||
|
||
def board_to_dict(self): | ||
board_as_dict = {} | ||
board_as_dict["id"] = self.id | ||
board_as_dict["title"] = self.title | ||
board_as_dict["owner"] = self.owner | ||
|
||
return board_as_dict | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,23 @@ | ||
from app import db | ||
|
||
|
||
class Card(db.Model): | ||
id = db.Column(db.Integer, primary_key=True, autoincrement=True) | ||
message = db.Column(db.String) | ||
likes_count = db.Column(db.Integer) | ||
board_id = db.Column(db.Integer, db.ForeignKey("board.id")) | ||
board = db.relationship("Board", back_populates="cards") | ||
|
||
def card_to_dict(self): | ||
card_as_dict = {} | ||
card_as_dict["id"] = self.id | ||
card_as_dict["message"] = self.message | ||
card_as_dict["likes_count"] = self.likes_count | ||
|
||
return card_as_dict | ||
|
||
@classmethod | ||
def card_from_dict(cls, card_data): | ||
new_card = cls(message=card_data["message"], likes_count=card_data.get("likes_count", 0)) | ||
|
||
return new_card |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from flask import make_response, abort | ||
|
||
def validate_model(cls, model_id): | ||
try: | ||
model_id = int(model_id) | ||
except: | ||
abort(make_response({"message": f"{cls.__name__} {model_id} invalid"}, 400)) | ||
|
||
model = cls.query.get(model_id) | ||
|
||
if not model: | ||
abort(make_response({"message": f"{cls.__name__} {model_id} not found"}, 404)) | ||
|
||
return model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Generic single-database configuration. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀 We shouldn't be able to create a Card that doesn't belong to a Board. Consider using the nested POST under Board to create a new Card which belongs to that Board, rather than associating an existing Card to an existing Board. That approach was slightly peculiar to Task List, which allowed Tasks to exist that weren't part of an overarching Goal.