From 71bff808ea2b6d7b3af3078904052da3b8f49a04 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 6 Nov 2018 01:36:11 +0300 Subject: [PATCH 01/66] [starts 161737424]Create RESTful api directory structure --- .gitignore | 3 +++ app/__init__.py | 8 ++++++++ app/api/__init__.py | 0 app/api/v1/__init__.py | 7 +++++++ app/api/v1/models.py | 0 app/api/v1/views.py | 19 +++++++++++++++++++ requirements.txt | 0 run.py | 3 +++ 8 files changed, 40 insertions(+) create mode 100644 .gitignore create mode 100644 app/__init__.py create mode 100644 app/api/__init__.py create mode 100644 app/api/v1/__init__.py create mode 100644 app/api/v1/models.py create mode 100644 app/api/v1/views.py create mode 100644 requirements.txt create mode 100644 run.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e2d16ff --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*__pycache__ +venv +.vscode diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..80afb5b --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,8 @@ +from flask import Flask, Blueprint +from .api.v1 import version1 + +def create_app(): + app = Flask(__name__) + app.register_blueprint(version1) + + return app \ No newline at end of file diff --git a/app/api/__init__.py b/app/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py new file mode 100644 index 0000000..af06015 --- /dev/null +++ b/app/api/v1/__init__.py @@ -0,0 +1,7 @@ +from flask import Blueprint +from flask_restful import Api + + +version1 = Blueprint('v1', __name__, url_prefix="/api/v1") + +api = Api(version1) diff --git a/app/api/v1/models.py b/app/api/v1/models.py new file mode 100644 index 0000000..e69de29 diff --git a/app/api/v1/views.py b/app/api/v1/views.py new file mode 100644 index 0000000..2842140 --- /dev/null +++ b/app/api/v1/views.py @@ -0,0 +1,19 @@ +from flask_restful import Resource +from flask import make_response, jsonify, request + + +class ParcelList(Resource): + + def post(self): + pass + + def get(self): + pass + +class IndividualParcel(Resource): + + def get(self, id): + pass + + def put(self, id): + pass \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/run.py b/run.py new file mode 100644 index 0000000..0a23b5a --- /dev/null +++ b/run.py @@ -0,0 +1,3 @@ +from app import create_app + +app = create_app() From ea6da1159b20523d7dbf6807a37df715acfa96c3 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 6 Nov 2018 02:30:22 +0300 Subject: [PATCH 02/66] [starts #161737782] build model and view for parcels POST api --- app/api/v1/__init__.py | 4 +++- app/api/v1/models.py | 21 +++++++++++++++++++++ app/api/v1/views.py | 18 ++++++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py index af06015..62908e1 100644 --- a/app/api/v1/__init__.py +++ b/app/api/v1/__init__.py @@ -1,7 +1,9 @@ from flask import Blueprint from flask_restful import Api - +from .views import ParcelList version1 = Blueprint('v1', __name__, url_prefix="/api/v1") api = Api(version1) + +api.add_resource(ParcelList, '/parcels') \ No newline at end of file diff --git a/app/api/v1/models.py b/app/api/v1/models.py index e69de29..ca04c2f 100644 --- a/app/api/v1/models.py +++ b/app/api/v1/models.py @@ -0,0 +1,21 @@ + +parcels = [] + +class Parcels: + + def __init__(self): + self.db = parcels + + def create_order(self, item, pickup, dest, pricing): + payload = { + "id" : len(self.db) + 1, + "itemName" : item, + "pickupLocation" : pickup, + "destination" : dest, + "pricing" : pricing + } + self.db.append(payload) + + def order(self): + return self.db + \ No newline at end of file diff --git a/app/api/v1/views.py b/app/api/v1/views.py index 2842140..1ed81bc 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -1,12 +1,26 @@ from flask_restful import Resource from flask import make_response, jsonify, request +from .models import Parcels -class ParcelList(Resource): +class ParcelList(Resource, Parcels): + + def __init__(self): + self.order = Parcels() def post(self): - pass + data = request.get_json() + item = data['item'] + pickup = data['pickup'] + dest = data['dest'] + pricing = data['pricing'] + + self.order.create_order(item, pickup, dest, pricing) + return make_response(jsonify({ + "message" : "delivery order created successfully" + }), 201) + def get(self): pass From 26d00318e58b2fa11828f327c4afe0ede2de3dbb Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 6 Nov 2018 14:48:16 +0300 Subject: [PATCH 03/66] [starts #161748253] Create GET delivery order list --- app/api/v1/models.py | 2 +- app/api/v1/views.py | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/api/v1/models.py b/app/api/v1/models.py index ca04c2f..4a9dd80 100644 --- a/app/api/v1/models.py +++ b/app/api/v1/models.py @@ -16,6 +16,6 @@ def create_order(self, item, pickup, dest, pricing): } self.db.append(payload) - def order(self): + def order_list(self): return self.db \ No newline at end of file diff --git a/app/api/v1/views.py b/app/api/v1/views.py index 1ed81bc..153f45a 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -2,7 +2,7 @@ from flask import make_response, jsonify, request from .models import Parcels - +cancelled = 'cancel' class ParcelList(Resource, Parcels): def __init__(self): @@ -22,7 +22,12 @@ def post(self): }), 201) def get(self): - pass + resp = self.order.order_list() + return make_response(jsonify({ + "message" : "ok" + "Delivery Orders" : resp + }), 200) + class IndividualParcel(Resource): @@ -30,4 +35,5 @@ def get(self, id): pass def put(self, id): - pass \ No newline at end of file + pass + \ No newline at end of file From 67006a92b1723460c94a33d9d02a1ca24ef4da06 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 00:44:46 +0300 Subject: [PATCH 04/66] [starts #161766269]Build API to retrieve single order --- app/api/v1/__init__.py | 5 +++-- app/api/v1/models.py | 5 +++++ app/api/v1/views.py | 24 ++++++++++++++---------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py index 62908e1..a419e8f 100644 --- a/app/api/v1/__init__.py +++ b/app/api/v1/__init__.py @@ -1,9 +1,10 @@ from flask import Blueprint from flask_restful import Api -from .views import ParcelList +from .views import ParcelList, IndividualParcel version1 = Blueprint('v1', __name__, url_prefix="/api/v1") api = Api(version1) -api.add_resource(ParcelList, '/parcels') \ No newline at end of file +api.add_resource(ParcelList, '/parcels') +api.add_resource(IndividualParcel, '/parcels/') \ No newline at end of file diff --git a/app/api/v1/models.py b/app/api/v1/models.py index 4a9dd80..53b78ac 100644 --- a/app/api/v1/models.py +++ b/app/api/v1/models.py @@ -18,4 +18,9 @@ def create_order(self, item, pickup, dest, pricing): def order_list(self): return self.db + + def retrieve_single_order(self, parcelID): + order_by_id = [parc for parc in self.db if parc['id'] == parcelID][0] + return order_by_id + \ No newline at end of file diff --git a/app/api/v1/views.py b/app/api/v1/views.py index 153f45a..a4ebb90 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -2,11 +2,9 @@ from flask import make_response, jsonify, request from .models import Parcels -cancelled = 'cancel' -class ParcelList(Resource, Parcels): +order = Parcels() - def __init__(self): - self.order = Parcels() +class ParcelList(Resource): def post(self): data = request.get_json() @@ -15,16 +13,17 @@ def post(self): dest = data['dest'] pricing = data['pricing'] - self.order.create_order(item, pickup, dest, pricing) - + order.create_order(item, pickup, dest, pricing) + orders = order.db return make_response(jsonify({ - "message" : "delivery order created successfully" + "message" : "delivery order created successfully", + "orders" : orders }), 201) def get(self): - resp = self.order.order_list() + resp = order.order_list() return make_response(jsonify({ - "message" : "ok" + "message" : "ok", "Delivery Orders" : resp }), 200) @@ -32,7 +31,12 @@ def get(self): class IndividualParcel(Resource): def get(self, id): - pass + single = order.retrieve_single_order(id) + return make_response(jsonify({ + "message" : "Ok", + "order" : single + }), 200) + def put(self, id): pass From 37f0d14487b07c0cefe5cd431fd8b9d3f7efdf11 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 00:53:12 +0300 Subject: [PATCH 05/66] [finishes #161766269] Add class and methods docstrings --- app/api/v1/models.py | 13 ++++++++++++- app/api/v1/views.py | 18 +++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/api/v1/models.py b/app/api/v1/models.py index 53b78ac..6e24a12 100644 --- a/app/api/v1/models.py +++ b/app/api/v1/models.py @@ -2,11 +2,16 @@ parcels = [] class Parcels: - + """ + Class with CRUD functionalities on the Parcels resource + """ def __init__(self): self.db = parcels def create_order(self, item, pickup, dest, pricing): + """ + instance method to generate new entry into delivery orders list + """ payload = { "id" : len(self.db) + 1, "itemName" : item, @@ -17,9 +22,15 @@ def create_order(self, item, pickup, dest, pricing): self.db.append(payload) def order_list(self): + """ + retrieves entire list of delivery orders + """ return self.db def retrieve_single_order(self, parcelID): + """ + retrive a single order by id + """ order_by_id = [parc for parc in self.db if parc['id'] == parcelID][0] return order_by_id diff --git a/app/api/v1/views.py b/app/api/v1/views.py index a4ebb90..6f0b6be 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -5,8 +5,13 @@ order = Parcels() class ParcelList(Resource): - + """ + class for Create order and retrieve list of orders API endpoints + """ def post(self): + """ + post method to add new order to list of orders + """ data = request.get_json() item = data['item'] pickup = data['pickup'] @@ -21,16 +26,23 @@ def post(self): }), 201) def get(self): + """ + get method to retrieve list of all orders + """ resp = order.order_list() return make_response(jsonify({ "message" : "ok", "Delivery Orders" : resp }), 200) - class IndividualParcel(Resource): - + """ + class for API endpoints for retrieving single order and cancelling particular order + """ def get(self, id): + """ + get method to retrieve order by id + """ single = order.retrieve_single_order(id) return make_response(jsonify({ "message" : "Ok", From 534a2b95ecfd2825889c8e540fe52dbb479d7f0b Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 08:24:06 +0300 Subject: [PATCH 06/66] [starts #161773293] write passing test for POST new parcel order --- app/tests/__init__.py | 0 app/tests/test_create_parcel.py | 25 +++++++++++++++++++++++++ requirements.txt | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 app/tests/__init__.py create mode 100644 app/tests/test_create_parcel.py diff --git a/app/tests/__init__.py b/app/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/test_create_parcel.py b/app/tests/test_create_parcel.py new file mode 100644 index 0000000..fad3dcc --- /dev/null +++ b/app/tests/test_create_parcel.py @@ -0,0 +1,25 @@ +from .. import create_app +import unittest +import json + +class TestPracelCreation(unittest.TestCase): + def setUp(self): + create_app().testing = True + self.app = create_app().test_client() + self.data = { + "item" : "seven ballons", + "pickup" : "Biashara street", + "dest" : "Kikuyu town", + "pricing": "250 ksh" + } + + def test_POST_create_delivery_order(self): + response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') + result = json.loads(response.data) + self.assertEqual(response.status_code, 201) + self.assertIn('seven ballons', str(result)) + +# make the tests you have written executable + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e69de29..5fa0e4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,24 @@ +aniso8601==4.0.1 +astroid==2.0.4 +atomicwrites==1.2.1 +attrs==18.2.0 +Click==7.0 +Flask==1.0.2 +Flask-RESTful==0.3.6 +isort==4.3.4 +itsdangerous==1.1.0 +Jinja2==2.10 +lazy-object-proxy==1.3.1 +MarkupSafe==1.0 +mccabe==0.6.1 +more-itertools==4.3.0 +pkg-resources==0.0.0 +pluggy==0.8.0 +py==1.7.0 +pylint==2.1.1 +pytest==3.10.0 +pytz==2018.7 +six==1.11.0 +typed-ast==1.1.0 +Werkzeug==0.14.1 +wrapt==1.10.11 From 66c2c042568f94cb45f28ca46348c9c814369c26 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 09:02:27 +0300 Subject: [PATCH 07/66] [starts #161773596] write test for GET list of delivery orders --- app/tests/test_parcels.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 app/tests/test_parcels.py diff --git a/app/tests/test_parcels.py b/app/tests/test_parcels.py new file mode 100644 index 0000000..69510d2 --- /dev/null +++ b/app/tests/test_parcels.py @@ -0,0 +1,35 @@ +from .. import create_app +import unittest +import json + +class TestPracelCreation(unittest.TestCase): + def setUp(self): + create_app().testing = True + self.app = create_app().test_client() + self.data = { + "item" : "seven ballons", + "pickup" : "Biashara street", + "dest" : "Kikuyu town", + "pricing": "250 ksh" + } + + def test_POST_create_delivery_order(self): + response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') + result = json.loads(response.data) + self.assertEqual(response.status_code, 201) + self.assertIn('seven ballons', str(result)) + + def test_GET_delivery_orders_list(self): + """Test if API can retrieve a list of delivery orders""" + response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') + self.assertEqual(response.status_code, 201) + response = self.app.get('/api/v1/parcels', content_type='application/json') + self.assertEqual(response.status_code, 200) + result = json.loads(response.data) + self.assertIn('seven ballons', str(result)) + + +# make the tests you have written executable + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 101cd2c193b179e9c551ad1d531af7c9d6a1ca2b Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 09:09:01 +0300 Subject: [PATCH 08/66] [finishes #161773596] add doctsrtings to test class --- app/tests/test_parcels.py | 13 ++++++++- app/tests/v1/__init__.py | 0 app/tests/{ => v1}/test_create_parcel.py | 0 app/tests/v1/test_parcels.py | 35 ++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 app/tests/v1/__init__.py rename app/tests/{ => v1}/test_create_parcel.py (100%) create mode 100644 app/tests/v1/test_parcels.py diff --git a/app/tests/test_parcels.py b/app/tests/test_parcels.py index 69510d2..fa4c28c 100644 --- a/app/tests/test_parcels.py +++ b/app/tests/test_parcels.py @@ -3,7 +3,13 @@ import json class TestPracelCreation(unittest.TestCase): + """ + class for Parcels test case + """ def setUp(self): + """ + Initialize app and define test variables + """ create_app().testing = True self.app = create_app().test_client() self.data = { @@ -14,13 +20,18 @@ def setUp(self): } def test_POST_create_delivery_order(self): + """ + Test whether API can create a new delivery order via POSt request + """ response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') result = json.loads(response.data) self.assertEqual(response.status_code, 201) self.assertIn('seven ballons', str(result)) def test_GET_delivery_orders_list(self): - """Test if API can retrieve a list of delivery orders""" + """ + Test if API can retrieve a list of delivery orders + """ response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') self.assertEqual(response.status_code, 201) response = self.app.get('/api/v1/parcels', content_type='application/json') diff --git a/app/tests/v1/__init__.py b/app/tests/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/test_create_parcel.py b/app/tests/v1/test_create_parcel.py similarity index 100% rename from app/tests/test_create_parcel.py rename to app/tests/v1/test_create_parcel.py diff --git a/app/tests/v1/test_parcels.py b/app/tests/v1/test_parcels.py new file mode 100644 index 0000000..69510d2 --- /dev/null +++ b/app/tests/v1/test_parcels.py @@ -0,0 +1,35 @@ +from .. import create_app +import unittest +import json + +class TestPracelCreation(unittest.TestCase): + def setUp(self): + create_app().testing = True + self.app = create_app().test_client() + self.data = { + "item" : "seven ballons", + "pickup" : "Biashara street", + "dest" : "Kikuyu town", + "pricing": "250 ksh" + } + + def test_POST_create_delivery_order(self): + response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') + result = json.loads(response.data) + self.assertEqual(response.status_code, 201) + self.assertIn('seven ballons', str(result)) + + def test_GET_delivery_orders_list(self): + """Test if API can retrieve a list of delivery orders""" + response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') + self.assertEqual(response.status_code, 201) + response = self.app.get('/api/v1/parcels', content_type='application/json') + self.assertEqual(response.status_code, 200) + result = json.loads(response.data) + self.assertIn('seven ballons', str(result)) + + +# make the tests you have written executable + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 7f1fd34c88825cbd1a98044427ecd9bc9a5903f2 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 10:01:29 +0300 Subject: [PATCH 09/66] [starts #161774149] restructure v1 test folder and write test for single order retrieval --- app/tests/test_parcels.py | 46 ------------------------------ app/tests/v1/test_create_parcel.py | 25 ---------------- app/tests/v1/test_parcels.py | 28 +++++++++++++++--- 3 files changed, 24 insertions(+), 75 deletions(-) delete mode 100644 app/tests/test_parcels.py delete mode 100644 app/tests/v1/test_create_parcel.py diff --git a/app/tests/test_parcels.py b/app/tests/test_parcels.py deleted file mode 100644 index fa4c28c..0000000 --- a/app/tests/test_parcels.py +++ /dev/null @@ -1,46 +0,0 @@ -from .. import create_app -import unittest -import json - -class TestPracelCreation(unittest.TestCase): - """ - class for Parcels test case - """ - def setUp(self): - """ - Initialize app and define test variables - """ - create_app().testing = True - self.app = create_app().test_client() - self.data = { - "item" : "seven ballons", - "pickup" : "Biashara street", - "dest" : "Kikuyu town", - "pricing": "250 ksh" - } - - def test_POST_create_delivery_order(self): - """ - Test whether API can create a new delivery order via POSt request - """ - response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') - result = json.loads(response.data) - self.assertEqual(response.status_code, 201) - self.assertIn('seven ballons', str(result)) - - def test_GET_delivery_orders_list(self): - """ - Test if API can retrieve a list of delivery orders - """ - response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') - self.assertEqual(response.status_code, 201) - response = self.app.get('/api/v1/parcels', content_type='application/json') - self.assertEqual(response.status_code, 200) - result = json.loads(response.data) - self.assertIn('seven ballons', str(result)) - - -# make the tests you have written executable - -if __name__ == "__main__": - unittest.main() \ No newline at end of file diff --git a/app/tests/v1/test_create_parcel.py b/app/tests/v1/test_create_parcel.py deleted file mode 100644 index fad3dcc..0000000 --- a/app/tests/v1/test_create_parcel.py +++ /dev/null @@ -1,25 +0,0 @@ -from .. import create_app -import unittest -import json - -class TestPracelCreation(unittest.TestCase): - def setUp(self): - create_app().testing = True - self.app = create_app().test_client() - self.data = { - "item" : "seven ballons", - "pickup" : "Biashara street", - "dest" : "Kikuyu town", - "pricing": "250 ksh" - } - - def test_POST_create_delivery_order(self): - response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') - result = json.loads(response.data) - self.assertEqual(response.status_code, 201) - self.assertIn('seven ballons', str(result)) - -# make the tests you have written executable - -if __name__ == "__main__": - unittest.main() \ No newline at end of file diff --git a/app/tests/v1/test_parcels.py b/app/tests/v1/test_parcels.py index 69510d2..a9f5e71 100644 --- a/app/tests/v1/test_parcels.py +++ b/app/tests/v1/test_parcels.py @@ -1,9 +1,15 @@ -from .. import create_app +from ... import create_app import unittest import json class TestPracelCreation(unittest.TestCase): + """ + class for Parcels test case + """ def setUp(self): + """ + Initialize app and define test variables + """ create_app().testing = True self.app = create_app().test_client() self.data = { @@ -14,21 +20,35 @@ def setUp(self): } def test_POST_create_delivery_order(self): + """ + Test whether API can create a new delivery order via POSt request + """ response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') result = json.loads(response.data) self.assertEqual(response.status_code, 201) self.assertIn('seven ballons', str(result)) def test_GET_delivery_orders_list(self): - """Test if API can retrieve a list of delivery orders""" + """ + Test if API can retrieve a list of delivery orders + """ response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') self.assertEqual(response.status_code, 201) response = self.app.get('/api/v1/parcels', content_type='application/json') self.assertEqual(response.status_code, 200) result = json.loads(response.data) self.assertIn('seven ballons', str(result)) - - + + def test_GET_single_delivery_order(self): + """ + Test if API can retrieve a single delivery order by its id + """ + response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') + self.assertEqual(response.status_code, 201) + result = self.app.get('/api/v1/parcels/1') + self.assertEqual(result.status_code, 200) + self.assertIn('seven ballons', str(result.data)) + # make the tests you have written executable if __name__ == "__main__": From 49471e2acd107765c1716a0b56db996ca8766dc8 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 13:32:59 +0300 Subject: [PATCH 10/66] [starts #161777597] Add status attribute and update status method --- app/api/v1/models.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/api/v1/models.py b/app/api/v1/models.py index 6e24a12..f863b58 100644 --- a/app/api/v1/models.py +++ b/app/api/v1/models.py @@ -7,6 +7,7 @@ class Parcels: """ def __init__(self): self.db = parcels + self.parcel_status = 'pending' def create_order(self, item, pickup, dest, pricing): """ @@ -17,7 +18,8 @@ def create_order(self, item, pickup, dest, pricing): "itemName" : item, "pickupLocation" : pickup, "destination" : dest, - "pricing" : pricing + "pricing" : pricing, + "status" : self.parcel_status } self.db.append(payload) @@ -29,9 +31,16 @@ def order_list(self): def retrieve_single_order(self, parcelID): """ - retrive a single order by id + retrieve a single order by id """ order_by_id = [parc for parc in self.db if parc['id'] == parcelID][0] return order_by_id - + + def cancel_order(self, ParcelID): + """ + update parcel status to cancel + """ + parcel_to_cancel = [parc for parc in self.db if parc['id'] == ParcelID] + parcel_to_cancel[0]['status'] = 'cancelled' + return parcel_to_cancel \ No newline at end of file From 7c66fd903d0971b9f3f8c29ae219c07746622a60 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 13:46:51 +0300 Subject: [PATCH 11/66] Create PUT method to cancel order by id --- app/api/v1/__init__.py | 5 +++-- app/api/v1/views.py | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py index a419e8f..1e0ed28 100644 --- a/app/api/v1/__init__.py +++ b/app/api/v1/__init__.py @@ -1,10 +1,11 @@ from flask import Blueprint from flask_restful import Api -from .views import ParcelList, IndividualParcel +from .views import ParcelList, IndividualParcel, CancelParcel version1 = Blueprint('v1', __name__, url_prefix="/api/v1") api = Api(version1) api.add_resource(ParcelList, '/parcels') -api.add_resource(IndividualParcel, '/parcels/') \ No newline at end of file +api.add_resource(IndividualParcel, '/parcels/') +api.add_resource(CancelParcel, '/parcels//cancel') \ No newline at end of file diff --git a/app/api/v1/views.py b/app/api/v1/views.py index 6f0b6be..6f39381 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -49,7 +49,17 @@ def get(self, id): "order" : single }), 200) - +class CancelParcel(Resource): + """ + class for endpoint to cancel parcel order + """ def put(self, id): - pass + """ + PUT request to update parcel status to 'cancelled' + """ + cancel_parcel = order.cancel_order(id) + return make_response(jsonify({ + "message" : "order is cancelled", + "cancelled order" : cancel_parcel + }), 201) \ No newline at end of file From d011417e90599ccd7456aa7a0936d4dfd6e4d5e8 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 7 Nov 2018 13:58:26 +0300 Subject: [PATCH 12/66] [finishes #161777597] write test for PUT cancel order endpoint --- app/tests/v1/test_parcels.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/tests/v1/test_parcels.py b/app/tests/v1/test_parcels.py index a9f5e71..b356dce 100644 --- a/app/tests/v1/test_parcels.py +++ b/app/tests/v1/test_parcels.py @@ -48,6 +48,16 @@ def test_GET_single_delivery_order(self): result = self.app.get('/api/v1/parcels/1') self.assertEqual(result.status_code, 200) self.assertIn('seven ballons', str(result.data)) + + def test_PUT_cancel_delivery_order(self): + """ + Test if API can cancel order by changing order status + """ + response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') + self.assertEqual(response.status_code, 201) + result = self.app.put('/api/v1/parcels/1/cancel') + self.assertEqual(result.status_code, 201) + self.assertIn('order is cancelled', str(result.data)) # make the tests you have written executable From e22c5239b753233f1b36de874693ef0f3b728a94 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Thu, 8 Nov 2018 00:33:47 +0300 Subject: [PATCH 13/66] [starts #161796710] Create authentication blueprint in project directory --- app/__init__.py | 4 +++- app/auth/__init__.py | 0 app/auth/v1/__init__.py | 8 ++++++++ app/auth/v1/models.py | 0 app/auth/v1/views.py | 0 5 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 app/auth/__init__.py create mode 100644 app/auth/v1/__init__.py create mode 100644 app/auth/v1/models.py create mode 100644 app/auth/v1/views.py diff --git a/app/__init__.py b/app/__init__.py index 80afb5b..06a4001 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,8 +1,10 @@ from flask import Flask, Blueprint from .api.v1 import version1 +from .auth.v1 import auth_version1 def create_app(): app = Flask(__name__) app.register_blueprint(version1) - + app.register_blueprint(auth_version1) + return app \ No newline at end of file diff --git a/app/auth/__init__.py b/app/auth/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/auth/v1/__init__.py b/app/auth/v1/__init__.py new file mode 100644 index 0000000..90fbe99 --- /dev/null +++ b/app/auth/v1/__init__.py @@ -0,0 +1,8 @@ +from flask import Blueprint +from flask_restful import Api +#from .views import Registration +auth_version1 = Blueprint('v1', __name__, url_prefix="/auth/v1") + +api = Api(auth_version1) + +#api.add_resource(Registration, '/register') diff --git a/app/auth/v1/models.py b/app/auth/v1/models.py new file mode 100644 index 0000000..e69de29 diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py new file mode 100644 index 0000000..e69de29 From 1abc1843efa676b6166a13ec76a4ccd501928208 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Thu, 8 Nov 2018 01:38:25 +0300 Subject: [PATCH 14/66] create user registration model and registration api --- app/__init__.py | 6 ++-- app/auth/__init__.py | 9 +++++ app/auth/models.py | 75 +++++++++++++++++++++++++++++++++++++++++ app/auth/v1/__init__.py | 8 ----- app/auth/v1/models.py | 0 app/auth/v1/views.py | 0 app/auth/views.py | 16 +++++++++ requirements.txt | 1 + 8 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 app/auth/models.py delete mode 100644 app/auth/v1/__init__.py delete mode 100644 app/auth/v1/models.py delete mode 100644 app/auth/v1/views.py create mode 100644 app/auth/views.py diff --git a/app/__init__.py b/app/__init__.py index 06a4001..c42a843 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,10 +1,10 @@ from flask import Flask, Blueprint from .api.v1 import version1 -from .auth.v1 import auth_version1 +from .auth import auth def create_app(): app = Flask(__name__) app.register_blueprint(version1) - app.register_blueprint(auth_version1) - + app.register_blueprint(auth) + return app \ No newline at end of file diff --git a/app/auth/__init__.py b/app/auth/__init__.py index e69de29..95fb857 100644 --- a/app/auth/__init__.py +++ b/app/auth/__init__.py @@ -0,0 +1,9 @@ +from flask import Blueprint +from flask_restful import Api +from .views import Registration + +auth = Blueprint('auth', __name__, url_prefix="/auth") + +api = Api(auth) + +api.add_resource(Registration, '/register') diff --git a/app/auth/models.py b/app/auth/models.py new file mode 100644 index 0000000..173241d --- /dev/null +++ b/app/auth/models.py @@ -0,0 +1,75 @@ +from datetime import datetime, timedelta +import jwt +from werkzeug.security import generate_password_hash, check_password_hash + +class MockDb(): + """ + class for a data structure database + """ + def __init__(self): + self.users = {} + self.orders = {} + self.user_no = 0 + self.entry_no = 0 + def drop(self): + self.__init__() + +db = MockDb() + +class Parent(): + """ + user class will inherit this class + """ + def bring_to_speed(self, data): + # Validate the contents before passing to mock database + for key in data: + setattr(self, key, data[key]) + setattr(self, 'last_updated', datetime.utcnow().isoformat()) + return self.lookup() + +class User(Parent): + """ + class to register user and generate tokens + """ + def __init__(self, email, password): + self.email = email + self.password = generate_password_hash(password) + self.id = None + self.created_at = datetime.utcnow().isoformat() + self.last_updated = datetime.utcnow().isoformat() + + def add_user(self): + """ + method to save a user's registration details + """ + setattr(self, 'id', db.user_no + 1) + db.users.update({self.id: self}) + db.user_no += 1 + db.orders.update({self.id: {}}) + return self.lookup() + + def validate_password(self, password): + """ + method to validate user password + """ + if check_password_hash(self.password, password): + return True + return False + + def lookup(self): + """ + method to jsonify object that represents user + """ + keys = ['email', 'id'] + return {key: getattr(self, key) for key in keys} + + @classmethod + def get_user_by_email(cls, email): + """ + method for getting a user by email + """ + for user_id in db.users: + user = db.users.get(user_id) + if user.email == email: + return user + return None \ No newline at end of file diff --git a/app/auth/v1/__init__.py b/app/auth/v1/__init__.py deleted file mode 100644 index 90fbe99..0000000 --- a/app/auth/v1/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from flask import Blueprint -from flask_restful import Api -#from .views import Registration -auth_version1 = Blueprint('v1', __name__, url_prefix="/auth/v1") - -api = Api(auth_version1) - -#api.add_resource(Registration, '/register') diff --git a/app/auth/v1/models.py b/app/auth/v1/models.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/auth/views.py b/app/auth/views.py new file mode 100644 index 0000000..2f97432 --- /dev/null +++ b/app/auth/views.py @@ -0,0 +1,16 @@ +from flask_restful import Resource +from flask import make_response,jsonify, request +from .models import User + +class Registration(Resource): + def post(self): + data = request.get_json() + email = data['email'] + password = data['password'] + + new_user = User(email=email, password=password) + new_user.add_user() + + return make_response(jsonify({ + 'message' : 'you have successfully registered an account' + }), 201) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 5fa0e4c..2c457bb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,6 +15,7 @@ more-itertools==4.3.0 pkg-resources==0.0.0 pluggy==0.8.0 py==1.7.0 +PyJWT==1.6.4 pylint==2.1.1 pytest==3.10.0 pytz==2018.7 From 5520d68d8132716509b52f2427c9166491650288 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Thu, 8 Nov 2018 08:09:24 +0300 Subject: [PATCH 15/66] [finishes #161796710] add a test for registration endpoint --- app/__init__.py | 2 +- app/auth/__init__.py | 9 --------- app/auth/v1/__init__.py | 9 +++++++++ app/auth/{ => v1}/models.py | 0 app/auth/{ => v1}/views.py | 0 app/tests/v1/test_registration.py | 27 +++++++++++++++++++++++++++ 6 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 app/auth/v1/__init__.py rename app/auth/{ => v1}/models.py (100%) rename app/auth/{ => v1}/views.py (100%) create mode 100644 app/tests/v1/test_registration.py diff --git a/app/__init__.py b/app/__init__.py index c42a843..b7f9191 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,6 +1,6 @@ from flask import Flask, Blueprint from .api.v1 import version1 -from .auth import auth +from .auth.v1 import auth def create_app(): app = Flask(__name__) diff --git a/app/auth/__init__.py b/app/auth/__init__.py index 95fb857..e69de29 100644 --- a/app/auth/__init__.py +++ b/app/auth/__init__.py @@ -1,9 +0,0 @@ -from flask import Blueprint -from flask_restful import Api -from .views import Registration - -auth = Blueprint('auth', __name__, url_prefix="/auth") - -api = Api(auth) - -api.add_resource(Registration, '/register') diff --git a/app/auth/v1/__init__.py b/app/auth/v1/__init__.py new file mode 100644 index 0000000..eccd429 --- /dev/null +++ b/app/auth/v1/__init__.py @@ -0,0 +1,9 @@ +from flask import Blueprint +from flask_restful import Api +from .views import Registration + +auth = Blueprint('auth', __name__, url_prefix="/auth/v1") + +api = Api(auth) + +api.add_resource(Registration, '/register') diff --git a/app/auth/models.py b/app/auth/v1/models.py similarity index 100% rename from app/auth/models.py rename to app/auth/v1/models.py diff --git a/app/auth/views.py b/app/auth/v1/views.py similarity index 100% rename from app/auth/views.py rename to app/auth/v1/views.py diff --git a/app/tests/v1/test_registration.py b/app/tests/v1/test_registration.py new file mode 100644 index 0000000..20d25ad --- /dev/null +++ b/app/tests/v1/test_registration.py @@ -0,0 +1,27 @@ +from ... import create_app +import unittest +import json + +class AuthTestCase(unittest.TestCase): + """ + test class for the registration endpoint + """ + def setUp(self): + create_app().testing = True + self.app = create_app().test_client() + self.mock_data = { + 'email' : 'test@hotmail.com', + 'password' : 'holy_water' + } + + def test_signup(self): + response = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') + res = json.loads(response.data) + self.assertEqual(response.status_code, 201) + self.assertEqual(res['message'], "you have successfully registered an account") + + + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 0d6055eaece7154081da418ba289701ecdfccfd6 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Thu, 8 Nov 2018 08:38:46 +0300 Subject: [PATCH 16/66] write test for registration endpoint and additional logic in its view --- app/auth/v1/views.py | 17 ++++++++++++----- app/tests/v1/test_registration.py | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index 2f97432..d474721 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -8,9 +8,16 @@ def post(self): email = data['email'] password = data['password'] - new_user = User(email=email, password=password) - new_user.add_user() + if not User.get_user_by_email(email): + new_user = User(email=email, password=password) + new_user.add_user() - return make_response(jsonify({ - 'message' : 'you have successfully registered an account' - }), 201) \ No newline at end of file + return make_response(jsonify({ + 'message' : 'you have successfully registered an account' + }), 201) + else: + response = { + 'message': 'Account with provided email exists. please login' + } + + return make_response((jsonify(response)), 202) \ No newline at end of file diff --git a/app/tests/v1/test_registration.py b/app/tests/v1/test_registration.py index 20d25ad..2a1600f 100644 --- a/app/tests/v1/test_registration.py +++ b/app/tests/v1/test_registration.py @@ -13,13 +13,22 @@ def setUp(self): 'email' : 'test@hotmail.com', 'password' : 'holy_water' } - + + """ def test_signup(self): - response = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') - res = json.loads(response.data) - self.assertEqual(response.status_code, 201) + response2 = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') + res = json.loads(response2.data) + self.assertEqual(response2.status_code, 201) self.assertEqual(res['message'], "you have successfully registered an account") + """ + def test_if_registered(self): + response1 = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') + self.assertEqual(response1.status_code, 201) + duplicate_signup = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') + self.assertEqual(duplicate_signup.status_code, 202) + res = json.loads(duplicate_signup.data) + self.assertEqual(res['message'], 'Account with provided email exists. please login') From 0a4cd7518f401a236113d824b239e24dfb7f9d22 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Thu, 8 Nov 2018 21:51:40 +0300 Subject: [PATCH 17/66] [starts #161820120] Add methods to decode/encode tokens and instance folder --- .gitignore | 3 +++ app/__init__.py | 2 ++ app/api/v1/__init__.py | 2 +- app/api/v1/views.py | 4 +--- app/auth/v1/models.py | 22 ++++++++++++++++++++++ app/tests/v1/test_parcels.py | 2 +- 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index e2d16ff..1ce024a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ *__pycache__ venv .vscode +*.pytest_cache +instance + diff --git a/app/__init__.py b/app/__init__.py index b7f9191..d92f812 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,9 +1,11 @@ from flask import Flask, Blueprint +from instance.config import DevConfig from .api.v1 import version1 from .auth.v1 import auth def create_app(): app = Flask(__name__) + app.config.from_object(DevConfig) app.register_blueprint(version1) app.register_blueprint(auth) diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py index 1e0ed28..deb2096 100644 --- a/app/api/v1/__init__.py +++ b/app/api/v1/__init__.py @@ -8,4 +8,4 @@ api.add_resource(ParcelList, '/parcels') api.add_resource(IndividualParcel, '/parcels/') -api.add_resource(CancelParcel, '/parcels//cancel') \ No newline at end of file +api.add_resource(CancelParcel, '/parcels//cancel') diff --git a/app/api/v1/views.py b/app/api/v1/views.py index 6f39381..e50a6c5 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -19,10 +19,8 @@ def post(self): pricing = data['pricing'] order.create_order(item, pickup, dest, pricing) - orders = order.db return make_response(jsonify({ - "message" : "delivery order created successfully", - "orders" : orders + "message" : "delivery order created successfully" }), 201) def get(self): diff --git a/app/auth/v1/models.py b/app/auth/v1/models.py index 173241d..69e69b7 100644 --- a/app/auth/v1/models.py +++ b/app/auth/v1/models.py @@ -1,4 +1,5 @@ from datetime import datetime, timedelta +from flask import current_app import jwt from werkzeug.security import generate_password_hash, check_password_hash @@ -63,6 +64,27 @@ def lookup(self): keys = ['email', 'id'] return {key: getattr(self, key) for key in keys} + def generate_token(self): + """ + method that generates token during each login + """ + payload = { + 'exp' : datetime.utcnow()+timedelta(minutes=5), + 'iat' : datetime.utcnow(), + 'email' : self.email, + 'id' : self.id + } + token = jwt.encode(payload, str(current_app.config.get('SECRET_KEY')), algorithm='HS256') + return token + + @staticmethod + def decode_token(token): + """ + method to decode the token generated during login + """ + payload = jwt.decode(token, str(current_app.config.get('SECRET_KEY')), algorithm='HS256') + return payload + @classmethod def get_user_by_email(cls, email): """ diff --git a/app/tests/v1/test_parcels.py b/app/tests/v1/test_parcels.py index b356dce..b408742 100644 --- a/app/tests/v1/test_parcels.py +++ b/app/tests/v1/test_parcels.py @@ -26,7 +26,7 @@ def test_POST_create_delivery_order(self): response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') result = json.loads(response.data) self.assertEqual(response.status_code, 201) - self.assertIn('seven ballons', str(result)) + self.assertIn('delivery order created', str(result)) def test_GET_delivery_orders_list(self): """ From dcf6e3e0c11f090981106ceef587f72eb63b99f8 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Thu, 8 Nov 2018 22:37:29 +0300 Subject: [PATCH 18/66] Add enpoint to login and generate token --- app/auth/v1/__init__.py | 3 ++- app/auth/v1/models.py | 42 +++++++++++++++++++++++++++-------------- app/auth/v1/views.py | 35 +++++++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/app/auth/v1/__init__.py b/app/auth/v1/__init__.py index eccd429..6b41930 100644 --- a/app/auth/v1/__init__.py +++ b/app/auth/v1/__init__.py @@ -1,9 +1,10 @@ from flask import Blueprint from flask_restful import Api -from .views import Registration +from .views import Registration, SignIn auth = Blueprint('auth', __name__, url_prefix="/auth/v1") api = Api(auth) api.add_resource(Registration, '/register') +api.add_resource(SignIn, '/login') diff --git a/app/auth/v1/models.py b/app/auth/v1/models.py index 69e69b7..1dc1f6b 100644 --- a/app/auth/v1/models.py +++ b/app/auth/v1/models.py @@ -21,7 +21,7 @@ class Parent(): """ user class will inherit this class """ - def bring_to_speed(self, data): + def update(self, data): # Validate the contents before passing to mock database for key in data: setattr(self, key, data[key]) @@ -64,27 +64,41 @@ def lookup(self): keys = ['email', 'id'] return {key: getattr(self, key) for key in keys} - def generate_token(self): + def generate_token(self, userID): """ method that generates token during each login """ - payload = { - 'exp' : datetime.utcnow()+timedelta(minutes=5), - 'iat' : datetime.utcnow(), - 'email' : self.email, - 'id' : self.id - } - token = jwt.encode(payload, str(current_app.config.get('SECRET_KEY')), algorithm='HS256') - return token - + try: + payload = { + 'exp' : datetime.utcnow()+timedelta(minutes=5), + 'iat' : datetime.utcnow(), + 'id' : userID + } + token = jwt.encode( + payload, + current_app.config.get('SECRET_KEY'), + algorithm='HS256' + ) + return token + except Exception as err: + return str(err) + @staticmethod def decode_token(token): """ method to decode the token generated during login """ - payload = jwt.decode(token, str(current_app.config.get('SECRET_KEY')), algorithm='HS256') - return payload - + try: + #attempt to decode token using SECRET_KEY variable + payload = jwt.decode(token, current_app.config.get('SECRET_KEY')) + return payload['id'] + except jwt.ExpiredSignatureError: + # expired token returns an error string + return "Token expired. please login again to generate fresh token" + except jwt.InvalidTokenError: + #the token is not valid, throw error + return "Unworthy token. Please login to get fresh authorization" + @classmethod def get_user_by_email(cls, email): """ diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index d474721..3a7fccb 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -3,6 +3,9 @@ from .models import User class Registration(Resource): + """ + class that handles registration of new user + """ def post(self): data = request.get_json() email = data['email'] @@ -20,4 +23,34 @@ def post(self): 'message': 'Account with provided email exists. please login' } - return make_response((jsonify(response)), 202) \ No newline at end of file + return make_response((jsonify(response)), 202) + +class SignIn(Resource): + """ + class that handles logging into user accounts and token generation + """ + def post(self): + data = request.get_json() + email = data['email'] + password = data['password'] + try: + user = User.get_user_by_email(email) + user_id = user.id + if user and user.validate_password(password): + auth_token = user.generate_token(user_id) + if auth_token: + response = { + 'message' : 'Successfully logged in', + 'authentication token' : auth_token.decode() + } + return make_response(jsonify(response), 200) + else: + response = { + 'message' : 'User with email already exists, please login' + } + return make_response(jsonify(response), 401) + except Exception as err: + response = { + 'message' : str(err) + } + return make_response(jsonify(response), 500) \ No newline at end of file From 9e3308458b37ad49ae3e22abc95f2af333fbeea6 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Thu, 8 Nov 2018 23:13:54 +0300 Subject: [PATCH 19/66] [finishes #161820120] write minimal tests for sign in endpoint --- app/tests/v1/test_login.py | 40 +++++++++++++++++++ ...{test_registration.py => test_register.py} | 13 +++--- 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 app/tests/v1/test_login.py rename app/tests/v1/{test_registration.py => test_register.py} (81%) diff --git a/app/tests/v1/test_login.py b/app/tests/v1/test_login.py new file mode 100644 index 0000000..3ee73e4 --- /dev/null +++ b/app/tests/v1/test_login.py @@ -0,0 +1,40 @@ +from ... import create_app +import unittest +import json + +class LoginTestCase(unittest.TestCase): + """ + test class for the registration endpoint + """ + def setUp(self): + create_app().testing = True + self.app = create_app().test_client() + self.mock_data = { + 'email' : 'test@chocoly.com', + 'password' : 'balerion' + } + self.not_user_data = { + 'email' : 'not_user@chocoly.com', + 'password' : 'silmarillion' + } + + def test_user_signin(self): + #test if a registered user can log in + res = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') + self.assertEqual(res.status_code, 201) + signin_res = self.app.post('/auth/v1/login', data=json.dumps(self.mock_data), content_type='application/json') + result = json.loads(signin_res.data) + self.assertEqual(result['message'], "Successfully logged in") + self.assertEqual(signin_res.status_code, 200) + self.assertTrue(result['authentication token']) + + def test_non_registered_user(self): + #test that unregistered user cannot log in + res = self.app.post('/auth/v1/login', data=json.dumps(self.mock_data), content_type='application/json') + result = json.loads(res.data) + self.assertEqual(res.status_code, 500) + + +if __name__ == "__main__": + unittest.main() + \ No newline at end of file diff --git a/app/tests/v1/test_registration.py b/app/tests/v1/test_register.py similarity index 81% rename from app/tests/v1/test_registration.py rename to app/tests/v1/test_register.py index 2a1600f..9543e51 100644 --- a/app/tests/v1/test_registration.py +++ b/app/tests/v1/test_register.py @@ -13,24 +13,25 @@ def setUp(self): 'email' : 'test@hotmail.com', 'password' : 'holy_water' } - + self.mock_data2 = { + 'email' : 'qarth@hotmail.com', + 'password' : 'jade_sea' + } + """ def test_signup(self): response2 = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') res = json.loads(response2.data) - self.assertEqual(response2.status_code, 201) self.assertEqual(res['message'], "you have successfully registered an account") """ def test_if_registered(self): - response1 = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') + response1 = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data2), content_type='application/json') self.assertEqual(response1.status_code, 201) - duplicate_signup = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') + duplicate_signup = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data2), content_type='application/json') self.assertEqual(duplicate_signup.status_code, 202) res = json.loads(duplicate_signup.data) self.assertEqual(res['message'], 'Account with provided email exists. please login') - - if __name__ == "__main__": unittest.main() \ No newline at end of file From 71d794e5f9ab526c5cf9a30f2762a5180dc47a8c Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 10:05:36 +0300 Subject: [PATCH 20/66] [starts #161834170]enable continuous integration --- .travis.yml | 9 +++++++++ requirements.txt | 8 ++++++++ 2 files changed, 17 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..867f847 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: python +python: + - "3.6.5" +# command to install dependencies +install: + - "pip install -r requirements.txt" +# command to run tests +script: + - "pytest" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 2c457bb..fc5cc68 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,9 +2,13 @@ aniso8601==4.0.1 astroid==2.0.4 atomicwrites==1.2.1 attrs==18.2.0 +certifi==2018.10.15 +chardet==3.0.4 Click==7.0 +coverage==4.0.3 Flask==1.0.2 Flask-RESTful==0.3.6 +idna==2.7 isort==4.3.4 itsdangerous==1.1.0 Jinja2==2.10 @@ -18,8 +22,12 @@ py==1.7.0 PyJWT==1.6.4 pylint==2.1.1 pytest==3.10.0 +python-coveralls==2.9.1 pytz==2018.7 +PyYAML==3.13 +requests==2.20.1 six==1.11.0 typed-ast==1.1.0 +urllib3==1.24.1 Werkzeug==0.14.1 wrapt==1.10.11 From df4bf08a0317b8777ff83c3503ebccf550fdf99d Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 10:11:49 +0300 Subject: [PATCH 21/66] add system site package --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 867f847..2863bd8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,9 @@ language: python python: - "3.6.5" # command to install dependencies +virtualenv: + system_site_packages: true + install: - "pip install -r requirements.txt" # command to run tests From 7ca8944bb9ab8351ae783df98f1a2f0e3171b25a Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 10:22:53 +0300 Subject: [PATCH 22/66] corrects the install script --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2863bd8..0cf95db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,9 @@ python: # command to install dependencies virtualenv: system_site_packages: true - + install: - - "pip install -r requirements.txt" + - pip install -r requirements.txt # command to run tests script: - - "pytest" \ No newline at end of file + - pytest \ No newline at end of file From 2be30edfdfcfd598fb4ab03cae95f0d6f58fbcff Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 10:25:59 +0300 Subject: [PATCH 23/66] update .travis.yml file --- .travis.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0cf95db..a33cc80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,15 @@ language: python python: - - "3.6.5" + - "2.6" + - "2.7" + - "3.3" + - "3.4" + - "3.5" + - "3.5-dev" # 3.5 development branch + - "3.6" + - "3.6-dev" # 3.6 development branch + - "3.7-dev" # 3.7 development branch # command to install dependencies -virtualenv: - system_site_packages: true - install: - pip install -r requirements.txt # command to run tests From 4014b589349b06eb3a231d290508417a0ea329fa Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 15:45:16 +0300 Subject: [PATCH 24/66] travis configuration --- .gitignore | 2 +- .travis.yml | 4 ---- app/__init__.py | 2 ++ app/auth/v1/models.py | 28 +++++++++++++++++++++++++++- requirements.txt | 2 +- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 1ce024a..89ed822 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ venv .vscode *.pytest_cache instance - +db_config.py diff --git a/.travis.yml b/.travis.yml index a33cc80..d9b9811 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,5 @@ language: python python: - - "2.6" - - "2.7" - - "3.3" - - "3.4" - "3.5" - "3.5-dev" # 3.5 development branch - "3.6" diff --git a/app/__init__.py b/app/__init__.py index d92f812..9493621 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -2,9 +2,11 @@ from instance.config import DevConfig from .api.v1 import version1 from .auth.v1 import auth +from db_config import create_tables, destroy_tables def create_app(): app = Flask(__name__) + create_tables() app.config.from_object(DevConfig) app.register_blueprint(version1) app.register_blueprint(auth) diff --git a/app/auth/v1/models.py b/app/auth/v1/models.py index 1dc1f6b..cd0bbd8 100644 --- a/app/auth/v1/models.py +++ b/app/auth/v1/models.py @@ -9,7 +9,33 @@ class for a data structure database """ def __init__(self): self.users = {} - self.orders = {} + self.orders = { + { + 'id' : 1, + 'order_name' : 'Ten boxes of dry ice', + 'pickup' : 'Ndananai', + 'dest' : 'Bomet', + 'pricing' : 'ksh. 3000', + 'user_id' : 4 + }, + { + 'id' : 2, + 'order_name' : 'four pink trousers', + 'pickup' : 'Mulutu', + 'dest' : 'Katheka', + 'pricing' : 'ksh. 1500', + 'user_id' : 7 + }, + { + 'id' : 3, + 'order_name' : 'three suitcases', + 'pickup' : 'Kathivo', + 'dest' : 'Matinyani', + 'pricing' : 'ksh. 200', + 'user_id' : 9 + } + + } self.user_no = 0 self.entry_no = 0 def drop(self): diff --git a/requirements.txt b/requirements.txt index fc5cc68..15aeca3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,8 +16,8 @@ lazy-object-proxy==1.3.1 MarkupSafe==1.0 mccabe==0.6.1 more-itertools==4.3.0 -pkg-resources==0.0.0 pluggy==0.8.0 +psycopg2-binary==2.7.6 py==1.7.0 PyJWT==1.6.4 pylint==2.1.1 From f6c77252f49a72399f875461ab61c3093208d80c Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 15:57:00 +0300 Subject: [PATCH 25/66] travis build correction --- .gitignore | 1 - .travis.yml | 21 ++++++++++++--------- instance/__init__.py | 0 instance/config.py | 7 +++++++ 4 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 instance/__init__.py create mode 100644 instance/config.py diff --git a/.gitignore b/.gitignore index 89ed822..7281740 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ venv .vscode *.pytest_cache -instance db_config.py diff --git a/.travis.yml b/.travis.yml index d9b9811..2a3b240 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,16 @@ language: python + python: - - "3.5" - - "3.5-dev" # 3.5 development branch - - "3.6" - - "3.6-dev" # 3.6 development branch - - "3.7-dev" # 3.7 development branch -# command to install dependencies + - "3.6.5" + install: - pip install -r requirements.txt -# command to run tests -script: - - pytest \ No newline at end of file + - pip install pytest + +script: + - python -m pytest + +after_success: + - coveralls + +cache: pip \ No newline at end of file diff --git a/instance/__init__.py b/instance/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/instance/config.py b/instance/config.py new file mode 100644 index 0000000..d370e04 --- /dev/null +++ b/instance/config.py @@ -0,0 +1,7 @@ +class DevConfig: + """ + configuration class for development variables + """ + DEBUG = True + SECRET_KEY = '12asgRx-67fdfsh-bsghsdj-bdjd7678bd' + \ No newline at end of file From 490ff5d89ceda8ee36a0d9e200f0a7f5b01755c3 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 19:55:11 +0300 Subject: [PATCH 26/66] travis build trials --- app/__init__.py | 6 +++--- app/auth/v1/models.py | 3 +++ requirements.txt | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 9493621..53897f7 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -2,11 +2,11 @@ from instance.config import DevConfig from .api.v1 import version1 from .auth.v1 import auth -from db_config import create_tables, destroy_tables +#from db_config import create_tables, destroy_tables def create_app(): - app = Flask(__name__) - create_tables() + app = Flask(__name__, instance_relative_config=True) + #create_tables() app.config.from_object(DevConfig) app.register_blueprint(version1) app.register_blueprint(auth) diff --git a/app/auth/v1/models.py b/app/auth/v1/models.py index cd0bbd8..27cd810 100644 --- a/app/auth/v1/models.py +++ b/app/auth/v1/models.py @@ -9,6 +9,8 @@ class for a data structure database """ def __init__(self): self.users = {} + self.orders = {} + """ self.orders = { { 'id' : 1, @@ -36,6 +38,7 @@ def __init__(self): } } + """ self.user_no = 0 self.entry_no = 0 def drop(self): diff --git a/requirements.txt b/requirements.txt index 15aeca3..af83093 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,7 @@ lazy-object-proxy==1.3.1 MarkupSafe==1.0 mccabe==0.6.1 more-itertools==4.3.0 +pkg-resources==0.0.0 pluggy==0.8.0 psycopg2-binary==2.7.6 py==1.7.0 From 3197171d8c38f414e684df709be129b09df4ee59 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 20:02:08 +0300 Subject: [PATCH 27/66] travis build trials --- app/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 53897f7..fe9c30a 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,5 +1,4 @@ from flask import Flask, Blueprint -from instance.config import DevConfig from .api.v1 import version1 from .auth.v1 import auth #from db_config import create_tables, destroy_tables @@ -7,7 +6,7 @@ def create_app(): app = Flask(__name__, instance_relative_config=True) #create_tables() - app.config.from_object(DevConfig) + app.config.from_pyfile('config.py') app.register_blueprint(version1) app.register_blueprint(auth) From 10742fdf5de9652b10fbba2798083733c18989b3 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 21:10:38 +0300 Subject: [PATCH 28/66] travis build trial --- .travis.yml | 2 +- app/auth/v1/models.py | 29 ----------------------------- app/auth/v1/views.py | 3 +-- app/tests/v1/test_login.py | 4 ++-- 4 files changed, 4 insertions(+), 34 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a3b240..dbabf89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ install: - pip install pytest script: - - python -m pytest + - pytest after_success: - coveralls diff --git a/app/auth/v1/models.py b/app/auth/v1/models.py index 27cd810..1dc1f6b 100644 --- a/app/auth/v1/models.py +++ b/app/auth/v1/models.py @@ -10,35 +10,6 @@ class for a data structure database def __init__(self): self.users = {} self.orders = {} - """ - self.orders = { - { - 'id' : 1, - 'order_name' : 'Ten boxes of dry ice', - 'pickup' : 'Ndananai', - 'dest' : 'Bomet', - 'pricing' : 'ksh. 3000', - 'user_id' : 4 - }, - { - 'id' : 2, - 'order_name' : 'four pink trousers', - 'pickup' : 'Mulutu', - 'dest' : 'Katheka', - 'pricing' : 'ksh. 1500', - 'user_id' : 7 - }, - { - 'id' : 3, - 'order_name' : 'three suitcases', - 'pickup' : 'Kathivo', - 'dest' : 'Matinyani', - 'pricing' : 'ksh. 200', - 'user_id' : 9 - } - - } - """ self.user_no = 0 self.entry_no = 0 def drop(self): diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index 3a7fccb..528b4ad 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -40,8 +40,7 @@ def post(self): auth_token = user.generate_token(user_id) if auth_token: response = { - 'message' : 'Successfully logged in', - 'authentication token' : auth_token.decode() + 'message' : 'Successfully logged in and token generated' } return make_response(jsonify(response), 200) else: diff --git a/app/tests/v1/test_login.py b/app/tests/v1/test_login.py index 3ee73e4..01f90cc 100644 --- a/app/tests/v1/test_login.py +++ b/app/tests/v1/test_login.py @@ -24,9 +24,9 @@ def test_user_signin(self): self.assertEqual(res.status_code, 201) signin_res = self.app.post('/auth/v1/login', data=json.dumps(self.mock_data), content_type='application/json') result = json.loads(signin_res.data) - self.assertEqual(result['message'], "Successfully logged in") + # self.assertEqual(result['message'], 'Successfully logged in') self.assertEqual(signin_res.status_code, 200) - self.assertTrue(result['authentication token']) + self.assertTrue(result) def test_non_registered_user(self): #test that unregistered user cannot log in From 2d3bf8066e6e767ce83756dd2b80ebb278f13565 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 21:15:09 +0300 Subject: [PATCH 29/66] travis build trial --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index af83093..15aeca3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,6 @@ lazy-object-proxy==1.3.1 MarkupSafe==1.0 mccabe==0.6.1 more-itertools==4.3.0 -pkg-resources==0.0.0 pluggy==0.8.0 psycopg2-binary==2.7.6 py==1.7.0 From d383adb8acf4ed91c4abaf97485c0ff09762d862 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 22:05:37 +0300 Subject: [PATCH 30/66] [starts #161850180] setup heroku Procfile --- Procfile | 1 + requirements.txt | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 Procfile diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..ee8e637 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: gunicorn deploy:app \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 15aeca3..884bde3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,7 @@ Click==7.0 coverage==4.0.3 Flask==1.0.2 Flask-RESTful==0.3.6 +gunicorn==19.9.0 idna==2.7 isort==4.3.4 itsdangerous==1.1.0 @@ -16,6 +17,7 @@ lazy-object-proxy==1.3.1 MarkupSafe==1.0 mccabe==0.6.1 more-itertools==4.3.0 +pkg-resources==0.0.0 pluggy==0.8.0 psycopg2-binary==2.7.6 py==1.7.0 From 284ee500d489cd013cefae2f47031b2451daae73 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 22:55:45 +0300 Subject: [PATCH 31/66] add runtime.txt --- Procfile | 2 +- runtime.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 runtime.txt diff --git a/Procfile b/Procfile index ee8e637..8001d1a 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: gunicorn deploy:app \ No newline at end of file +web: gunicorn app:app \ No newline at end of file diff --git a/runtime.txt b/runtime.txt new file mode 100644 index 0000000..486fcce --- /dev/null +++ b/runtime.txt @@ -0,0 +1 @@ +python-3.6.5 From cb7780726ac1a628b8f75e7aa197723f195f4266 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 23:21:13 +0300 Subject: [PATCH 32/66] Edit Profile --- Procfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Procfile b/Procfile index 8001d1a..80a980e 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: gunicorn app:app \ No newline at end of file +web: gunicorn run:app \ No newline at end of file From 8894c8dee662cd9d9ced9309cb68d048d037ea23 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Fri, 9 Nov 2018 23:26:22 +0300 Subject: [PATCH 33/66] Add port to Procfile --- Procfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Procfile b/Procfile index 80a980e..3c005ef 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: gunicorn run:app \ No newline at end of file +web: gunicorn -b :$PORT run:app \ No newline at end of file From 2d9886185c49eb3adff2a6c8bb6f3530460e70bd Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sat, 10 Nov 2018 09:55:33 +0300 Subject: [PATCH 34/66] Add covergae script in travis.yml --- .coverage | 1 + .travis.yml | 5 +++-- requirements.txt | 35 ----------------------------------- 3 files changed, 4 insertions(+), 37 deletions(-) create mode 100644 .coverage diff --git a/.coverage b/.coverage new file mode 100644 index 0000000..4bb129f --- /dev/null +++ b/.coverage @@ -0,0 +1 @@ +!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,26,36,39,40,50,53,54,15,16,17,18,19,21,22,23,24,30,31,32,33,34,44,45,46,47,48,58,59,60,61,62],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,26,32,39,9,10,17,18,19,20,21,22,24,30,36,37,43,44,45],"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,36,37,38,51,53,55,10,11,12,14,15,16,18,19,20,39,40,41,43,45,23,26],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,22,31,42,52,64,13,14,16,17,18,19,35,36,37,38,39,40,46,47,48,49,50,26,27,28,29,56,57,58,59,60],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34],"/home/ipaullly/dev/sendIT/app/db_config.py":[]}} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index dbabf89..93816bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,10 @@ install: - pip install pytest script: - - pytest + - python -m pytest --cov-report term-missing --cov=app + after_success: - coveralls -cache: pip \ No newline at end of file +cache: pip diff --git a/requirements.txt b/requirements.txt index 884bde3..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,35 +0,0 @@ -aniso8601==4.0.1 -astroid==2.0.4 -atomicwrites==1.2.1 -attrs==18.2.0 -certifi==2018.10.15 -chardet==3.0.4 -Click==7.0 -coverage==4.0.3 -Flask==1.0.2 -Flask-RESTful==0.3.6 -gunicorn==19.9.0 -idna==2.7 -isort==4.3.4 -itsdangerous==1.1.0 -Jinja2==2.10 -lazy-object-proxy==1.3.1 -MarkupSafe==1.0 -mccabe==0.6.1 -more-itertools==4.3.0 -pkg-resources==0.0.0 -pluggy==0.8.0 -psycopg2-binary==2.7.6 -py==1.7.0 -PyJWT==1.6.4 -pylint==2.1.1 -pytest==3.10.0 -python-coveralls==2.9.1 -pytz==2018.7 -PyYAML==3.13 -requests==2.20.1 -six==1.11.0 -typed-ast==1.1.0 -urllib3==1.24.1 -Werkzeug==0.14.1 -wrapt==1.10.11 From ea32f029dba3f595d8cfc77a771c4b49f6fae9de Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sat, 10 Nov 2018 11:08:28 +0300 Subject: [PATCH 35/66] [starts #161858618] create GET orders from a single user --- .travis.yml | 2 +- app/api/v1/__init__.py | 3 ++- app/api/v1/models.py | 12 ++++++++++-- app/api/v1/views.py | 14 +++++++++++++- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93816bc..65be951 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ install: - pip install pytest script: - - python -m pytest --cov-report term-missing --cov=app + - pytest --cov-report term-missing --cov=app after_success: diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py index deb2096..c251c17 100644 --- a/app/api/v1/__init__.py +++ b/app/api/v1/__init__.py @@ -1,6 +1,6 @@ from flask import Blueprint from flask_restful import Api -from .views import ParcelList, IndividualParcel, CancelParcel +from .views import ParcelList, IndividualParcel, CancelParcel, UserOrders version1 = Blueprint('v1', __name__, url_prefix="/api/v1") @@ -8,4 +8,5 @@ api.add_resource(ParcelList, '/parcels') api.add_resource(IndividualParcel, '/parcels/') +api.add_resource(UserOrders, '/user//parcels') api.add_resource(CancelParcel, '/parcels//cancel') diff --git a/app/api/v1/models.py b/app/api/v1/models.py index f863b58..fee0f79 100644 --- a/app/api/v1/models.py +++ b/app/api/v1/models.py @@ -9,7 +9,7 @@ def __init__(self): self.db = parcels self.parcel_status = 'pending' - def create_order(self, item, pickup, dest, pricing): + def create_order(self, item, pickup, dest, pricing, username): """ instance method to generate new entry into delivery orders list """ @@ -19,6 +19,7 @@ def create_order(self, item, pickup, dest, pricing): "pickupLocation" : pickup, "destination" : dest, "pricing" : pricing, + "authorId" : username, "status" : self.parcel_status } self.db.append(payload) @@ -43,4 +44,11 @@ def cancel_order(self, ParcelID): parcel_to_cancel = [parc for parc in self.db if parc['id'] == ParcelID] parcel_to_cancel[0]['status'] = 'cancelled' return parcel_to_cancel - \ No newline at end of file + + def get_orders_by_user(self, AuthorID): + """ + retrieve all orders by a specific user given her/his username + """ + user_orders = [parc for parc in self.db if parc['authorId'] == AuthorID][0] + return user_orders + diff --git a/app/api/v1/views.py b/app/api/v1/views.py index e50a6c5..c7ed800 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -17,8 +17,9 @@ def post(self): pickup = data['pickup'] dest = data['dest'] pricing = data['pricing'] + author = data['username'] - order.create_order(item, pickup, dest, pricing) + order.create_order(item, pickup, dest, pricing, author) return make_response(jsonify({ "message" : "delivery order created successfully" }), 201) @@ -47,6 +48,17 @@ def get(self, id): "order" : single }), 200) +class UserOrders(Resource): + """ + class for endpoint that restrieves all the orders made by a specific user + """ + def get(self, id): + user_orders = order.get_orders_by_user(id) + return make_response(jsonify({ + "message" : "Ok", + "orders by single user" : user_orders + }), 200) + class CancelParcel(Resource): """ class for endpoint to cancel parcel order From 7e532851b1ee7a9600f1b69d779c5c1637cf14e8 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sat, 10 Nov 2018 11:48:39 +0300 Subject: [PATCH 36/66] [finishes #161858618] add test for retrieving orders by a specific user --- app/tests/v1/test_parcels.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/tests/v1/test_parcels.py b/app/tests/v1/test_parcels.py index b408742..7f41e7c 100644 --- a/app/tests/v1/test_parcels.py +++ b/app/tests/v1/test_parcels.py @@ -16,7 +16,8 @@ def setUp(self): "item" : "seven ballons", "pickup" : "Biashara street", "dest" : "Kikuyu town", - "pricing": "250 ksh" + "pricing": "250 ksh", + "username" : "barnabas" } def test_POST_create_delivery_order(self): @@ -49,6 +50,16 @@ def test_GET_single_delivery_order(self): self.assertEqual(result.status_code, 200) self.assertIn('seven ballons', str(result.data)) + def test_GET_orders_by_single_user(self): + """ + Test if API can retrieve orders made by a spefic user + """ + response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') + self.assertEqual(response.status_code, 201) + res = self.app.get('/api/v1/user/barnabas/parcels') + self.assertEqual(res.status_code, 200) + self.assertIn('orders by single user', str(res.data)) + def test_PUT_cancel_delivery_order(self): """ Test if API can cancel order by changing order status From fbce096b3147c80d8f72989109e6aa025e1383c3 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sat, 10 Nov 2018 16:23:57 +0300 Subject: [PATCH 37/66] update README.md --- .travis.yml | 2 +- Procfile | 2 +- README.md | 70 ++++++++++++++++++++++++++++++++++++ app/tests/v1/test_parcels.py | 2 +- 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 65be951..fb0d0df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ install: - pip install pytest script: - - pytest --cov-report term-missing --cov=app + - pytest #--cov-report term-missing --cov=app after_success: diff --git a/Procfile b/Procfile index 3c005ef..62e430a 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: gunicorn -b :$PORT run:app \ No newline at end of file +web: gunicorn 'app:create_app()' \ No newline at end of file diff --git a/README.md b/README.md index 5970e9f..1e57ba0 100644 --- a/README.md +++ b/README.md @@ -1 +1,71 @@ # sendIT + +The sendIT app is built using flask to make RESTful APIs to achieve basic functionalities for the app + +## RESTful API Endpoints for sendIT + + +| Method | Endpoint | Description | +| ------------- | ------------- | ------------- | +| `POST` | `/api/v1/parcels` | Create a new parcel order | +| `GET` | `/api/v1/parcels` | Get a all parcel delivery orders | +| `GET` | `/api/v1/parcels/` | Get a single delivery order by id | +| `POST` | `/auth/v1/register` | Register a new user | +| `POST` | `/auth/v1/login` | log a user into account | +| `PUT` | `/api/v1/parcels//cancel` | Cancel a specific parcel delivery order | + + +# Development Configuration + +Ensure that you have python 3.6.5, pip and virtualenv running + +# Initial Setup + +Create a project directory in your local machine + +``` +mkdir sendIT +``` + +Move into your directory: + +``` +cd sendIT +``` + +## Initialize a virtual python Environment to House all your Dependencies + +create the virtual environment + +``` +python3 -p virtualenv venv +``` +activate the environment before cloning the project from github + +``` +source venv/bin/activate +``` + +## Clone and Configure a the sendIT flask Project + +Provided you have a github account, login before entering the command to create a local copy of the repo + +``` +git clone https://github.com/ipaullly/sendIT.git +``` + +Next, install the requirements by typing: + +``` +pip install -r requirements.txt +``` + +## Unit Testing +To test the endpointsensure that the following tools are available the follow steps below + ### Tools: + Postman + +### Commands + The application was tested using `pytest` and coverage. run the following command + + pytest --with-coverage --cover-package=app && coverage report diff --git a/app/tests/v1/test_parcels.py b/app/tests/v1/test_parcels.py index 7f41e7c..0ebf2ee 100644 --- a/app/tests/v1/test_parcels.py +++ b/app/tests/v1/test_parcels.py @@ -59,7 +59,7 @@ def test_GET_orders_by_single_user(self): res = self.app.get('/api/v1/user/barnabas/parcels') self.assertEqual(res.status_code, 200) self.assertIn('orders by single user', str(res.data)) - + def test_PUT_cancel_delivery_order(self): """ Test if API can cancel order by changing order status From db77b9ac0009e5cd2a7c58ad8210ed4709b90d95 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sun, 11 Nov 2018 12:23:06 +0300 Subject: [PATCH 38/66] add code climate badges --- .coverage | 2 +- .travis.yml | 7 +++---- README.md | 9 +++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.coverage b/.coverage index 4bb129f..4090f9d 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,26,36,39,40,50,53,54,15,16,17,18,19,21,22,23,24,30,31,32,33,34,44,45,46,47,48,58,59,60,61,62],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,26,32,39,9,10,17,18,19,20,21,22,24,30,36,37,43,44,45],"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,36,37,38,51,53,55,10,11,12,14,15,16,18,19,20,39,40,41,43,45,23,26],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,22,31,42,52,64,13,14,16,17,18,19,35,36,37,38,39,40,46,47,48,49,50,26,27,28,29,56,57,58,59,60],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34],"/home/ipaullly/dev/sendIT/app/db_config.py":[]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46],"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,36,37,38,51,53,55,10,11,12,14,15,16,18,19,20,39,40,41,43,45,23,26],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34],"/home/ipaullly/dev/sendIT/app/db_config.py":[]}} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index fb0d0df..0450db8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,13 @@ language: python python: - - "3.6.5" + - 3.6.5 install: - - pip install -r requirements.txt - - pip install pytest + - pip install -r requirements.txt script: - - pytest #--cov-report term-missing --cov=app + - pytest --cov-report term-missing --cov=app after_success: diff --git a/README.md b/README.md index 1e57ba0..82d923f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # sendIT - +[![Maintainability](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/maintainability)](https://codeclimate.com/github/ipaullly/sendIT/maintainability) +[![Test Coverage](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/test_coverage)](https://codeclimate.com/github/ipaullly/sendIT/test_coverage) The sendIT app is built using flask to make RESTful APIs to achieve basic functionalities for the app ## RESTful API Endpoints for sendIT @@ -60,12 +61,12 @@ Next, install the requirements by typing: pip install -r requirements.txt ``` -## Unit Testing +## Testing To test the endpointsensure that the following tools are available the follow steps below ### Tools: Postman ### Commands - The application was tested using `pytest` and coverage. run the following command + The application was tested using `pytest` and coveralls. - pytest --with-coverage --cover-package=app && coverage report + pytest --cov-report term-missing --cov=app From 7583551f0ec2af94d3ff0eb443edb6b3213f3362 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sun, 11 Nov 2018 12:47:18 +0300 Subject: [PATCH 39/66] Add nosetest command to .travis.yml --- .coverage | 2 +- .gitignore | 1 + .travis.yml | 9 ++------- requirements.txt | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/.coverage b/.coverage index 4090f9d..89a3d6e 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46],"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,36,37,38,51,53,55,10,11,12,14,15,16,18,19,20,39,40,41,43,45,23,26],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34],"/home/ipaullly/dev/sendIT/app/db_config.py":[]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34],"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/db_config.py":[],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,36,37,38,51,53,55,10,11,12,14,15,16,18,19,20,39,40,41,43,45,23,26],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46]}} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7281740..6ab5fbf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ venv .vscode *.pytest_cache db_config.py +*__init__.pyc \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 0450db8..45e827f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,11 @@ language: python - python: - 3.6.5 - install: - pip install -r requirements.txt - + - pip install coveralls script: - - pytest --cov-report term-missing --cov=app - - + - nosetests --with-coverage --cover-package=app after_success: - coveralls - cache: pip diff --git a/requirements.txt b/requirements.txt index e69de29..bf70e8f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,38 @@ +aniso8601==4.0.1 +astroid==2.0.4 +atomicwrites==1.2.1 +attrs==18.2.0 +certifi==2018.10.15 +chardet==3.0.4 +Click==7.0 +coverage==4.5.1 +coveralls==1.5.1 +docopt==0.6.2 +Flask==1.0.2 +Flask-RESTful==0.3.6 +gunicorn==19.9.0 +idna==2.7 +isort==4.3.4 +itsdangerous==1.1.0 +Jinja2==2.10 +lazy-object-proxy==1.3.1 +MarkupSafe==1.0 +mccabe==0.6.1 +more-itertools==4.3.0 +pkg-resources==0.0.0 +pluggy==0.8.0 +psycopg2-binary==2.7.6 +py==1.7.0 +PyJWT==1.6.4 +pylint==2.1.1 +pytest==3.10.0 +pytest-cov==2.6.0 +python-coveralls==2.9.1 +pytz==2018.7 +PyYAML==3.13 +requests==2.20.1 +six==1.11.0 +typed-ast==1.1.0 +urllib3==1.24.1 +Werkzeug==0.14.1 +wrapt==1.10.11 From c3258f01f6772ea05d7de09d6a3d962a7d967295 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sun, 11 Nov 2018 12:51:11 +0300 Subject: [PATCH 40/66] delete pkg-resources from requirements.txt --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bf70e8f..57df97a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,6 @@ lazy-object-proxy==1.3.1 MarkupSafe==1.0 mccabe==0.6.1 more-itertools==4.3.0 -pkg-resources==0.0.0 pluggy==0.8.0 psycopg2-binary==2.7.6 py==1.7.0 From effae76cfc364c81b6c49411b6712206ae40e960 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sun, 11 Nov 2018 12:59:45 +0300 Subject: [PATCH 41/66] add update pip command to .travis.yml --- .coverage | 2 +- .travis.yml | 2 +- README.md | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.coverage b/.coverage index 89a3d6e..deaae71 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34],"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/db_config.py":[],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,36,37,38,51,53,55,10,11,12,14,15,16,18,19,20,39,40,41,43,45,23,26],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34],"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/db_config.py":[],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,36,37,38,51,53,55,10,11,12,14,15,16,18,19,20,39,40,41,43,45,23,26],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46]}} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 45e827f..a0adfe6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: python python: - 3.6.5 install: - - pip install -r requirements.txt + - pip install --upgrade pip && pip install -r requirements.txt - pip install coveralls script: - nosetests --with-coverage --cover-package=app diff --git a/README.md b/README.md index 82d923f..c04f163 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # sendIT [![Maintainability](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/maintainability)](https://codeclimate.com/github/ipaullly/sendIT/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/test_coverage)](https://codeclimate.com/github/ipaullly/sendIT/test_coverage) + The sendIT app is built using flask to make RESTful APIs to achieve basic functionalities for the app ## RESTful API Endpoints for sendIT From 52965be6a5972f7ceb36134616a1973a8e91d05f Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sun, 11 Nov 2018 13:03:21 +0300 Subject: [PATCH 42/66] Travis trial 27 --- .gitignore | 1 - app/__init__.pyc | Bin 0 -> 656 bytes instance/__init__.pyc | Bin 0 -> 133 bytes 3 files changed, 1 deletion(-) create mode 100644 app/__init__.pyc create mode 100644 instance/__init__.pyc diff --git a/.gitignore b/.gitignore index 6ab5fbf..7281740 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ venv .vscode *.pytest_cache db_config.py -*__init__.pyc \ No newline at end of file diff --git a/app/__init__.pyc b/app/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0419f2d309edf3c7d5c5ea4394bcdf6e47a671e7 GIT binary patch literal 656 zcmbV}%}N6?5XUFG+Yc*+;z4|b_0pwxk)j}YDYETpJ%rdz+tlm_o7qA^PxZBY9G}1k z(3xF}o(;)l{*z(yo5cSd4j$e=9+&VlJldzU+%1`urT`0&2}lHF9wZ)!)PvLq>q8bm z60|x1+kvbLNtbj7-T;ywq+OVYJ*s2AXoOrEJ7n&xa?f}|-i@twS(zM-AQiH~KAD}a zoGJ228wn_)YTPuCoWlX;b5k-%Q!poba1i1Z;00jo!!`gSJqQr2JAmE4qIVSY(5E6Z zydZ0GhbmucS!t`#?6h1K`O2&vv$pQI+=omU(`s3z%vGkPM5bC)wWf=X*?3Csswy&B z?pMZYJR@D{wQ;B``E=|)=BJ67qivWyRhA)b&=_|~UbHDP9hp+q*4llP>Rse?p58Aa z%8jHnxj`uj5C@dKth7Qc>4 Date: Sun, 11 Nov 2018 13:10:11 +0300 Subject: [PATCH 43/66] travis integration trial 29 --- app/auth/v1/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/auth/v1/__init__.py b/app/auth/v1/__init__.py index 6b41930..28921d7 100644 --- a/app/auth/v1/__init__.py +++ b/app/auth/v1/__init__.py @@ -2,7 +2,7 @@ from flask_restful import Api from .views import Registration, SignIn -auth = Blueprint('auth', __name__, url_prefix="/auth/v1") +auth = Blueprint('authV1', __name__, url_prefix="/auth/v1") api = Api(auth) From e55316aad279064188dab218092ddf4f95159bcc Mon Sep 17 00:00:00 2001 From: ipaullly Date: Sun, 11 Nov 2018 15:07:47 +0300 Subject: [PATCH 44/66] update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c04f163..74d5543 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # sendIT [![Maintainability](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/maintainability)](https://codeclimate.com/github/ipaullly/sendIT/maintainability) -[![Test Coverage](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/test_coverage)](https://codeclimate.com/github/ipaullly/sendIT/test_coverage) +[![Test Coverage](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/test_coverage)](https://codeclimate.com/github/ipaullly/sendIT/test_coverage)[![Build Status](https://travis-ci.com/ipaullly/sendIT.svg?branch=ft-GET-user-orders-161858618)](https://travis-ci.com/ipaullly/sendIT) The sendIT app is built using flask to make RESTful APIs to achieve basic functionalities for the app From 32c468c8c07c7d6c35913b8a59177340f7d7715c Mon Sep 17 00:00:00 2001 From: ipaullly Date: Mon, 12 Nov 2018 10:01:48 +0300 Subject: [PATCH 45/66] add codecov to .travis.yml --- .coverage | 2 +- .travis.yml | 13 +++++++++---- README.md | 2 +- app/auth/v1/views.py | 1 + requirements.txt | 1 + 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.coverage b/.coverage index deaae71..eb7b567 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34],"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/db_config.py":[],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,36,37,38,51,53,55,10,11,12,14,15,16,18,19,20,39,40,41,43,45,23,26],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46],"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,37,38,39,52,54,56,10,11,12,14,15,16,18,19,20,40,41,42,44,46,23,26],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34]}} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index a0adfe6..cdebdfe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,16 @@ language: python python: - - 3.6.5 + - "3.6.5" install: - pip install --upgrade pip && pip install -r requirements.txt - pip install coveralls + - pip install pytest script: - - nosetests --with-coverage --cover-package=app -after_success: + - pytest + +after_script: - coveralls -cache: pip + +after_success: + - codecov + diff --git a/README.md b/README.md index 74d5543..94a1d70 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # sendIT [![Maintainability](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/maintainability)](https://codeclimate.com/github/ipaullly/sendIT/maintainability) -[![Test Coverage](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/test_coverage)](https://codeclimate.com/github/ipaullly/sendIT/test_coverage)[![Build Status](https://travis-ci.com/ipaullly/sendIT.svg?branch=ft-GET-user-orders-161858618)](https://travis-ci.com/ipaullly/sendIT) +[![Test Coverage](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/test_coverage)](https://codeclimate.com/github/ipaullly/sendIT/test_coverage) [![Build Status](https://travis-ci.com/ipaullly/sendIT.svg?branch=ft-GET-user-orders-161858618)](https://travis-ci.com/ipaullly/sendIT) [![Coverage Status](https://coveralls.io/repos/github/ipaullly/sendIT/badge.svg?branch=master)](https://coveralls.io/github/ipaullly/sendIT?branch=master) The sendIT app is built using flask to make RESTful APIs to achieve basic functionalities for the app diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index 528b4ad..4ba270f 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -33,6 +33,7 @@ def post(self): data = request.get_json() email = data['email'] password = data['password'] + try: user = User.get_user_by_email(email) user_id = user.id diff --git a/requirements.txt b/requirements.txt index 57df97a..bf70e8f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,6 +19,7 @@ lazy-object-proxy==1.3.1 MarkupSafe==1.0 mccabe==0.6.1 more-itertools==4.3.0 +pkg-resources==0.0.0 pluggy==0.8.0 psycopg2-binary==2.7.6 py==1.7.0 From 81177dc92ef5d5ee8d4256fdd7e4ae4ebeb092dc Mon Sep 17 00:00:00 2001 From: ipaullly Date: Mon, 12 Nov 2018 10:16:55 +0300 Subject: [PATCH 46/66] remove pkg-resources==0.0.0 --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index bf70e8f..57df97a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,6 @@ lazy-object-proxy==1.3.1 MarkupSafe==1.0 mccabe==0.6.1 more-itertools==4.3.0 -pkg-resources==0.0.0 pluggy==0.8.0 psycopg2-binary==2.7.6 py==1.7.0 From 8834aad925f167e3f7d1d321d3b93b4f63d59b26 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Mon, 12 Nov 2018 16:26:53 +0300 Subject: [PATCH 47/66] add codecov token --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 94a1d70..15861ad 100644 --- a/README.md +++ b/README.md @@ -70,4 +70,4 @@ To test the endpointsensure that the following tools are available the follow st ### Commands The application was tested using `pytest` and coveralls. - pytest --cov-report term-missing --cov=app + pytest --cov app From 7571ed0c4691880348789c609f03bf317ba3180a Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 13 Nov 2018 14:30:21 +0300 Subject: [PATCH 48/66] [starts #161911823] add assert statement to check signup endpoint --- .coverage | 2 +- app/api/v1/views.py | 15 +++++++++++---- app/auth/v1/views.py | 4 ++-- app/tests/v1/test_login.py | 3 ++- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.coverage b/.coverage index eb7b567..8a9092b 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46],"/home/ipaullly/dev/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,37,38,39,52,54,56,10,11,12,14,15,16,18,19,20,40,41,42,44,46,23,26],"/home/ipaullly/dev/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,38,10,11,13,14,17,18,33,34,35,23,24,25,26,28,29],"/home/ipaullly/dev/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,37,38,39,52,54,56,10,11,12,14,15,16,18,19,20,40,41,42,44,46,23,26],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,39,10,11,13,14,17,18,33,34,35,36,23,24,25,26,27,28,29],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34]}} \ No newline at end of file diff --git a/app/api/v1/views.py b/app/api/v1/views.py index c7ed800..3bd1ab1 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -19,10 +19,17 @@ def post(self): pricing = data['pricing'] author = data['username'] - order.create_order(item, pickup, dest, pricing, author) - return make_response(jsonify({ - "message" : "delivery order created successfully" - }), 201) + try: + + order.create_order(item, pickup, dest, pricing, author) + return make_response(jsonify({ + "message" : "delivery order created successfully" + }), 201) + + except Exception: + return make_response(jsonify({ + "message" : "wrong input format" + }), 400) def get(self): """ diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index 4ba270f..8145948 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -49,8 +49,8 @@ def post(self): 'message' : 'User with email already exists, please login' } return make_response(jsonify(response), 401) - except Exception as err: + except Exception: response = { - 'message' : str(err) + 'message' : 'wrong login credentials, please create account' } return make_response(jsonify(response), 500) \ No newline at end of file diff --git a/app/tests/v1/test_login.py b/app/tests/v1/test_login.py index 01f90cc..6688cea 100644 --- a/app/tests/v1/test_login.py +++ b/app/tests/v1/test_login.py @@ -24,7 +24,7 @@ def test_user_signin(self): self.assertEqual(res.status_code, 201) signin_res = self.app.post('/auth/v1/login', data=json.dumps(self.mock_data), content_type='application/json') result = json.loads(signin_res.data) - # self.assertEqual(result['message'], 'Successfully logged in') + self.assertIn('Successfully logged in', str(result)) self.assertEqual(signin_res.status_code, 200) self.assertTrue(result) @@ -32,6 +32,7 @@ def test_non_registered_user(self): #test that unregistered user cannot log in res = self.app.post('/auth/v1/login', data=json.dumps(self.mock_data), content_type='application/json') result = json.loads(res.data) + self.assertIn('wrong login credentials', str(result)) self.assertEqual(res.status_code, 500) From 290fa1456c921120b940a6035de73d7fe4e1e1c7 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 13 Nov 2018 14:45:40 +0300 Subject: [PATCH 49/66] edit assertIn args for login/register api tests --- app/auth/v1/views.py | 4 ++-- app/tests/v1/test_login.py | 2 +- app/tests/v1/test_register.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index 8145948..8a7e45b 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -23,7 +23,7 @@ def post(self): 'message': 'Account with provided email exists. please login' } - return make_response((jsonify(response)), 202) + return make_response(jsonify(response), 202) class SignIn(Resource): """ @@ -51,6 +51,6 @@ def post(self): return make_response(jsonify(response), 401) except Exception: response = { - 'message' : 'wrong login credentials, please create account' + 'message' : 'wrong input format, please enter details again' } return make_response(jsonify(response), 500) \ No newline at end of file diff --git a/app/tests/v1/test_login.py b/app/tests/v1/test_login.py index 6688cea..35de6a3 100644 --- a/app/tests/v1/test_login.py +++ b/app/tests/v1/test_login.py @@ -32,7 +32,7 @@ def test_non_registered_user(self): #test that unregistered user cannot log in res = self.app.post('/auth/v1/login', data=json.dumps(self.mock_data), content_type='application/json') result = json.loads(res.data) - self.assertIn('wrong login credentials', str(result)) + self.assertIn("{'message': 'wrong input format, please enter details again'}", str(result)) self.assertEqual(res.status_code, 500) diff --git a/app/tests/v1/test_register.py b/app/tests/v1/test_register.py index 9543e51..ff1c012 100644 --- a/app/tests/v1/test_register.py +++ b/app/tests/v1/test_register.py @@ -18,12 +18,12 @@ def setUp(self): 'password' : 'jade_sea' } - """ + def test_signup(self): response2 = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data), content_type='application/json') res = json.loads(response2.data) - self.assertEqual(res['message'], "you have successfully registered an account") - """ + self.assertEqual("{'message': 'you have successfully registered an account'}", str(res)) + def test_if_registered(self): response1 = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data2), content_type='application/json') @@ -31,7 +31,7 @@ def test_if_registered(self): duplicate_signup = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data2), content_type='application/json') self.assertEqual(duplicate_signup.status_code, 202) res = json.loads(duplicate_signup.data) - self.assertEqual(res['message'], 'Account with provided email exists. please login') + self.assertIn('Account with provided email exists. please login', str(res)) if __name__ == "__main__": unittest.main() \ No newline at end of file From fe13c7e4aa55d109afee35a83e396d26aca718c0 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 13 Nov 2018 15:54:41 +0300 Subject: [PATCH 50/66] [finishes #161911823] add test for empty strings and finish checking response messages --- .coverage | 2 +- app/api/v1/views.py | 15 +++++++++------ app/tests/v1/test_edgecases.py | 33 +++++++++++++++++++++++++++++++++ app/tests/v1/test_parcels.py | 2 +- 4 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 app/tests/v1/test_edgecases.py diff --git a/.coverage b/.coverage index 8a9092b..26da42c 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,27,37,40,41,51,54,55,62,65,66,15,16,17,18,19,20,22,23,24,25,31,32,33,34,35,56,57,58,59,60,45,46,47,48,49,70,71,72,73,74],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,37,38,39,52,54,56,10,11,12,14,15,16,18,19,20,40,41,42,44,46,23,26],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,39,10,11,13,14,17,18,33,34,35,36,23,24,25,26,27,28,29],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,28,36,10,11,13,14,17,18,29,30,31,32,33,34]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,37,47,50,51,61,64,65,72,75,76,15,16,17,18,19,20,22,23,24,32,33,34,35,25,28,29,30,31,41,42,43,44,45,66,67,68,69,70,55,56,57,58,59,80,81,82,83,84],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,37,38,39,52,54,56,10,11,12,14,15,16,18,19,20,40,41,42,44,46,23,26],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[1,2,3,5,8,9,23,32,13,14,16,17,18,19,20,27,28,29,30],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,39,10,11,13,14,17,18,33,34,35,36,23,24,25,26,27,28,29],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,22,28,36,10,11,13,14,17,18,29,30,31,32,33,34,23,24,25]}} \ No newline at end of file diff --git a/app/api/v1/views.py b/app/api/v1/views.py index 3bd1ab1..e7eedfe 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -20,12 +20,15 @@ def post(self): author = data['username'] try: - - order.create_order(item, pickup, dest, pricing, author) - return make_response(jsonify({ - "message" : "delivery order created successfully" - }), 201) - + if " " in item: + raise Exception + elif type(pricing) is not int: + raise Exception + else: + order.create_order(item, pickup, dest, pricing, author) + return make_response(jsonify({ + "message" : "delivery order created successfully" + }), 201) except Exception: return make_response(jsonify({ "message" : "wrong input format" diff --git a/app/tests/v1/test_edgecases.py b/app/tests/v1/test_edgecases.py new file mode 100644 index 0000000..eb342c2 --- /dev/null +++ b/app/tests/v1/test_edgecases.py @@ -0,0 +1,33 @@ +from ... import create_app +import unittest +import json + +class TestEdgeCases(unittest.TestCase): + """ + class for testing invalid input data and + """ + def setUp(self): + """ + Initialize app and define test variables + """ + create_app().testing = True + self.app = create_app().test_client() + self.dummy = { + "item" : " ", + "pickup" : "muranga", + "dest" : "house", + "pricing": 250, + "username" : "stanLee" + } + + def test_empty_strings_in_POST_create_order(self): + """ + Test whether API can create a new delivery order via POSt request + """ + response = self.app.post('/api/v1/parcels', data=json.dumps(self.dummy), content_type='application/json') + result = json.loads(response.data) + self.assertEqual(response.status_code, 400) + self.assertIn('wrong input format', str(result)) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/app/tests/v1/test_parcels.py b/app/tests/v1/test_parcels.py index 0ebf2ee..3b51d5b 100644 --- a/app/tests/v1/test_parcels.py +++ b/app/tests/v1/test_parcels.py @@ -16,7 +16,7 @@ def setUp(self): "item" : "seven ballons", "pickup" : "Biashara street", "dest" : "Kikuyu town", - "pricing": "250 ksh", + "pricing": 250, "username" : "barnabas" } From 31b405a64994b8c4bd2794075b05870e636b2dd0 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 13 Nov 2018 17:11:43 +0300 Subject: [PATCH 51/66] [starts #161920708] create utilities and move decode token function into it --- app/auth/v1/models.py | 16 ---------------- app/utilities/JWT_token.py | 18 ++++++++++++++++++ app/utilities/__init__.py | 0 3 files changed, 18 insertions(+), 16 deletions(-) create mode 100644 app/utilities/JWT_token.py create mode 100644 app/utilities/__init__.py diff --git a/app/auth/v1/models.py b/app/auth/v1/models.py index 1dc1f6b..fb4ff66 100644 --- a/app/auth/v1/models.py +++ b/app/auth/v1/models.py @@ -82,22 +82,6 @@ def generate_token(self, userID): return token except Exception as err: return str(err) - - @staticmethod - def decode_token(token): - """ - method to decode the token generated during login - """ - try: - #attempt to decode token using SECRET_KEY variable - payload = jwt.decode(token, current_app.config.get('SECRET_KEY')) - return payload['id'] - except jwt.ExpiredSignatureError: - # expired token returns an error string - return "Token expired. please login again to generate fresh token" - except jwt.InvalidTokenError: - #the token is not valid, throw error - return "Unworthy token. Please login to get fresh authorization" @classmethod def get_user_by_email(cls, email): diff --git a/app/utilities/JWT_token.py b/app/utilities/JWT_token.py new file mode 100644 index 0000000..82b6877 --- /dev/null +++ b/app/utilities/JWT_token.py @@ -0,0 +1,18 @@ +from flask import current_app +import jwt + + +def decode_token(token): + """ + method to decode the token generated during login + """ + try: + #attempt to decode token using SECRET_KEY variable + payload = jwt.decode(token, current_app.config.get('SECRET_KEY')) + return payload['id'] + except jwt.ExpiredSignatureError: + # expired token returns an error string + return "Token expired. please login again to generate fresh token" + except jwt.InvalidTokenError: + #the token is not valid, throw error + return "Unworthy token. Please login to get fresh authorization" \ No newline at end of file diff --git a/app/utilities/__init__.py b/app/utilities/__init__.py new file mode 100644 index 0000000..e69de29 From 70898e08ae134cf22e545be68bd575d34aa21512 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 13 Nov 2018 17:30:57 +0300 Subject: [PATCH 52/66] [starts #161921842] add scripts for code climate integration --- .travis.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cdebdfe..0b27c91 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ +env: + global: + - CC_TEST_REPORTER_ID=e6fc31601f7b6906c6ff9c0bfc5afb08d679e93ea89c315aaf6758c20bcdc274 language: python python: - "3.6.5" @@ -5,12 +8,15 @@ install: - pip install --upgrade pip && pip install -r requirements.txt - pip install coveralls - pip install pytest +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 script: - pytest - after_script: + - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT - coveralls - after_success: - codecov From fd2a6622ed364fe5a1012f79ac988cf9d4191f0f Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 13 Nov 2018 17:55:58 +0300 Subject: [PATCH 53/66] Try codecov integration --- .coverage | 2 +- .coveragerc | 13 +++++++++++++ .travis.yml | 3 ++- 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 .coveragerc diff --git a/.coverage b/.coverage index 26da42c..18f13e4 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[1,2,3,6,7,9,10,11,13],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[1,2,3,5,7,9,10,11,12],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[1,2,3,5,7,10,11,37,47,50,51,61,64,65,72,75,76,15,16,17,18,19,20,22,23,24,32,33,34,35,25,28,29,30,31,41,42,43,44,45,66,67,68,69,70,55,56,57,58,59,80,81,82,83,84],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[2,4,7,8,12,27,33,40,48,9,10,17,18,19,20,21,22,23,25,31,52,53,37,38,44,45,46],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[1,2,3,5,7,9,10],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[1,2,3,5,8,9,28,31,32,33,34,35,37,38,39,52,54,56,10,11,12,14,15,16,18,19,20,40,41,42,44,46,23,26],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[1,2,3,4,6,9,10,15,18,11,12,13,14,20,23,24,31,34,35,42,52,60,67,86,102,107,111,36,37,38,39,40,46,47,48,49,50,64,65,108,109,110,56,57,71,73,74,75,77,78,79,80,83,84],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[1],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[1,2,3,5,8,9,23,32,13,14,16,17,18,19,20,27,28,29,30],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[1,2,3,5,8,9,21,31,39,10,11,13,14,17,18,33,34,35,36,23,24,25,26,27,28,29],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[1,2,3,5,8,9,23,32,43,53,63,75,13,14,16,17,18,19,20,36,37,38,39,40,41,57,58,59,60,61,47,48,49,50,51,27,28,29,30,67,68,69,70,71],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[1,2,3,5,8,9,22,28,36,10,11,13,14,17,18,29,30,31,32,33,34,23,24,25]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"arcs":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[[-1,1],[1,2],[2,3],[3,6],[6,-1],[-6,7],[7,9],[9,10],[10,11],[11,13],[13,-6]],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,11],[11,12],[12,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[-7,7],[7,10],[10,11],[11,37],[37,-7],[7,47],[-47,47],[47,50],[50,51],[51,-47],[47,61],[-61,61],[61,64],[64,65],[65,-61],[61,72],[-72,72],[72,75],[75,76],[76,-72],[72,-1],[-11,15],[15,16],[16,17],[17,18],[18,19],[19,20],[20,22],[22,23],[23,24],[24,32],[32,33],[33,34],[34,35],[35,-11],[23,25],[25,28],[28,29],[29,30],[30,31],[31,-11],[-37,41],[41,42],[42,43],[43,44],[44,45],[45,-37],[-65,66],[66,67],[67,68],[68,69],[69,70],[70,-65],[-51,55],[55,56],[56,57],[57,58],[58,59],[59,-51],[-76,80],[80,81],[81,82],[82,83],[83,84],[84,-76]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[[-2,2],[2,4],[-4,4],[4,7],[7,8],[8,12],[12,27],[27,33],[33,40],[40,48],[48,-4],[4,-2],[-8,9],[9,10],[10,-8],[-12,17],[17,18],[18,19],[19,20],[20,21],[21,22],[22,23],[23,25],[25,-12],[-27,31],[31,-27],[-48,52],[-52,52],[52,52],[52,-52],[52,53],[53,-48],[-33,37],[-37,37],[37,37],[37,-37],[37,38],[38,-33],[-40,44],[-44,44],[44,44],[44,-44],[44,45],[45,46],[46,-40]],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,-5],[5,28],[-28,28],[28,31],[31,32],[32,-28],[28,-1],[-32,33],[33,34],[34,35],[35,37],[37,38],[38,39],[39,52],[52,54],[54,56],[56,-32],[-9,10],[10,11],[11,12],[12,14],[14,15],[15,16],[16,18],[18,19],[19,20],[20,-9],[39,40],[40,41],[41,42],[42,44],[44,46],[46,-32],[14,23],[23,26],[26,-9]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,15],[15,-6],[6,18],[-10,11],[11,12],[12,13],[13,14],[14,-10],[18,20],[-20,20],[20,23],[23,24],[24,-20],[20,31],[-31,31],[31,34],[34,35],[35,42],[42,52],[52,60],[60,67],[67,86],[86,-31],[31,-1],[-86,91],[91,95],[95,-86],[-35,36],[36,37],[37,38],[38,39],[39,40],[40,-35],[-42,46],[46,47],[47,48],[48,49],[49,50],[-60,64],[64,65],[-65,65],[65,65],[65,-65],[65,-60],[50,-42],[91,92],[92,93],[93,94],[94,-86],[-52,56],[56,57],[57,-52],[-67,71],[71,73],[73,74],[74,75],[75,77],[77,78],[78,79],[79,80],[80,83],[83,84],[84,-67],[93,91]],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,-5],[5,32],[32,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-23,27],[27,28],[28,29],[29,30],[30,-23]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,21],[21,31],[31,-5],[5,39],[39,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-31,33],[33,34],[34,35],[35,36],[36,-31],[-21,23],[23,24],[24,25],[25,26],[26,27],[27,28],[28,29],[29,-21]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,32],[32,43],[43,53],[53,63],[63,-5],[5,75],[75,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-32,36],[36,37],[37,38],[38,39],[39,40],[40,41],[41,-32],[-53,57],[57,58],[58,59],[59,60],[60,61],[61,-53],[-43,47],[47,48],[48,49],[49,50],[50,51],[51,-43],[-23,27],[27,28],[28,29],[29,30],[30,-23],[-63,67],[67,68],[68,69],[69,70],[70,71],[71,-63]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,22],[22,28],[28,-5],[5,36],[36,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-28,29],[29,30],[30,31],[31,32],[32,33],[33,34],[34,-28],[-22,23],[23,24],[24,25],[25,-22]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/__init__.py":[],"/home/ipaullly/dev/parcels/sendIT/app/utilities/JWT_token.py":[]}} \ No newline at end of file diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..a3caf3b --- /dev/null +++ b/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True +source = app + +[report] +exclude_lines = + if self.debug: + pragma: no cover + raise NotImplementedError + if __name__ == .__main__.: +ignore_errors = True +omit = + tests/* \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 0b27c91..ca2f18f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ python: install: - pip install --upgrade pip && pip install -r requirements.txt - pip install coveralls + - pip install codecov - pip install pytest before_script: - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter @@ -18,5 +19,5 @@ after_script: - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT - coveralls after_success: - - codecov + - codecov -t b1bc8af2-07e9-45e9-8824-c733282c6cea From 42e74bcfff118b3fe5ce58e6e8bf596caa2c8a21 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 13 Nov 2018 18:07:13 +0300 Subject: [PATCH 54/66] add coverage xml --- coverage.xml | 390 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 coverage.xml diff --git a/coverage.xml b/coverage.xml new file mode 100644 index 0000000..2da2130 --- /dev/null +++ b/coverage.xml @@ -0,0 +1,390 @@ + + + + + + /home/ipaullly/dev/parcels/sendIT/app + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d9239ca4b37cbc9278f6e2d62d45f96d16af19f6 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Tue, 13 Nov 2018 18:24:23 +0300 Subject: [PATCH 55/66] add codecov badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15861ad..adec8ad 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # sendIT [![Maintainability](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/maintainability)](https://codeclimate.com/github/ipaullly/sendIT/maintainability) -[![Test Coverage](https://api.codeclimate.com/v1/badges/db4df351dbe833d147b0/test_coverage)](https://codeclimate.com/github/ipaullly/sendIT/test_coverage) [![Build Status](https://travis-ci.com/ipaullly/sendIT.svg?branch=ft-GET-user-orders-161858618)](https://travis-ci.com/ipaullly/sendIT) [![Coverage Status](https://coveralls.io/repos/github/ipaullly/sendIT/badge.svg?branch=master)](https://coveralls.io/github/ipaullly/sendIT?branch=master) + [![Build Status](https://travis-ci.com/ipaullly/sendIT.svg?branch=ft-GET-user-orders-161858618)](https://travis-ci.com/ipaullly/sendIT) [![codecov](https://codecov.io/gh/ipaullly/sendIT/branch/ch-code-climates-161921842/graph/badge.svg)](https://codecov.io/gh/ipaullly/sendIT) The sendIT app is built using flask to make RESTful APIs to achieve basic functionalities for the app From b11f21ed174da24975fe660334f715ff321905d9 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 15:37:42 +0300 Subject: [PATCH 56/66] [starts #161951629] update README.md with commands to run app locally --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index adec8ad..fba29ac 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,17 @@ Next, install the requirements by typing: ``` pip install -r requirements.txt ``` +## Running the sendIT flask app locally + +Once you are in a virtual environment with all the dependencies installed, set the environmental variables: +``` +export FLASK_APP=run.py +export FLASK_ENV=development +``` +initialize the server with the command: +``` +flask run +``` ## Testing To test the endpointsensure that the following tools are available the follow steps below From f65d1c5d65809782b0a868063381bd6c0e45c5ab Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 15:46:44 +0300 Subject: [PATCH 57/66] [finishes #161951629] make testing instructions more clear --- README.md | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fba29ac..5d9ccbe 100644 --- a/README.md +++ b/README.md @@ -75,10 +75,24 @@ flask run ## Testing To test the endpointsensure that the following tools are available the follow steps below - ### Tools: - Postman + +### Tool: + Postman + + with the flask server running power up POSTMAN to test your endpoints. set the localhost: + ``` + http://127.0.0.1:5000/ + ``` + append the localhost with urls for the various endpoints, for example: + ``` + http://127.0.0.1:5000/api/v1/parcels + ``` + ensure to set the correct HTTP method before sending the request ### Commands - The application was tested using `pytest` and coveralls. - - pytest --cov app + The application was tested using `pytest` and code cov. + run the command + ``` + pytest --cov app + ``` + this generates a detailed log of the tests in your app directory From 64d72d4d13b15a985a2c445c7fc535676dd9c818 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 16:16:39 +0300 Subject: [PATCH 58/66] [starts #161954076] Add created order to response of POST request --- app/api/v1/models.py | 1 + app/api/v1/views.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/api/v1/models.py b/app/api/v1/models.py index fee0f79..eb81a84 100644 --- a/app/api/v1/models.py +++ b/app/api/v1/models.py @@ -23,6 +23,7 @@ def create_order(self, item, pickup, dest, pricing, username): "status" : self.parcel_status } self.db.append(payload) + return payload def order_list(self): """ diff --git a/app/api/v1/views.py b/app/api/v1/views.py index e7eedfe..eb5acbc 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -17,7 +17,7 @@ def post(self): pickup = data['pickup'] dest = data['dest'] pricing = data['pricing'] - author = data['username'] + author = data['user_id'] try: if " " in item: @@ -25,9 +25,10 @@ def post(self): elif type(pricing) is not int: raise Exception else: - order.create_order(item, pickup, dest, pricing, author) + res = order.create_order(item, pickup, dest, pricing, author) return make_response(jsonify({ - "message" : "delivery order created successfully" + "message" : "delivery order created successfully", + "new delivery order" : res }), 201) except Exception: return make_response(jsonify({ From ec5db7c2661eac8465d887da223f78e9e8ce49fb Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 17:30:42 +0300 Subject: [PATCH 59/66] [starts #161955974] Add whitespace validation --- app/auth/v1/views.py | 32 +++++++++++++++++---------- app/tests/v1/test_edgecases.py | 2 +- app/tests/v1/test_login.py | 4 ++-- app/tests/v1/test_parcels.py | 4 ++-- app/tests/v1/test_register.py | 2 +- app/utilities/JWT_token.py | 8 +++---- app/utilities/validation_functions.py | 6 +++++ 7 files changed, 36 insertions(+), 22 deletions(-) create mode 100644 app/utilities/validation_functions.py diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index 8a7e45b..963e25e 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -1,6 +1,7 @@ from flask_restful import Resource from flask import make_response,jsonify, request from .models import User +from ...utilities.validation_functions import check_for_space class Registration(Resource): """ @@ -10,20 +11,27 @@ def post(self): data = request.get_json() email = data['email'] password = data['password'] - - if not User.get_user_by_email(email): - new_user = User(email=email, password=password) - new_user.add_user() - return make_response(jsonify({ - 'message' : 'you have successfully registered an account' - }), 201) + if check_for_space(email): + if not User.get_user_by_email(email): + new_user = User(email=email, password=password) + new_user.add_user() + + return make_response(jsonify({ + 'message' : 'you have successfully registered an account' + }), 201) + else: + response = { + 'message': 'Account with provided email exists. please login' + } + + return make_response(jsonify(response), 409) else: response = { - 'message': 'Account with provided email exists. please login' + 'message' : 'Whitespaces are invalid inputs' } + return make_response(jsonify(response), 400) - return make_response(jsonify(response), 202) class SignIn(Resource): """ @@ -46,11 +54,11 @@ def post(self): return make_response(jsonify(response), 200) else: response = { - 'message' : 'User with email already exists, please login' + 'message' : 'Invalid password, please enter it again' } return make_response(jsonify(response), 401) except Exception: response = { - 'message' : 'wrong input format, please enter details again' + 'message' : 'wrong email format, please enter email again' } - return make_response(jsonify(response), 500) \ No newline at end of file + return make_response(jsonify(response), 400) \ No newline at end of file diff --git a/app/tests/v1/test_edgecases.py b/app/tests/v1/test_edgecases.py index eb342c2..01503b1 100644 --- a/app/tests/v1/test_edgecases.py +++ b/app/tests/v1/test_edgecases.py @@ -17,7 +17,7 @@ def setUp(self): "pickup" : "muranga", "dest" : "house", "pricing": 250, - "username" : "stanLee" + "user_id" : "12" } def test_empty_strings_in_POST_create_order(self): diff --git a/app/tests/v1/test_login.py b/app/tests/v1/test_login.py index 35de6a3..0155aad 100644 --- a/app/tests/v1/test_login.py +++ b/app/tests/v1/test_login.py @@ -32,8 +32,8 @@ def test_non_registered_user(self): #test that unregistered user cannot log in res = self.app.post('/auth/v1/login', data=json.dumps(self.mock_data), content_type='application/json') result = json.loads(res.data) - self.assertIn("{'message': 'wrong input format, please enter details again'}", str(result)) - self.assertEqual(res.status_code, 500) + self.assertIn("{'message': 'wrong email format, please enter email again'}", str(result)) + self.assertEqual(res.status_code, 400) if __name__ == "__main__": diff --git a/app/tests/v1/test_parcels.py b/app/tests/v1/test_parcels.py index 3b51d5b..c2048c1 100644 --- a/app/tests/v1/test_parcels.py +++ b/app/tests/v1/test_parcels.py @@ -17,7 +17,7 @@ def setUp(self): "pickup" : "Biashara street", "dest" : "Kikuyu town", "pricing": 250, - "username" : "barnabas" + "user_id" : "12" } def test_POST_create_delivery_order(self): @@ -56,7 +56,7 @@ def test_GET_orders_by_single_user(self): """ response = self.app.post('/api/v1/parcels', data=json.dumps(self.data), content_type='application/json') self.assertEqual(response.status_code, 201) - res = self.app.get('/api/v1/user/barnabas/parcels') + res = self.app.get('/api/v1/user/12/parcels') self.assertEqual(res.status_code, 200) self.assertIn('orders by single user', str(res.data)) diff --git a/app/tests/v1/test_register.py b/app/tests/v1/test_register.py index ff1c012..b3d08d2 100644 --- a/app/tests/v1/test_register.py +++ b/app/tests/v1/test_register.py @@ -29,7 +29,7 @@ def test_if_registered(self): response1 = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data2), content_type='application/json') self.assertEqual(response1.status_code, 201) duplicate_signup = self.app.post('/auth/v1/register', data=json.dumps(self.mock_data2), content_type='application/json') - self.assertEqual(duplicate_signup.status_code, 202) + self.assertEqual(duplicate_signup.status_code, 409) res = json.loads(duplicate_signup.data) self.assertIn('Account with provided email exists. please login', str(res)) diff --git a/app/utilities/JWT_token.py b/app/utilities/JWT_token.py index 82b6877..61c8a35 100644 --- a/app/utilities/JWT_token.py +++ b/app/utilities/JWT_token.py @@ -1,11 +1,10 @@ +""" from flask import current_app import jwt def decode_token(token): - """ - method to decode the token generated during login - """ + try: #attempt to decode token using SECRET_KEY variable payload = jwt.decode(token, current_app.config.get('SECRET_KEY')) @@ -15,4 +14,5 @@ def decode_token(token): return "Token expired. please login again to generate fresh token" except jwt.InvalidTokenError: #the token is not valid, throw error - return "Unworthy token. Please login to get fresh authorization" \ No newline at end of file + return "Unworthy token. Please login to get fresh authorization" +""" \ No newline at end of file diff --git a/app/utilities/validation_functions.py b/app/utilities/validation_functions.py new file mode 100644 index 0000000..3bd126f --- /dev/null +++ b/app/utilities/validation_functions.py @@ -0,0 +1,6 @@ +def check_for_space(varib): + output = varib.strip(" ") + if output: + return True + else: + return False \ No newline at end of file From 9d74994a67375f6763841a23106435d0f3ee6f19 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 17:46:02 +0300 Subject: [PATCH 60/66] [finishes #161955974] add test for blank email registration --- .coverage | 2 +- app/tests/v1/test_edgecases.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.coverage b/.coverage index 18f13e4..72253bb 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"arcs":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[[-1,1],[1,2],[2,3],[3,6],[6,-1],[-6,7],[7,9],[9,10],[10,11],[11,13],[13,-6]],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,11],[11,12],[12,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[-7,7],[7,10],[10,11],[11,37],[37,-7],[7,47],[-47,47],[47,50],[50,51],[51,-47],[47,61],[-61,61],[61,64],[64,65],[65,-61],[61,72],[-72,72],[72,75],[75,76],[76,-72],[72,-1],[-11,15],[15,16],[16,17],[17,18],[18,19],[19,20],[20,22],[22,23],[23,24],[24,32],[32,33],[33,34],[34,35],[35,-11],[23,25],[25,28],[28,29],[29,30],[30,31],[31,-11],[-37,41],[41,42],[42,43],[43,44],[44,45],[45,-37],[-65,66],[66,67],[67,68],[68,69],[69,70],[70,-65],[-51,55],[55,56],[56,57],[57,58],[58,59],[59,-51],[-76,80],[80,81],[81,82],[82,83],[83,84],[84,-76]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[[-2,2],[2,4],[-4,4],[4,7],[7,8],[8,12],[12,27],[27,33],[33,40],[40,48],[48,-4],[4,-2],[-8,9],[9,10],[10,-8],[-12,17],[17,18],[18,19],[19,20],[20,21],[21,22],[22,23],[23,25],[25,-12],[-27,31],[31,-27],[-48,52],[-52,52],[52,52],[52,-52],[52,53],[53,-48],[-33,37],[-37,37],[37,37],[37,-37],[37,38],[38,-33],[-40,44],[-44,44],[44,44],[44,-44],[44,45],[45,46],[46,-40]],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,-5],[5,28],[-28,28],[28,31],[31,32],[32,-28],[28,-1],[-32,33],[33,34],[34,35],[35,37],[37,38],[38,39],[39,52],[52,54],[54,56],[56,-32],[-9,10],[10,11],[11,12],[12,14],[14,15],[15,16],[16,18],[18,19],[19,20],[20,-9],[39,40],[40,41],[41,42],[42,44],[44,46],[46,-32],[14,23],[23,26],[26,-9]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,15],[15,-6],[6,18],[-10,11],[11,12],[12,13],[13,14],[14,-10],[18,20],[-20,20],[20,23],[23,24],[24,-20],[20,31],[-31,31],[31,34],[34,35],[35,42],[42,52],[52,60],[60,67],[67,86],[86,-31],[31,-1],[-86,91],[91,95],[95,-86],[-35,36],[36,37],[37,38],[38,39],[39,40],[40,-35],[-42,46],[46,47],[47,48],[48,49],[49,50],[-60,64],[64,65],[-65,65],[65,65],[65,-65],[65,-60],[50,-42],[91,92],[92,93],[93,94],[94,-86],[-52,56],[56,57],[57,-52],[-67,71],[71,73],[73,74],[74,75],[75,77],[77,78],[78,79],[79,80],[80,83],[83,84],[84,-67],[93,91]],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,-5],[5,32],[32,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-23,27],[27,28],[28,29],[29,30],[30,-23]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,21],[21,31],[31,-5],[5,39],[39,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-31,33],[33,34],[34,35],[35,36],[36,-31],[-21,23],[23,24],[24,25],[25,26],[26,27],[27,28],[28,29],[29,-21]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,32],[32,43],[43,53],[53,63],[63,-5],[5,75],[75,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-32,36],[36,37],[37,38],[38,39],[39,40],[40,41],[41,-32],[-53,57],[57,58],[58,59],[59,60],[60,61],[61,-53],[-43,47],[47,48],[48,49],[49,50],[50,51],[51,-43],[-23,27],[27,28],[28,29],[29,30],[30,-23],[-63,67],[67,68],[68,69],[69,70],[70,71],[71,-63]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,22],[22,28],[28,-5],[5,36],[36,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-28,29],[29,30],[30,31],[31,32],[32,33],[33,34],[34,-28],[-22,23],[23,24],[24,25],[25,-22]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/__init__.py":[],"/home/ipaullly/dev/parcels/sendIT/app/utilities/JWT_token.py":[]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"arcs":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[[-1,1],[1,2],[2,3],[3,6],[6,-1],[-6,7],[7,9],[9,10],[10,11],[11,13],[13,-6]],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,11],[11,12],[12,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[-7,7],[7,10],[10,11],[11,38],[38,-7],[7,48],[-48,48],[48,51],[51,52],[52,-48],[48,62],[-62,62],[62,65],[65,66],[66,-62],[62,73],[-73,73],[73,76],[76,77],[77,-73],[73,-1],[-11,15],[15,16],[16,17],[17,18],[18,19],[19,20],[20,22],[22,23],[23,24],[24,33],[33,34],[34,35],[35,36],[36,-11],[23,25],[25,28],[28,29],[29,30],[30,31],[31,32],[32,-11],[-38,42],[42,43],[43,44],[44,45],[45,46],[46,-38],[-66,67],[67,68],[68,69],[69,70],[70,71],[71,-66],[-52,56],[56,57],[57,58],[58,59],[59,60],[60,-52],[-77,81],[81,82],[82,83],[83,84],[84,85],[85,-77]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[[-2,2],[2,4],[-4,4],[4,7],[7,8],[8,12],[12,28],[28,34],[34,41],[41,49],[49,-4],[4,-2],[-8,9],[9,10],[10,-8],[-12,17],[17,18],[18,19],[19,20],[20,21],[21,22],[22,23],[23,25],[25,26],[26,-12],[-28,32],[32,-28],[-49,53],[-53,53],[53,53],[53,-53],[53,54],[54,-49],[-34,38],[-38,38],[38,38],[38,-38],[38,39],[39,-34],[-41,45],[-45,45],[45,45],[45,-45],[45,46],[46,47],[47,-41]],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,-6],[6,36],[-36,36],[36,39],[39,40],[40,-36],[36,-1],[-10,11],[11,12],[12,13],[13,15],[15,31],[31,33],[33,-10],[-40,41],[41,42],[42,43],[43,45],[45,46],[46,47],[47,60],[60,62],[62,64],[64,-40],[15,16],[16,17],[17,18],[18,20],[20,21],[21,22],[22,-10],[47,48],[48,49],[49,50],[50,52],[52,54],[54,-40],[16,25],[25,28],[28,-10]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,15],[15,-6],[6,18],[-10,11],[11,12],[12,13],[13,14],[14,-10],[18,20],[-20,20],[20,23],[23,24],[24,-20],[20,31],[-31,31],[31,34],[34,35],[35,42],[42,52],[52,60],[60,67],[67,86],[86,-31],[31,-1],[-86,91],[91,95],[95,-86],[-35,36],[36,37],[37,38],[38,39],[39,40],[40,-35],[-42,46],[46,47],[47,48],[48,49],[49,50],[-60,64],[64,65],[-65,65],[65,65],[65,-65],[65,-60],[50,-42],[91,92],[92,93],[93,94],[94,-86],[-52,56],[56,57],[57,-52],[-67,71],[71,73],[73,74],[74,75],[75,77],[77,78],[78,79],[79,80],[80,83],[83,84],[84,-67],[93,91]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/validation_functions.py":[[-1,1],[1,-1],[-1,2],[2,3],[3,6],[6,-1],[3,4],[4,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,27],[27,36],[36,-5],[5,42],[42,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,23],[23,24],[24,-9],[-27,31],[31,32],[32,33],[33,34],[34,-27],[-36,37],[37,38],[38,39],[39,40],[40,-36]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,21],[21,31],[31,-5],[5,39],[39,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-31,33],[33,34],[34,35],[35,36],[36,-31],[-21,23],[23,24],[24,25],[25,26],[26,27],[27,28],[28,29],[29,-21]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,32],[32,43],[43,53],[53,63],[63,-5],[5,75],[75,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-32,36],[36,37],[37,38],[38,39],[39,40],[40,41],[41,-32],[-53,57],[57,58],[58,59],[59,60],[60,61],[61,-53],[-43,47],[47,48],[48,49],[49,50],[50,51],[51,-43],[-23,27],[27,28],[28,29],[29,30],[30,-23],[-63,67],[67,68],[68,69],[69,70],[70,71],[71,-63]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,22],[22,28],[28,-5],[5,36],[36,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-28,29],[29,30],[30,31],[31,32],[32,33],[33,34],[34,-28],[-22,23],[23,24],[24,25],[25,-22]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/JWT_token.py":[]}} \ No newline at end of file diff --git a/app/tests/v1/test_edgecases.py b/app/tests/v1/test_edgecases.py index 01503b1..03a5d1c 100644 --- a/app/tests/v1/test_edgecases.py +++ b/app/tests/v1/test_edgecases.py @@ -19,6 +19,10 @@ def setUp(self): "pricing": 250, "user_id" : "12" } + self.invalid_registration_details = { + "email" : " ", + "password" : "ghfgfg" + } def test_empty_strings_in_POST_create_order(self): """ @@ -29,5 +33,11 @@ def test_empty_strings_in_POST_create_order(self): self.assertEqual(response.status_code, 400) self.assertIn('wrong input format', str(result)) + def test_whitespces_in_email_field(self): + response2 = self.app.post('/auth/v1/register', data=json.dumps(self.invalid_registration_details), content_type='application/json') + self.assertEqual(response2.status_code, 400) + res = json.loads(response2.data) + self.assertEqual("{'message': 'Whitespaces are invalid inputs'}", str(res)) + if __name__ == "__main__": unittest.main() \ No newline at end of file From 360b4fa82603da44ee1542070c2396bfb0103ccb Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 18:12:38 +0300 Subject: [PATCH 61/66] [starts #161957214] Add validation for correct email pattern --- app/auth/v1/views.py | 26 ++++++++++++++++---------- app/utilities/validation_functions.py | 11 ++++++++++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index 963e25e..4694bd1 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -1,7 +1,7 @@ from flask_restful import Resource from flask import make_response,jsonify, request from .models import User -from ...utilities.validation_functions import check_for_space +from ...utilities.validation_functions import check_for_space, check_email_format class Registration(Resource): """ @@ -13,19 +13,25 @@ def post(self): password = data['password'] if check_for_space(email): - if not User.get_user_by_email(email): - new_user = User(email=email, password=password) - new_user.add_user() + if check_email_format(email): + if not User.get_user_by_email(email): + new_user = User(email=email, password=password) + new_user.add_user() - return make_response(jsonify({ - 'message' : 'you have successfully registered an account' - }), 201) + return make_response(jsonify({ + 'message' : 'you have successfully registered an account' + }), 201) + else: + response = { + 'message': 'Account with provided email exists. please login' + } + + return make_response(jsonify(response), 409) else: response = { - 'message': 'Account with provided email exists. please login' + 'message' : 'Invalid email format' } - - return make_response(jsonify(response), 409) + return make_response(jsonify(response), 400) else: response = { 'message' : 'Whitespaces are invalid inputs' diff --git a/app/utilities/validation_functions.py b/app/utilities/validation_functions.py index 3bd126f..e5d4e5e 100644 --- a/app/utilities/validation_functions.py +++ b/app/utilities/validation_functions.py @@ -1,6 +1,15 @@ +import re + def check_for_space(varib): output = varib.strip(" ") if output: return True else: - return False \ No newline at end of file + return False + +def check_email_format(varib): + match = re.search(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9]+\.[a-zA-Z0-9.]*\.*[com|org|edu]{3}$)",varib) + if match: + return True + else: + return False From d58860c990ddd9fdc0c45e14c292d1d4b50aed23 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 18:18:15 +0300 Subject: [PATCH 62/66] [finishes #161957214] test wrong email pattern --- app/tests/v1/test_edgecases.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/tests/v1/test_edgecases.py b/app/tests/v1/test_edgecases.py index 03a5d1c..c52919d 100644 --- a/app/tests/v1/test_edgecases.py +++ b/app/tests/v1/test_edgecases.py @@ -19,10 +19,14 @@ def setUp(self): "pricing": 250, "user_id" : "12" } - self.invalid_registration_details = { + self.blank_email = { "email" : " ", "password" : "ghfgfg" } + self.invalid_pattern = { + "email" : "house", + "password" : "xgss" + } def test_empty_strings_in_POST_create_order(self): """ @@ -34,10 +38,15 @@ def test_empty_strings_in_POST_create_order(self): self.assertIn('wrong input format', str(result)) def test_whitespces_in_email_field(self): - response2 = self.app.post('/auth/v1/register', data=json.dumps(self.invalid_registration_details), content_type='application/json') + response2 = self.app.post('/auth/v1/register', data=json.dumps(self.blank_email), content_type='application/json') self.assertEqual(response2.status_code, 400) res = json.loads(response2.data) self.assertEqual("{'message': 'Whitespaces are invalid inputs'}", str(res)) - + + def test_wrong_email_pattern(self): + response3 = self.app.post('/auth/v1/register', data=json.dumps(self.invalid_pattern), content_type='application/json') + self.assertEqual(response3.status_code, 400) + res = json.loads(response3.data) + self.assertEqual("{'message': 'Invalid email format'}", str(res)) if __name__ == "__main__": unittest.main() \ No newline at end of file From fa9b43859e5ebcc2282da39d7506315d548bf81c Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 22:11:50 +0300 Subject: [PATCH 63/66] [starts #161966166] add link to API documentation in README.md --- README.md | 3 ++- app/auth/v1/views.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5d9ccbe..ad79e2a 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,8 @@ To test the endpointsensure that the following tools are available the follow st ``` http://127.0.0.1:5000/api/v1/parcels ``` - ensure to set the correct HTTP method before sending the request + ensure to set the correct HTTP method before sending the request. + alternatively you can access the API documentation [here](https://documenter.getpostman.com/view/4014888/RzZCCwun#22450978-87c5-be21-e538-51cd4100035a) ### Commands The application was tested using `pytest` and code cov. diff --git a/app/auth/v1/views.py b/app/auth/v1/views.py index 4694bd1..37afd45 100644 --- a/app/auth/v1/views.py +++ b/app/auth/v1/views.py @@ -55,7 +55,7 @@ def post(self): auth_token = user.generate_token(user_id) if auth_token: response = { - 'message' : 'Successfully logged in and token generated' + 'message' : 'Successfully logged in' } return make_response(jsonify(response), 200) else: From 29425024a315dabbbf58fa59438ec6cec6e521d4 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 22:16:35 +0300 Subject: [PATCH 64/66] [finishes #161966166] update coverage --- README.md | 3 +- coverage.xml | 161 +++++++++++++++++++++++++++++---------------------- 2 files changed, 95 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index ad79e2a..903a8cc 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,8 @@ To test the endpointsensure that the following tools are available the follow st http://127.0.0.1:5000/api/v1/parcels ``` ensure to set the correct HTTP method before sending the request. - alternatively you can access the API documentation [here](https://documenter.getpostman.com/view/4014888/RzZCCwun#22450978-87c5-be21-e538-51cd4100035a) + + Alternatively you can access the API documentation via this [link](https://documenter.getpostman.com/view/4014888/RzZCCwun#22450978-87c5-be21-e538-51cd4100035a). ### Commands The application was tested using `pytest` and code cov. diff --git a/coverage.xml b/coverage.xml index 2da2130..3113ece 100644 --- a/coverage.xml +++ b/coverage.xml @@ -1,5 +1,5 @@ - + @@ -32,7 +32,7 @@ - + @@ -59,18 +59,19 @@ - - - - - - - - + + + + + + + + - - - + + + + @@ -95,23 +96,23 @@ - - - + + - - - + + + - - + + - - - + + + + @@ -124,7 +125,7 @@ - + @@ -195,41 +196,48 @@ - + - - + + - - - + + + + - - - - - - - - - + + + + + + + - - - - + - + + + - - + + + + + + + + + + + @@ -242,13 +250,13 @@ - + - + @@ -259,11 +267,23 @@ - - - - - + + + + + + + + + + + + + + + + + @@ -363,27 +383,32 @@ - + - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + From 8b92a37cedd2283f7db6216b001f40409ff0c366 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 22:36:51 +0300 Subject: [PATCH 65/66] [starts #161967302] Add validation for parcel id --- .coverage | 2 +- app/api/v1/models.py | 8 ++++++-- app/api/v1/views.py | 14 ++++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.coverage b/.coverage index 72253bb..d48b109 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"arcs":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[[-1,1],[1,2],[2,3],[3,6],[6,-1],[-6,7],[7,9],[9,10],[10,11],[11,13],[13,-6]],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,11],[11,12],[12,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[-7,7],[7,10],[10,11],[11,38],[38,-7],[7,48],[-48,48],[48,51],[51,52],[52,-48],[48,62],[-62,62],[62,65],[65,66],[66,-62],[62,73],[-73,73],[73,76],[76,77],[77,-73],[73,-1],[-11,15],[15,16],[16,17],[17,18],[18,19],[19,20],[20,22],[22,23],[23,24],[24,33],[33,34],[34,35],[35,36],[36,-11],[23,25],[25,28],[28,29],[29,30],[30,31],[31,32],[32,-11],[-38,42],[42,43],[43,44],[44,45],[45,46],[46,-38],[-66,67],[67,68],[68,69],[69,70],[70,71],[71,-66],[-52,56],[56,57],[57,58],[58,59],[59,60],[60,-52],[-77,81],[81,82],[82,83],[83,84],[84,85],[85,-77]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[[-2,2],[2,4],[-4,4],[4,7],[7,8],[8,12],[12,28],[28,34],[34,41],[41,49],[49,-4],[4,-2],[-8,9],[9,10],[10,-8],[-12,17],[17,18],[18,19],[19,20],[20,21],[21,22],[22,23],[23,25],[25,26],[26,-12],[-28,32],[32,-28],[-49,53],[-53,53],[53,53],[53,-53],[53,54],[54,-49],[-34,38],[-38,38],[38,38],[38,-38],[38,39],[39,-34],[-41,45],[-45,45],[45,45],[45,-45],[45,46],[46,47],[47,-41]],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,-6],[6,36],[-36,36],[36,39],[39,40],[40,-36],[36,-1],[-10,11],[11,12],[12,13],[13,15],[15,31],[31,33],[33,-10],[-40,41],[41,42],[42,43],[43,45],[45,46],[46,47],[47,60],[60,62],[62,64],[64,-40],[15,16],[16,17],[17,18],[18,20],[20,21],[21,22],[22,-10],[47,48],[48,49],[49,50],[50,52],[52,54],[54,-40],[16,25],[25,28],[28,-10]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,15],[15,-6],[6,18],[-10,11],[11,12],[12,13],[13,14],[14,-10],[18,20],[-20,20],[20,23],[23,24],[24,-20],[20,31],[-31,31],[31,34],[34,35],[35,42],[42,52],[52,60],[60,67],[67,86],[86,-31],[31,-1],[-86,91],[91,95],[95,-86],[-35,36],[36,37],[37,38],[38,39],[39,40],[40,-35],[-42,46],[46,47],[47,48],[48,49],[49,50],[-60,64],[64,65],[-65,65],[65,65],[65,-65],[65,-60],[50,-42],[91,92],[92,93],[93,94],[94,-86],[-52,56],[56,57],[57,-52],[-67,71],[71,73],[73,74],[74,75],[75,77],[77,78],[78,79],[79,80],[80,83],[83,84],[84,-67],[93,91]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/validation_functions.py":[[-1,1],[1,-1],[-1,2],[2,3],[3,6],[6,-1],[3,4],[4,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,27],[27,36],[36,-5],[5,42],[42,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,23],[23,24],[24,-9],[-27,31],[31,32],[32,33],[33,34],[34,-27],[-36,37],[37,38],[38,39],[39,40],[40,-36]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,21],[21,31],[31,-5],[5,39],[39,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-31,33],[33,34],[34,35],[35,36],[36,-31],[-21,23],[23,24],[24,25],[25,26],[26,27],[27,28],[28,29],[29,-21]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,32],[32,43],[43,53],[53,63],[63,-5],[5,75],[75,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-32,36],[36,37],[37,38],[38,39],[39,40],[40,41],[41,-32],[-53,57],[57,58],[58,59],[59,60],[60,61],[61,-53],[-43,47],[47,48],[48,49],[49,50],[50,51],[51,-43],[-23,27],[27,28],[28,29],[29,30],[30,-23],[-63,67],[67,68],[68,69],[69,70],[70,71],[71,-63]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,22],[22,28],[28,-5],[5,36],[36,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-28,29],[29,30],[30,31],[31,32],[32,33],[33,34],[34,-28],[-22,23],[23,24],[24,25],[25,-22]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/JWT_token.py":[]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"arcs":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[[-1,1],[1,2],[2,3],[3,6],[6,-1],[-6,7],[7,9],[9,10],[10,11],[11,13],[13,-6]],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,11],[11,12],[12,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[-7,7],[7,10],[10,11],[11,38],[38,-7],[7,48],[-48,48],[48,51],[51,52],[52,-48],[48,62],[-62,62],[62,65],[65,66],[66,-62],[62,73],[-73,73],[73,76],[76,77],[77,-73],[73,-1],[-11,15],[15,16],[16,17],[17,18],[18,19],[19,20],[20,22],[22,23],[23,24],[24,33],[33,34],[34,35],[35,36],[36,-11],[23,25],[25,28],[28,29],[29,30],[30,31],[31,32],[32,-11],[-38,42],[42,43],[43,44],[44,45],[45,46],[46,-38],[-66,67],[67,68],[68,69],[69,70],[70,71],[71,-66],[-52,56],[56,57],[57,58],[58,59],[59,60],[60,-52],[-77,81],[81,82],[82,83],[83,84],[84,85],[85,-77]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[[-2,2],[2,4],[-4,4],[4,7],[7,8],[8,12],[12,28],[28,34],[34,41],[41,49],[49,-4],[4,-2],[-8,9],[9,10],[10,-8],[-12,17],[17,18],[18,19],[19,20],[20,21],[21,22],[22,23],[23,25],[25,26],[26,-12],[-28,32],[32,-28],[-49,53],[-53,53],[53,53],[53,-53],[53,54],[54,-49],[-34,38],[-38,38],[38,38],[38,-38],[38,39],[39,-34],[-41,45],[-45,45],[45,45],[45,-45],[45,46],[46,47],[47,-41]],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,-6],[6,42],[-42,42],[42,45],[45,46],[46,-42],[42,-1],[-10,11],[11,12],[12,13],[13,15],[15,37],[37,39],[39,-10],[15,16],[16,32],[32,34],[34,-10],[-46,47],[47,48],[48,49],[49,51],[51,52],[52,53],[53,66],[66,68],[68,70],[70,-46],[16,17],[17,18],[18,19],[19,21],[21,22],[22,23],[23,-10],[53,54],[54,55],[55,56],[56,58],[58,60],[60,-46],[17,26],[26,29],[29,-10]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,15],[15,-6],[6,18],[-10,11],[11,12],[12,13],[13,14],[14,-10],[18,20],[-20,20],[20,23],[23,24],[24,-20],[20,31],[-31,31],[31,34],[34,35],[35,42],[42,52],[52,60],[60,67],[67,86],[86,-31],[31,-1],[-86,91],[91,95],[95,-86],[-35,36],[36,37],[37,38],[38,39],[39,40],[40,-35],[-42,46],[46,47],[47,48],[48,49],[49,50],[-60,64],[64,65],[-65,65],[65,65],[65,-65],[65,-60],[50,-42],[91,92],[92,93],[93,94],[94,-86],[-52,56],[56,57],[57,-52],[-67,71],[71,73],[73,74],[74,75],[75,77],[77,78],[78,79],[79,80],[80,83],[83,84],[84,-67],[93,91]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/validation_functions.py":[[-1,1],[1,3],[3,10],[10,-1],[-3,4],[4,5],[5,8],[8,-3],[5,6],[6,-3],[-10,11],[11,12],[12,15],[15,-10],[12,13],[13,-10]],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,31],[31,40],[40,46],[46,-5],[5,51],[51,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,23],[23,24],[24,27],[27,28],[28,-9],[-31,35],[35,36],[36,37],[37,38],[38,-31],[-40,41],[41,42],[42,43],[43,44],[44,-40],[-46,47],[47,48],[48,49],[49,50],[50,-46]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,21],[21,31],[31,-5],[5,39],[39,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-31,33],[33,34],[34,35],[35,36],[36,-31],[-21,23],[23,24],[24,25],[25,26],[26,27],[27,28],[28,29],[29,-21]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,32],[32,43],[43,53],[53,63],[63,-5],[5,75],[75,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-32,36],[36,37],[37,38],[38,39],[39,40],[40,41],[41,-32],[-53,57],[57,58],[58,59],[59,60],[60,61],[61,-53],[-43,47],[47,48],[48,49],[49,50],[50,51],[51,-43],[-23,27],[27,28],[28,29],[29,30],[30,-23],[-63,67],[67,68],[68,69],[69,70],[70,71],[71,-63]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,22],[22,28],[28,-5],[5,36],[36,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-28,29],[29,30],[30,31],[31,32],[32,33],[33,34],[34,-28],[-22,23],[23,24],[24,25],[25,-22]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/JWT_token.py":[]}} \ No newline at end of file diff --git a/app/api/v1/models.py b/app/api/v1/models.py index eb81a84..262a0d0 100644 --- a/app/api/v1/models.py +++ b/app/api/v1/models.py @@ -35,8 +35,12 @@ def retrieve_single_order(self, parcelID): """ retrieve a single order by id """ - order_by_id = [parc for parc in self.db if parc['id'] == parcelID][0] - return order_by_id + for parc in self.db: + if parc['id'] == parcelID: + return parc + else: + return False + def cancel_order(self, ParcelID): """ diff --git a/app/api/v1/views.py b/app/api/v1/views.py index eb5acbc..37e922f 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -53,11 +53,17 @@ def get(self, id): """ get method to retrieve order by id """ + single = order.retrieve_single_order(id) - return make_response(jsonify({ - "message" : "Ok", - "order" : single - }), 200) + if single: + return make_response(jsonify({ + "message" : "Ok", + "order" : single + }), 200) + else: + return make_response(jsonify({ + "message" : "Invalid id" + }), 400) class UserOrders(Resource): """ From 0782e0114d59a0f344f584223f7e266947445e51 Mon Sep 17 00:00:00 2001 From: ipaullly Date: Wed, 14 Nov 2018 22:45:56 +0300 Subject: [PATCH 66/66] [finishes #161967302] test invalid id response --- .coverage | 2 +- app/api/v1/views.py | 5 +++-- app/tests/v1/test_edgecases.py | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.coverage b/.coverage index d48b109..29290f2 100644 --- a/.coverage +++ b/.coverage @@ -1 +1 @@ -!coverage.py: This is a private format, don't read it directly!{"arcs":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[[-1,1],[1,2],[2,3],[3,6],[6,-1],[-6,7],[7,9],[9,10],[10,11],[11,13],[13,-6]],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,11],[11,12],[12,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[-7,7],[7,10],[10,11],[11,38],[38,-7],[7,48],[-48,48],[48,51],[51,52],[52,-48],[48,62],[-62,62],[62,65],[65,66],[66,-62],[62,73],[-73,73],[73,76],[76,77],[77,-73],[73,-1],[-11,15],[15,16],[16,17],[17,18],[18,19],[19,20],[20,22],[22,23],[23,24],[24,33],[33,34],[34,35],[35,36],[36,-11],[23,25],[25,28],[28,29],[29,30],[30,31],[31,32],[32,-11],[-38,42],[42,43],[43,44],[44,45],[45,46],[46,-38],[-66,67],[67,68],[68,69],[69,70],[70,71],[71,-66],[-52,56],[56,57],[57,58],[58,59],[59,60],[60,-52],[-77,81],[81,82],[82,83],[83,84],[84,85],[85,-77]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[[-2,2],[2,4],[-4,4],[4,7],[7,8],[8,12],[12,28],[28,34],[34,41],[41,49],[49,-4],[4,-2],[-8,9],[9,10],[10,-8],[-12,17],[17,18],[18,19],[19,20],[20,21],[21,22],[22,23],[23,25],[25,26],[26,-12],[-28,32],[32,-28],[-49,53],[-53,53],[53,53],[53,-53],[53,54],[54,-49],[-34,38],[-38,38],[38,38],[38,-38],[38,39],[39,-34],[-41,45],[-45,45],[45,45],[45,-45],[45,46],[46,47],[47,-41]],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,-6],[6,42],[-42,42],[42,45],[45,46],[46,-42],[42,-1],[-10,11],[11,12],[12,13],[13,15],[15,37],[37,39],[39,-10],[15,16],[16,32],[32,34],[34,-10],[-46,47],[47,48],[48,49],[49,51],[51,52],[52,53],[53,66],[66,68],[68,70],[70,-46],[16,17],[17,18],[18,19],[19,21],[21,22],[22,23],[23,-10],[53,54],[54,55],[55,56],[56,58],[58,60],[60,-46],[17,26],[26,29],[29,-10]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,15],[15,-6],[6,18],[-10,11],[11,12],[12,13],[13,14],[14,-10],[18,20],[-20,20],[20,23],[23,24],[24,-20],[20,31],[-31,31],[31,34],[34,35],[35,42],[42,52],[52,60],[60,67],[67,86],[86,-31],[31,-1],[-86,91],[91,95],[95,-86],[-35,36],[36,37],[37,38],[38,39],[39,40],[40,-35],[-42,46],[46,47],[47,48],[48,49],[49,50],[-60,64],[64,65],[-65,65],[65,65],[65,-65],[65,-60],[50,-42],[91,92],[92,93],[93,94],[94,-86],[-52,56],[56,57],[57,-52],[-67,71],[71,73],[73,74],[74,75],[75,77],[77,78],[78,79],[79,80],[80,83],[83,84],[84,-67],[93,91]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/validation_functions.py":[[-1,1],[1,3],[3,10],[10,-1],[-3,4],[4,5],[5,8],[8,-3],[5,6],[6,-3],[-10,11],[11,12],[12,15],[15,-10],[12,13],[13,-10]],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,31],[31,40],[40,46],[46,-5],[5,51],[51,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,23],[23,24],[24,27],[27,28],[28,-9],[-31,35],[35,36],[36,37],[37,38],[38,-31],[-40,41],[41,42],[42,43],[43,44],[44,-40],[-46,47],[47,48],[48,49],[49,50],[50,-46]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,21],[21,31],[31,-5],[5,39],[39,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-31,33],[33,34],[34,35],[35,36],[36,-31],[-21,23],[23,24],[24,25],[25,26],[26,27],[27,28],[28,29],[29,-21]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,32],[32,43],[43,53],[53,63],[63,-5],[5,75],[75,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-32,36],[36,37],[37,38],[38,39],[39,40],[40,41],[41,-32],[-53,57],[57,58],[58,59],[59,60],[60,61],[61,-53],[-43,47],[47,48],[48,49],[49,50],[50,51],[51,-43],[-23,27],[27,28],[28,29],[29,30],[30,-23],[-63,67],[67,68],[68,69],[69,70],[70,71],[71,-63]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,22],[22,28],[28,-5],[5,36],[36,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-28,29],[29,30],[30,31],[31,32],[32,33],[33,34],[34,-28],[-22,23],[23,24],[24,25],[25,-22]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/JWT_token.py":[]}} \ No newline at end of file +!coverage.py: This is a private format, don't read it directly!{"arcs":{"/home/ipaullly/dev/parcels/sendIT/app/__init__.py":[[-1,1],[1,2],[2,3],[3,6],[6,-1],[-6,7],[7,9],[9,10],[10,11],[11,13],[13,-6]],"/home/ipaullly/dev/parcels/sendIT/app/api/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,11],[11,12],[12,-1]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/views.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[-7,7],[7,10],[10,11],[11,38],[38,-7],[7,48],[-48,48],[48,51],[51,52],[52,-48],[48,69],[-69,69],[69,72],[72,73],[73,-69],[69,80],[-80,80],[80,83],[83,84],[84,-80],[80,-1],[-11,15],[15,16],[16,17],[17,18],[18,19],[19,20],[20,22],[22,23],[23,24],[24,33],[33,34],[34,35],[35,36],[36,-11],[23,25],[25,28],[28,29],[29,30],[30,31],[31,32],[32,-11],[-52,57],[57,58],[58,65],[65,67],[67,-52],[-38,42],[42,43],[43,44],[44,45],[45,46],[46,-38],[-73,74],[74,75],[75,76],[76,77],[77,78],[78,-73],[58,59],[59,60],[60,61],[61,62],[62,-52],[-84,88],[88,89],[89,90],[90,91],[91,92],[92,-84]],"/home/ipaullly/dev/parcels/sendIT/app/api/v1/models.py":[[-2,2],[2,4],[-4,4],[4,7],[7,8],[8,12],[12,28],[28,34],[34,45],[45,53],[53,-4],[4,-2],[-8,9],[9,10],[10,-8],[-12,17],[17,18],[18,19],[19,20],[20,21],[21,22],[22,23],[23,25],[25,26],[26,-12],[-34,38],[38,39],[39,42],[42,-34],[-28,32],[32,-28],[-53,57],[-57,57],[57,57],[57,-57],[57,58],[58,-53],[39,40],[40,-34],[-45,49],[-49,49],[49,49],[49,-49],[49,50],[50,51],[51,-45]],"/home/ipaullly/dev/parcels/sendIT/app/auth/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/__init__.py":[[-1,1],[1,2],[2,3],[3,5],[5,7],[7,9],[9,10],[10,-1]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/views.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,-6],[6,42],[-42,42],[42,45],[45,46],[46,-42],[42,-1],[-10,11],[11,12],[12,13],[13,15],[15,37],[37,39],[39,-10],[15,16],[16,32],[32,34],[34,-10],[-46,47],[47,48],[48,49],[49,51],[51,52],[52,53],[53,66],[66,68],[68,70],[70,-46],[16,17],[17,18],[18,19],[19,21],[21,22],[22,23],[23,-10],[53,54],[54,55],[55,56],[56,58],[58,60],[60,-46],[17,26],[26,29],[29,-10]],"/home/ipaullly/dev/parcels/sendIT/app/auth/v1/models.py":[[-1,1],[1,2],[2,3],[3,4],[4,6],[-6,6],[6,9],[9,10],[10,15],[15,-6],[6,18],[-10,11],[11,12],[12,13],[13,14],[14,-10],[18,20],[-20,20],[20,23],[23,24],[24,-20],[20,31],[-31,31],[31,34],[34,35],[35,42],[42,52],[52,60],[60,67],[67,86],[86,-31],[31,-1],[-86,91],[91,95],[95,-86],[-35,36],[36,37],[37,38],[38,39],[39,40],[40,-35],[-42,46],[46,47],[47,48],[48,49],[49,50],[-60,64],[64,65],[-65,65],[65,65],[65,-65],[65,-60],[50,-42],[91,92],[92,93],[93,94],[94,-86],[-52,56],[56,57],[57,-52],[-67,71],[71,73],[73,74],[74,75],[75,77],[77,78],[78,79],[79,80],[80,83],[83,84],[84,-67],[93,91]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/validation_functions.py":[[-1,1],[1,3],[3,10],[10,-1],[-3,4],[4,5],[5,8],[8,-3],[5,6],[6,-3],[-10,11],[11,12],[12,15],[15,-10],[12,13],[13,-10]],"/home/ipaullly/dev/parcels/sendIT/app/tests/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/__init__.py":[[-1,1],[1,-1]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_edgecases.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,38],[38,47],[47,53],[53,59],[59,-5],[5,66],[66,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,23],[23,24],[24,27],[27,28],[28,31],[31,32],[32,33],[33,34],[34,35],[35,-9],[-38,42],[42,43],[43,44],[44,45],[45,-38],[-59,60],[60,61],[61,62],[62,63],[63,64],[64,-59],[-47,48],[48,49],[49,50],[50,51],[51,-47],[-53,54],[54,55],[55,56],[56,57],[57,-53]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_login.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,21],[21,31],[31,-5],[5,39],[39,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-31,33],[33,34],[34,35],[35,36],[36,-31],[-21,23],[23,24],[24,25],[25,26],[26,27],[27,28],[28,29],[29,-21]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_parcels.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,23],[23,32],[32,43],[43,53],[53,63],[63,-5],[5,75],[75,-1],[-9,13],[13,14],[14,16],[16,17],[17,18],[18,19],[19,20],[20,-9],[-32,36],[36,37],[37,38],[38,39],[39,40],[40,41],[41,-32],[-53,57],[57,58],[58,59],[59,60],[60,61],[61,-53],[-43,47],[47,48],[48,49],[49,50],[50,51],[51,-43],[-23,27],[27,28],[28,29],[29,30],[30,-23],[-63,67],[67,68],[68,69],[69,70],[70,71],[71,-63]],"/home/ipaullly/dev/parcels/sendIT/app/tests/v1/test_register.py":[[-1,1],[1,2],[2,3],[3,5],[-5,5],[5,8],[8,9],[9,22],[22,28],[28,-5],[5,36],[36,-1],[-9,10],[10,11],[11,13],[13,14],[14,17],[17,18],[18,-9],[-28,29],[29,30],[30,31],[31,32],[32,33],[33,34],[34,-28],[-22,23],[23,24],[24,25],[25,-22]],"/home/ipaullly/dev/parcels/sendIT/app/utilities/JWT_token.py":[]}} \ No newline at end of file diff --git a/app/api/v1/views.py b/app/api/v1/views.py index 37e922f..c4559d0 100644 --- a/app/api/v1/views.py +++ b/app/api/v1/views.py @@ -61,9 +61,10 @@ def get(self, id): "order" : single }), 200) else: - return make_response(jsonify({ + response = { "message" : "Invalid id" - }), 400) + } + return make_response(jsonify(response), 400) class UserOrders(Resource): """ diff --git a/app/tests/v1/test_edgecases.py b/app/tests/v1/test_edgecases.py index c52919d..586e825 100644 --- a/app/tests/v1/test_edgecases.py +++ b/app/tests/v1/test_edgecases.py @@ -27,6 +27,13 @@ def setUp(self): "email" : "house", "password" : "xgss" } + self.invalid_id = { + "item" : "seven ballons", + "pickup" : "Biashara street", + "dest" : "Kikuyu town", + "pricing": 250, + "user_id" : "12" + } def test_empty_strings_in_POST_create_order(self): """ @@ -48,5 +55,13 @@ def test_wrong_email_pattern(self): self.assertEqual(response3.status_code, 400) res = json.loads(response3.data) self.assertEqual("{'message': 'Invalid email format'}", str(res)) + + def test_invalid_parcel_id(self): + response = self.app.post('/api/v1/parcels', data=json.dumps(self.invalid_id), content_type='application/json') + self.assertEqual(response.status_code, 201) + result = self.app.get('/api/v1/parcels/30') + self.assertEqual(result.status_code, 400) + self.assertIn('"message": "Invalid id"', str(result.data)) + if __name__ == "__main__": unittest.main() \ No newline at end of file