Skip to content

Creates tests for the store manager api and its endpoints #1

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

Open
wants to merge 111 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
1d9e559
[Chore #161203416] Create the application's project folder
calebrotich Oct 14, 2018
02bdb3b
[Chore #161209925] Add requirements.txt file
calebrotich Oct 15, 2018
28dd336
[Chore #161209988] Setup Application factory to create the application
calebrotich Oct 15, 2018
0864c42
[Chore #161209988] Create a blueprint for version 1 of the application
calebrotich Oct 15, 2018
5a6a25f
[Chore #161216309] Add travis.yml file for Travis CI
calebrotich Oct 15, 2018
0d6d048
[Chore #161209925] Add Continous Integration packages
calebrotich Oct 15, 2018
37f7585
[Chore #161201973] Create test for app creation
calebrotich Oct 15, 2018
0de12a2
[Chore #161209988] Change environment for running the application
calebrotich Oct 15, 2018
106afa8
[Chore #161216309] Rename travis file
calebrotich Oct 15, 2018
0a8647b
[Chore #161209988] Allow instance configurations
calebrotich Oct 15, 2018
866c537
[Chore #161216309] Remove extra spacing in .travis.yml
calebrotich Oct 15, 2018
86bb1e3
[Chore #161203416] Add files for routes and endpoints
calebrotich Oct 15, 2018
869bd5f
[Chore #161203416] Remove unwanted lines in views.py
calebrotich Oct 15, 2018
ec7ae66
[Chore #161216309] Move coveralls command to Script
calebrotich Oct 15, 2018
bcd108c
[Chore #161216309] Add Travis CI badge
calebrotich Oct 15, 2018
55cb477
[Chore #161216309] Change badge to Markdown
calebrotich Oct 15, 2018
fc59405
[Chore #161223919] Edit CI title
calebrotich Oct 15, 2018
63943fa
[Chore #161223919] Add badge for coveralls.io
calebrotich Oct 15, 2018
2189b3c
[Chore #161223919] Organize badges
calebrotich Oct 15, 2018
31d4136
[Chore #161223919] Add code climate badge
calebrotich Oct 15, 2018
9290393
[Chore #161201973] Create a base test file
calebrotich Oct 16, 2018
245e430
[Chore #161201973] Rename test file
calebrotich Oct 16, 2018
225da57
[Chore #161201973] Create test for add (post) new product
calebrotich Oct 16, 2018
c58c433
Merge branch 'develop' of https://github.com/calebrotich10/store-mana…
calebrotich Oct 16, 2018
07b40ca
[Chore #161209988] Update .gitignore file
calebrotich Oct 16, 2018
f8ab017
[Feature #161201833] Create add_new_product endpoint
calebrotich Oct 16, 2018
8db3b43
[Feature #161201833] Create route for POST /products
calebrotich Oct 16, 2018
44a4022
[Chore #161248446] Create a products list
calebrotich Oct 16, 2018
67e6391
[Feature #161201833] Refactor code
calebrotich Oct 16, 2018
b3ed006
[Chore #161201973] Create test for GET all products endpoint
calebrotich Oct 16, 2018
90539e2
[Finishes bug #161254684] Fix class name conflict
calebrotich Oct 16, 2018
f3844fe
[Feature #161201851] Create fetch all products endpoint
calebrotich Oct 16, 2018
955d4c6
[Feature #161201851] Create route for GET /products endpoint
calebrotich Oct 16, 2018
818d5ad
Merge branch 'ch-tests-for-endpoints-161201973' into ft-fetch-all-pro…
calebrotich Oct 16, 2018
549377c
[Chore #161216309] Add repo token to .coveralls.yml
calebrotich Oct 16, 2018
08c3a9d
[Chore #161216309] Change python version
calebrotich Oct 16, 2018
5b4ac1f
[Chore #161209925] Add python-coveralls and gunicorn packages
calebrotich Oct 16, 2018
1cb07a5
[Chore #161216309] Add coveralls command under script in travis file
calebrotich Oct 16, 2018
69fe9e0
[Chore #161216309] Configure code climate
calebrotich Oct 17, 2018
5f6d989
[Chore #161201973] Create test for GET specific product endpoint
calebrotich Oct 17, 2018
9826908
[Chore #161216309] Add repo token to .coveralls.yml
calebrotich Oct 16, 2018
6b4e63f
[Chore #161216309] Change python version
calebrotich Oct 16, 2018
261a32e
[Chore #161209925] Add python-coveralls and gunicorn packages
calebrotich Oct 16, 2018
d71641b
[Chore #161216309] Add coveralls command under script in travis file
calebrotich Oct 16, 2018
b2b58a4
[Chore #161216309] Configure code climate
calebrotich Oct 17, 2018
165140f
[Feature #161201912] Create fetch specific product endpoint
calebrotich Oct 17, 2018
28b83a5
[Feature #161201912] Create route for GET /products/<id> endpoint
calebrotich Oct 17, 2018
bdfcc71
Merge branch 'ft-fetch-specific-order-161201912' of https://github.co…
calebrotich Oct 17, 2018
9585084
[Chore #161201973] Create test for add sale record
calebrotich Oct 17, 2018
e45cd77
[Chore #161248446] Create sale orders list
calebrotich Oct 17, 2018
08799ad
[Feature #161201919] Create POST /saleorder endpoint
calebrotich Oct 17, 2018
bf1e287
[Feature #161201919] Create route for POST /saleorder endpoint
calebrotich Oct 17, 2018
bdb3252
Merge branch 'ft-add-sale-order-161201919' into ch-tests-for-endpoint…
calebrotich Oct 17, 2018
9cd9faf
[Chore #161201973] Create test for GET /saleorder endpoint
calebrotich Oct 18, 2018
46b82bb
[Feature #161201927] Create GET /saleorders endpoint
calebrotich Oct 18, 2018
8153ab6
[Feature #161201927] Create route for GET /saleorder
calebrotich Oct 18, 2018
d464e83
Merge branch 'ch-tests-for-endpoints-161201973' into ft-fetch-sale-or…
calebrotich Oct 18, 2018
af03bff
[Release #161309750] Add gunicorn configuration to Procfile
calebrotich Oct 18, 2018
940d020
[Release #161309750] Change environment setting in run.py
calebrotich Oct 18, 2018
8e3aa6f
[Chore #161201973] Refactor tests to increase test coverage
calebrotich Oct 18, 2018
85181d9
[Chore #161201973] Create test for fetch specific sale order endpoint
calebrotich Oct 19, 2018
5aca05f
[Feature #161337098] Create a GET /saleorder/<sale_order_id> endpoint
calebrotich Oct 19, 2018
95fb8c9
[Feature #161337098] Create a route for GET /saleorder/<sale_order_id>
calebrotich Oct 19, 2018
3fa9bf6
Merge branch 'ch-tests-for-endpoints-161201973' into ft-fetch-specifi…
calebrotich Oct 19, 2018
fcfd6d3
[Chore #161223919] Add endpoints listings
calebrotich Oct 19, 2018
489b914
[Chore #161201973] Create tests for the auth endpoints
calebrotich Oct 20, 2018
370e21e
[Chore #161209988] Create an authentication blueprint
calebrotich Oct 20, 2018
ee9d38c
Merge branch 'develop' of https://github.com/calebrotich10/store-mana…
calebrotich Oct 20, 2018
9bea170
[Chore #161209925] Add authentication packages
calebrotich Oct 20, 2018
3a46358
[Feature #161362891] Add /auth endpoints
calebrotich Oct 20, 2018
f59d144
[Chore #161248446] Create users list
calebrotich Oct 20, 2018
317ba86
[Feature #161362891] Create routes for /auth endpoint
calebrotich Oct 20, 2018
a34dcfd
[Chore #161209925] Remove jwt
calebrotich Oct 20, 2018
1fb3b0c
[Chore #161223919] Add documentation and credits
calebrotich Oct 22, 2018
25fccbc
[Chore #161248446] Create classes for the models
calebrotich Oct 23, 2018
bf7896e
[Chore #161216309] Modify test command at .travis.yml
calebrotich Oct 23, 2018
f115f86
[Chore #161408153] Implement OOP for CRUD actions
calebrotich Oct 23, 2018
15ba00d
[Fixes bug #161408196] Fix auth token decode and encode
calebrotich Oct 23, 2018
c6a0ee0
[Chore #161201973] Refactor tests
calebrotich Oct 23, 2018
2da39e1
[Chore #161223919] Add app testing information
calebrotich Oct 23, 2018
ab06317
[Chore #161414025] Refactor code to meet standards
calebrotich Oct 23, 2018
0f73fd0
Merge branch 'develop' of https://github.com/calebrotich10/store-mana…
calebrotich Oct 23, 2018
7c742a8
[Fixes bug #161415191] Varible ref before assignement
calebrotich Oct 23, 2018
25b10ee
[Chore #161414025] Remove unnecessary code block
calebrotich Oct 23, 2018
9644b84
[Chore #161414025] Strip spaces from request data
calebrotich Oct 23, 2018
e3c8174
[Chore #161414025] Remove unnecessary else block causing inconsistency
calebrotich Oct 23, 2018
0034f3c
Merge branch 'develop' of https://github.com/calebrotich10/store-mana…
calebrotich Oct 23, 2018
9cf2677
Merge branch 'develop' into ft-auth-161362891
calebrotich Oct 23, 2018
97f6a48
[Chore #161414025] Strip spaces around request data
calebrotich Oct 23, 2018
46c3b84
[Chore #161414025] Prevent the response from returning password
calebrotich Oct 23, 2018
f8398e4
[Feature #161362891] Increase token expiry time from 5 to 30 minutes
calebrotich Oct 23, 2018
8abebcb
[Chore #161201912] Return all product details on query
calebrotich Oct 24, 2018
e806de0
[Chore #161414025] Strip spaces from login request data
calebrotich Oct 24, 2018
bbe5603
[Chore #161457608] Create blueprints for version two
calebrotich Oct 25, 2018
ddf0670
[Chore #161462204] Create database configuration file
calebrotich Oct 25, 2018
2bffeec
[Chore #161248446] Model products
calebrotich Oct 25, 2018
284664c
[Chore #161248446] Modify users model to integrate database
calebrotich Oct 25, 2018
91936a9
[Chore #161248446] Modify sale orders model to integrate database
calebrotich Oct 25, 2018
a25059f
[Chore #161491333] Create test for store attendant endpoint
calebrotich Oct 25, 2018
ba68659
[Chore #161491333] Create test for general user endpoint
calebrotich Oct 25, 2018
09527c4
[Chore #161491333] Create test for auth endpoint
calebrotich Oct 25, 2018
74ed66d
[Chore #161491333] Create test to check app working
calebrotich Oct 25, 2018
0a2a6f1
[Chore #161491333] Create tests for admin endpoints
calebrotich Oct 25, 2018
0126a54
Merge branch 'ch-setup-database-161462204' into develop
calebrotich Oct 25, 2018
fc49570
[Chore #161491969] Enable endpoints to connect to database
calebrotich Oct 25, 2018
93051be
[Chore #161491969] Add data validation and routing
calebrotich Oct 25, 2018
051d896
[Chore #161209925] Add psycopg2 package for databases
calebrotich Oct 25, 2018
802b774
[Chore #161216309] Change travis command to cover version 2
calebrotich Oct 25, 2018
49fe876
[Chore #161216309] Add database creation commands
calebrotich Oct 25, 2018
8841717
[Chore #161209988] Remove version 2 of the application from version 1
calebrotich Oct 26, 2018
60b2551
[Chore #161216309] Remove database environment variables from .travis
calebrotich Oct 26, 2018
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ local_settings.py
db.sqlite3

# Flask stuff:
instance/
#instance/
.webassets-cache

# Scrapy stuff:
Expand Down Expand Up @@ -102,3 +102,6 @@ venv.bak/

# mypy
.mypy_cache/

# VS code settings
.vscode/
31 changes: 31 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
env:
global:
- CC_TEST_REPORTER_ID=18007e474cdfcf70da58a682805aff9f88216339b0dce34454dc0bfcc988ea91
- APP_SETTINGS="development"
- SECRET_KEY="mvangiffj38kncliu3yt7gvLWDNTDISFJWrk'\flQHJsdnlQI2ROH"

language: python

# python version
python:
- "3.6"

# command to install dependencies
install:
- pip install -r requirements.txt

before_script:
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
- chmod +x ./cc-test-reporter
- ./cc-test-reporter before-build

# command to run tests
script:
- coverage run --source=app.api.v1 -m pytest app/tests/v1 -v -W error::UserWarning && coverage report

after_script:
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT

# Post coverage results to coverage.io
after_success:
- coveralls
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: gunicorn run:app
84 changes: 84 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,86 @@
# store-manager-api

#### Continous Integration badges
[![Build Status](https://travis-ci.com/calebrotich10/store-manager-api.svg?branch=develop)](https://travis-ci.com/calebrotich10/store-manager-api) [![Coverage Status](https://coveralls.io/repos/github/calebrotich10/store-manager-api/badge.svg?branch=develop)](https://coveralls.io/github/calebrotich10/store-manager-api?branch=develop) [![Maintainability](https://api.codeclimate.com/v1/badges/e87820f417b8d15c3a64/maintainability)](https://codeclimate.com/github/calebrotich10/store-manager-api/maintainability)


Store Manager is a web application that helps store owners manage sales and product inventory records. This application is meant for use in a single store. This repository contains the API endpoints for the application.

#### Endpoints
<table>
<tr>
<th>Http Method</th>
<th>Endpoint</th>
<th>Functionality</th>
</tr>
<tr>
<td>POST</td>
<td>api/v1/auth/signup</td>
<td>Creates a new user account</td>
</tr>
<tr>
<td>POST</td>
<td>api/v1/products</td>
<td>Used by the admin to add a new product</td>
</tr>
<tr>
<td>POST</td>
<td>api/v1/saleorder</td>
<td>Used by the sale attendant to add a new sale order</td>
</tr>
<tr>
<td>GET</td>
<td>api/v1/auth/signin</td>
<td>Authenticates and creates a token for the users</td>
</tr>
<tr>
<td>GET</td>
<td>api/v1/products/&ltproduct_id&gt</td>
<td>Enables a user to fetch a specific product</td>
</tr>
<tr>
<td>GET</td>
<td>api/v1/saleorder/&ltsale_order_id&gt</td>
<td>Enables a user to fetch a specific sale order</td>
</tr>
<tr>
<td>GET</td>
<td>api/v1/products</td>
<td>Enables a user to fetch all products</td>
</tr>
<tr>
<td>GET</td>
<td>api/v1/saleorder</td>
<td>Enables a user to fetch all sale orders</td>
</tr>
</table>

#### Installing the application
1. Open a command terminal in your preferred folder
2. Run command `git clone https://github.com/calebrotich10/store-manager-api.git` to have a copy locally
3. `cd store-manager-api`
4. Create a virtual environment for the application `virtualenv venv`
5. Install dependencies from the `requirements.txt` file `pip3 install -r requirements.txt`
6. Export environment variables to your environment ```export JWT_SECRET_KEY=your-secret-key```, ```export FLASK_APP="run.py"```
6. Run the application using flask command `flask run` or using python3 `python3 run.py`

#### Running tests
Inside the virtual environment created above, run command: `coverage run --source=app.api.v1 -m pytest app/tests/v1 -v -W error::UserWarning && coverage report`

#### Technologies used
1. `JWT` for authentication
2. `pytest` for running tests
3. Python based framework `flask`
4. Flask packages

#### Deployment
[Heroku](https://store-manager-api.herokuapp.com/api/v1/products)

#### Documentation
https://documenter.getpostman.com/view/5265531/RWguxwzy

#### Author
[Caleb Rotich](https://github.com/calebrotich10)

#### Credits
This application was build as part of the Andela NBO 33 challenge
23 changes: 23 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import os

from flask import Flask
from flask_jwt_extended import JWTManager

from instance.config import config

jwt = JWTManager()

def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
app.config['JWT_SECRET_KEY'] = os.getenv('JWT_SECRET_KEY', default='SdaHv342nx!jknr837bjwd?c,lsajjjhw673hdsbgeh')

jwt.init_app(app)

from .api.v1 import endpoint_v1_blueprint as v1_blueprint
app.register_blueprint(v1_blueprint, url_prefix='/api/v1')

from .api.v1 import auth_v1_blueprint as v1_blueprint
app.register_blueprint(v1_blueprint, url_prefix='/api/v1/auth')

return app
Empty file added app/api/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions app/api/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from flask import Blueprint


endpoint_v1_blueprint = Blueprint('endpoint_v1_blueprint', __name__)
auth_v1_blueprint = Blueprint('auth_v1_blueprint', __name__)



from . import views
24 changes: 24 additions & 0 deletions app/api/v1/models/products.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""This module contains the data store

and data logic of the store's products
"""

PRODUCTS = []

class Products():
def __init__(self, product_name, product_price, category):
self.id = len(PRODUCTS) + 1
self.product_name = product_name
self.product_price = product_price
self.category = category

def save(self):
new_product = {
"product_id": self.id,
"product_name": self.product_name,
"product_price": self.product_price,
"category": self.category
}

PRODUCTS.append(new_product)
return new_product
26 changes: 26 additions & 0 deletions app/api/v1/models/sale_orders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""This module contains the data store

and data logic of the store attendant's sale orders
"""
from flask import jsonify

SALE_ORDERS = []

class SaleOrder():
def __init__(self, product_name, product_price, quantity):
self.id = len(SALE_ORDERS) + 1
self.product_name = product_name
self.product_price = product_price
self.quantity = quantity

def save(self):
new_sale_order = {
"sale_order_id": self.id,
"product_name": self.product_name,
"product_price": self.product_price,
"quantity": self.quantity,
"amount": (self.product_price * self.quantity)
}

SALE_ORDERS.append(new_sale_order)
return new_sale_order
27 changes: 27 additions & 0 deletions app/api/v1/models/users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from flask import make_response, jsonify
USERS = []


class User_Model():
def __init__(self, email, password, role):
self.id = len(USERS) + 1
self.email = email
self.password = password
self.role = role

def save(self):
new_user = {
"id": self.id,
"email": self.email,
"password": self.password,
"role": self.role
}

new_added_user = {
"id": self.id,
"email": self.email,
"role": self.role
}

USERS.append(new_user)
return new_added_user
Empty file.
70 changes: 70 additions & 0 deletions app/api/v1/resources/admin_endpoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""This module contains endpoints

that are specific to the admin
"""
import os
import jwt
from functools import wraps

from flask import Flask, jsonify, request, abort, make_response
from flask_restful import Resource
from flask_jwt_extended import get_jwt_identity, jwt_required

from . import helper_functions
from app.api.v1.models import products, sale_orders, users
from . import verify


class ProductsManagement(Resource):
"""Class contains admin specific endpoints"""


def post(self):
"""POST /products endpoint"""

# Token verification and admin user determination
logged_user = verify.verify_tokens()
helper_functions.abort_if_user_is_not_admin(logged_user)

data = request.get_json()
helper_functions.no_json_in_request(data)
try:
product_name = data['product_name']
product_price = data['product_price']
category = data['category']
except KeyError:
# If product is missing required parameter
helper_functions.missing_a_required_parameter()

verify.verify_post_product_fields(product_price, product_name, category)

response = helper_functions.add_product_to_store(product_name, product_price, category)

return make_response(jsonify({
"message": "Product added successfully",
"product": response
}), 201)


class SaleAttendantsManagement(Resource):
"""Class contains the tests managing

sale orders
"""

def get(self):
"""GET /saleorder endpoint"""

verify.verify_tokens()

if not sale_orders.SALE_ORDERS:
# If no products exist in the store yet
abort(make_response(
jsonify(message="There are no sale orders made yet"), 404))
# if at least one product exists
response = jsonify({
'message': "Successfully fetched all the sale orders",
'sale_orders': sale_orders.SALE_ORDERS
})
response.status_code = 200
return response
60 changes: 60 additions & 0 deletions app/api/v1/resources/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import os
import datetime
import jwt
from werkzeug.security import generate_password_hash, check_password_hash
from functools import wraps

from flask import Flask, jsonify, request, make_response
from flask_restful import Resource
from flask_jwt_extended import (
jwt_required, create_access_token,
get_jwt_identity
)

from instance import config
from app.api.v1.utils.validator import Validator
from app.api.v1.models import users

class SignUp(Resource):
def post(self):
data = request.get_json()
if not data:
return make_response(jsonify({
"message": "Missing required credentials"
}), 400)
email = data["email"].strip()
password = generate_password_hash(data["password"].strip(), method='sha256')
role = data["role"].strip()
Validator.validate_credentials(self, data)
user = users.User_Model(email, password, role)
res = user.save()
return make_response(jsonify({
"message": "Account created successfully",
"user": res
}), 202)


class Login(Resource):
def post(self):
data = request.get_json()
if not data:
return make_response(jsonify({
"message": "Kindly enter your credentials"
}
), 400)
email = data["email"].strip()
password = data["password"].strip()

for user in users.USERS:
if email == user["email"] and check_password_hash(user["password"], password):
token = jwt.encode({
"email": email,
"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
}, os.getenv('JWT_SECRET_KEY', default='SdaHv342nx!jknr837bjwd?c,lsajjjhw673hdsbgeh'))
return make_response(jsonify({
"message": "Login successful",
"token": token.decode("UTF-8")}), 200)
return make_response(jsonify({
"message": "Wrong credentials provided"
}
), 403)
Loading