Skip to content

Commit

Permalink
Merge pull request #36 from JoshuaOndieki/ft-register-vehicle-158860854
Browse files Browse the repository at this point in the history
[Delivers #158860854] Register Vehicle Endpoint
  • Loading branch information
JoshuaOndieki committed Jul 7, 2018
2 parents ef5db1b + 0a4a5df commit 450b2b8
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 2 deletions.
33 changes: 33 additions & 0 deletions ridemyway/api/v2/controllers/vehicle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
Controller for endpoints on user
"""
from flask_jwt_extended import get_jwt_identity

from ridemyway.utils.response import Response
from ridemyway.utils.db_queries import (select_user,
insert_vehicle, select_vehicle)


class VehicleController():
"""
Registers a vehicle
"""

def register(self, **kwargs):
"""
register vehicle
"""
username = get_jwt_identity()
self.user = select_user(username)
if self.user['usertype'] == 'driver':
vehicle = select_vehicle(kwargs['number_plate'])
if vehicle:
message = 'A vehicle with that numberplate is registered'
return Response.failed(message=message), 409
kwargs['driver'] = self.user['username']
reg_vehicle = insert_vehicle(**kwargs)
if reg_vehicle:
message = 'Vehicle registered successfully'
return Response.success(message=message), 201
message = 'Only drivers can register vehicles'
return Response.failed(message=message), 403
31 changes: 31 additions & 0 deletions ridemyway/api/v2/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@

from .controllers.auth import AuthController
from .controllers.user import UserController
from .controllers.vehicle import VehicleController
from ridemyway.utils import errors
from ridemyway.utils.response import Response


auth = AuthController()
user = UserController()
a_vehicle = VehicleController()


class Signup(Resource):
Expand Down Expand Up @@ -130,3 +132,32 @@ def put(self):
if self.errors:
return errors, 422
return user.edit_user(**self.data)


class Vehicle(Resource):
"""
Resource for adding a vehicle
"""

def __init__(self):
self.parser = reqparse.RequestParser()
self.parser.add_argument('number_plate',
help='This field cannot be blank',
required=True)
self.parser.add_argument('vehicle_type',
help='This field cannot be blank',
required=True)
self.parser.add_argument('color',
help='This field cannot be blank',
required=True)
self.parser.add_argument('capacity',
help='This field cannot be blank',
required=True)

@jwt_required
def post(self):
self.data = self.parser.parse_args()
vehicle_errors = errors.vehicle_errors(**self.data)
if vehicle_errors:
return vehicle_errors, 422
return a_vehicle.register(**self.data)
1 change: 1 addition & 0 deletions ridemyway/api/v2/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
add(r.Logout, '/auth/logout') # POST
add(r.GetUser, '/users/<username>') # GET
add(r.EditUser, '/users') # PUT
add(r.Vehicle, '/vehicle') # POST
4 changes: 2 additions & 2 deletions ridemyway/tests/tests_v2/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,15 @@
VALID_VEHICLE = {
'model': 'Model1',
'number_plate': 'KDF-A12',
'type': 'TypeA',
'vehicle_type': 'TypeA',
'color': 'Color Y',
'capacity': 4
}

INVALID_VEHICLE_CAPACITY = {
'model': 'Model1',
'number_plate': 'KDF-A12',
'type': 'TypeA',
'vehicle_type': 'TypeA',
'color': 'Color Y',
'capacity': 4.1
}
Empty file.
79 changes: 79 additions & 0 deletions ridemyway/tests/tests_v2/test_vehicle/test_vehicle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""
Module for testing add vehicle
"""

import unittest
import json

from ridemyway.tests.tests_v2 import V2BaseTest
from ridemyway.tests.tests_v2.urls import SIGNUP, LOGIN, VEHICLE
from ridemyway.tests.tests_v2.data import (VALID_RIDER,
VALID_DRIVER,
VALID_VEHICLE,
INVALID_VEHICLE_CAPACITY)


class TestCreateVehicle(V2BaseTest):
"""
Tests Add Vehicle API endpoint
- Ride: '/api/v2/vehicle' # POST
"""

def authenticate(self):
self.client().post(SIGNUP, data=VALID_DRIVER)
self.response = self.client().post(LOGIN, data=VALID_DRIVER)
access_token = json.loads(self.response.data.decode())['access_token']
return access_token

def test_add_vehicle_successful(self):
access_token = self.authenticate()
self.response = self.client().post(VEHICLE, data=VALID_VEHICLE,
headers=dict(
Authorization="Bearer " +
access_token))
self.assertEqual(self.response.status_code, 201,
msg='Should create a vehicle successfully!')

def test_doesnot_allow_duplicate_vehicles(self):
access_token = self.authenticate()
self.client().post(VEHICLE, data=VALID_VEHICLE,
headers=dict(
Authorization="Bearer " + access_token))
self.response = self.client().post(VEHICLE, data=VALID_VEHICLE,
headers=dict(
Authorization="Bearer " +
access_token))
self.assertEqual(self.response.status_code, 409,
msg='Should not add duplicate vehicles!')

def test_add_vehicle_unsuccessful_with_rider(self):
self.client().post(SIGNUP, data=VALID_RIDER)
self.response = self.client().post(LOGIN, data=VALID_RIDER)
access_token = json.loads(self.response.data.decode())['access_token']
self.response = self.client().post(VEHICLE, data=VALID_VEHICLE,
headers=dict(
Authorization="Bearer " +
access_token))
result = json.loads(self.response.data.decode())
self.assertEqual(result['message'],
'Only drivers can register vehicles',
msg='Only drivers can register vehicles')
self.assertEqual(self.response.status_code, 403)

def test_does_not_add_vehicle_with_invalid_capacity(self):
access_token = self.authenticate()

self.response = self.client().post(VEHICLE, data=INVALID_VEHICLE_CAPACITY,
headers=dict(
Authorization="Bearer " +
access_token))
result = json.loads(self.response.data.decode())
print(result)
self.assertEqual(result['errors']['capacity'],
'Capacity is in invalid format',
msg='Should only accept integer capacity!')
self.assertEqual(self.response.status_code, 422)


if __name__ == '__main__':
unittest.main()
31 changes: 31 additions & 0 deletions ridemyway/utils/db_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,34 @@ def update_user(**kwargs):
return True
except psycopg2.Error:
return False


def select_vehicle(number_plate=None):
sql = """
SELECT * FROM uservehicle WHERE number_plate=%s;
"""
cur = app.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
try:
cur.execute(sql, (number_plate,))
vehicle = cur.fetchone()
app.conn.commit()
cur.close()
return vehicle
except psycopg2.Error:
return False


def insert_vehicle(**kwargs):
sql = "INSERT INTO uservehicle (number_plate, driver, vehicle_type, color, capacity) VALUES (%s, %s, %s, %s, %s)"
data = (kwargs['number_plate'],
kwargs['driver'],
kwargs['vehicle_type'],
kwargs['color'],
kwargs['capacity'])
cur = app.conn.cursor()
try:
cur.execute(sql, data)
app.conn.commit()
return True
except psycopg2.Error:
app.conn.rollback()
12 changes: 12 additions & 0 deletions ridemyway/utils/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,15 @@ def edit_errors(**kwargs):
meta = {'errors': len(errors)}
if errors:
return Response.failed(meta=meta, message=message, errors=errors)


def vehicle_errors(**kwargs):
message = 'Could not add vehicle'
errors = {}
if not is_int(kwargs['capacity']):
errors['capacity'] = 'Capacity is in invalid format'
if is_number(kwargs['number_plate']):
errors['number_plate'] = 'Invalid vehicle number plate |Expects string'
meta = {'errors': len(errors)}
if errors:
return Response.failed(meta=meta, message=message, errors=errors)

0 comments on commit 450b2b8

Please sign in to comment.