Commit 840b2c9f authored by Jacek Furmankiewicz's avatar Jacek Furmankiewicz

BDDs for complex nested customer/customer address test cases

parent 80435508
...@@ -242,7 +242,7 @@ class RequestRouter: ...@@ -242,7 +242,7 @@ class RequestRouter:
self.__cachedUrls[request.method][path][contentType] = CachedUrl(instance, args) self.__cachedUrls[request.method][path][contentType] = CachedUrl(instance, args)
urlRouterInstance,pathargs = instance,args urlRouterInstance,pathargs = instance,args
break break
#actual call #actual call
if urlRouterInstance != None and pathargs != None: if urlRouterInstance != None and pathargs != None:
allargs = copy.deepcopy(pathargs) allargs = copy.deepcopy(pathargs)
...@@ -283,7 +283,7 @@ class RequestRouter: ...@@ -283,7 +283,7 @@ class RequestRouter:
response = self.__generateResponse(request, val, request.code) response = self.__generateResponse(request, val, request.code)
except exceptions.TypeError as ex: except exceptions.TypeError as ex:
log.err(ex) log.msg(ex,logLevel=logging.WARN)
response = self.__createErrorResponse(request,400,"%s" % ex) response = self.__createErrorResponse(request,400,"%s" % ex)
except RESTException as ex: except RESTException as ex:
...@@ -299,7 +299,7 @@ class RequestRouter: ...@@ -299,7 +299,7 @@ class RequestRouter:
response = self.__createErrorResponse(request,500,"Unexpected server error: %s\n%s" % (type(ex),ex)) response = self.__createErrorResponse(request,500,"Unexpected server error: %s\n%s" % (type(ex),ex))
else: else:
log.msg(ex,logLevel=logging.WARN) log.msg("URL %s not found" % path,logLevel=logging.WARN)
response = self.__createErrorResponse(request,404,"URL '%s' not found\n" % request.path) response = self.__createErrorResponse(request,404,"URL '%s' not found\n" % request.path)
except Exception as ex: except Exception as ex:
......
...@@ -16,7 +16,7 @@ Feature: REST App ...@@ -16,7 +16,7 @@ Feature: REST App
Then I expect HTTP code 201 Then I expect HTTP code 201
@full @customer
Scenario: Full Customer lifecycle Scenario: Full Customer lifecycle
When as user 'None:None' I GET 'http://127.0.0.1:8085/customer' When as user 'None:None' I GET 'http://127.0.0.1:8085/customer'
Then I expect HTTP code 200 Then I expect HTTP code 200
...@@ -24,19 +24,19 @@ Feature: REST App ...@@ -24,19 +24,19 @@ Feature: REST App
""" """
[ [
{ {
"addresses": [], "addresses": {},
"customerId": "d2", "customerId": "d2",
"firstName": "John", "firstName": "John",
"lastName": "Doe2" "lastName": "Doe2"
}, },
{ {
"addresses": [], "addresses": {},
"customerId": "d3", "customerId": "d3",
"firstName": "John", "firstName": "John",
"lastName": "Doe3" "lastName": "Doe3"
}, },
{ {
"addresses": [], "addresses": {},
"customerId": "d1", "customerId": "d1",
"firstName": "John", "firstName": "John",
"lastName": "Doe1" "lastName": "Doe1"
...@@ -51,7 +51,7 @@ Feature: REST App ...@@ -51,7 +51,7 @@ Feature: REST App
And I expect JSON content And I expect JSON content
""" """
{ {
"addresses": [], "addresses": {},
"customerId": "c1", "customerId": "c1",
"firstName": "John", "firstName": "John",
"lastName": "Doe" "lastName": "Doe"
...@@ -65,7 +65,7 @@ Feature: REST App ...@@ -65,7 +65,7 @@ Feature: REST App
And I expect JSON content And I expect JSON content
""" """
{ {
"addresses": [], "addresses": {},
"customerId": "c1", "customerId": "c1",
"firstName": "Jill", "firstName": "Jill",
"lastName": "Jones" "lastName": "Jones"
...@@ -85,4 +85,27 @@ Feature: REST App ...@@ -85,4 +85,27 @@ Feature: REST App
""" """
[] []
""" """
@customer_address
Scenario: Full Customer Address lifecycle
When as user 'None:None' I GET 'http://127.0.0.1:8085/customer/d1/address'
Then I expect HTTP code 200
And I expect JSON content
"""
{}
"""
# add 1
When as user 'None:None' I POST 'http://127.0.0.1:8085/customer/d1/address' with 'addressId=HOME&streetNumber=100&streetName=MyStreet&stateCode=CA&countryCode=US'
Then I expect HTTP code 201
When as user 'None:None' I GET 'http://127.0.0.1:8085/customer/d1/address/HOME'
Then I expect HTTP code 200
And I expect JSON content
"""
{
"countryCode": "US",
"stateCode": "CA",
"streetName": "MyStreet",
"streetNumber": "100"
}
"""
\ No newline at end of file
Using step definitions from: '../steps' Using step definitions from: '../steps'
@url_routing
Feature: URL routing Feature: URL routing
CorePost should be able to CorePost should be able to
correctly route requests correctly route requests
......
...@@ -5,72 +5,132 @@ Server tests ...@@ -5,72 +5,132 @@ Server tests
from corepost import Response, NotFoundException, AlreadyExistsException from corepost import Response, NotFoundException, AlreadyExistsException
from corepost.web import RESTResource, route, Http from corepost.web import RESTResource, route, Http
from twisted.python import log
import sys
#log.startLogging(sys.stdout)
class DB(): class DB():
"""Fake in-memory DB for testing""" """Fake in-memory DB for testing"""
customers = {} customers = {}
class Customer(): @classmethod
def getAllCustomers(cls):
return DB.customers.values()
@classmethod
def getCustomer(cls,customerId):
if customerId in DB.customers:
return DB.customers[customerId]
else:
raise NotFoundException("Customer",customerId)
@classmethod
def saveCustomer(cls,customer):
if customer.customerId in DB.customers:
raise AlreadyExistsException("Customer",customer.customerId)
else:
DB.customers[customer.customerId] = customer
@classmethod
def deleteCustomer(cls,customerId):
if customerId in DB.customers:
del(DB.customers[customerId])
else:
raise NotFoundException("Customer",customerId)
@classmethod
def deleteAllCustomers(cls):
DB.customers.clear()
@classmethod
def getCustomerAddress(cls,customerId,addressId):
c = DB.getCustomer(customerId)
if addressId in c.addresses:
return c.addresses[addressId]
else:
raise NotFoundException("Customer Address",addressId)
class Customer:
"""Represents customer entity""" """Represents customer entity"""
def __init__(self,customerId,firstName,lastName): def __init__(self,customerId,firstName,lastName):
(self.customerId,self.firstName,self.lastName) = (customerId,firstName,lastName) (self.customerId,self.firstName,self.lastName) = (customerId,firstName,lastName)
self.addresses = [] self.addresses = {}
class CustomerAddress(): class CustomerAddress:
"""Represents customer address entity""" """Represents customer address entity"""
def __init__(self,customer,streetNumber,streetName,stateCode,countryCode): def __init__(self,streetNumber,streetName,stateCode,countryCode):
(self.customer,self.streetNumber,self.streetName.self.stateCode,self.countryCode) = (customer,streetNumber,streetName,stateCode,countryCode) (self.streetNumber,self.streetName,self.stateCode,self.countryCode) = (streetNumber,streetName,stateCode,countryCode)
class CustomerRestService(): class CustomerRESTService():
path = "/customer" path = "/customer"
@route("/") @route("/")
def getAll(self,request): def getAll(self,request):
return DB.customers.values() return DB.getAllCustomers()
@route("/<customerId>") @route("/<customerId>")
def get(self,request,customerId): def get(self,request,customerId):
if customerId in DB.customers: return DB.getCustomer(customerId)
return DB.customers[customerId]
else:
raise NotFoundException("Customer", customerId)
@route("/",Http.POST) @route("/",Http.POST)
def post(self,request,customerId,firstName,lastName): def post(self,request,customerId,firstName,lastName):
if customerId in DB.customers: customer = Customer(customerId, firstName, lastName)
raise AlreadyExistsException("Customer",customerId) DB.saveCustomer(customer)
else: return Response(201)
DB.customers[customerId] = Customer(customerId, firstName, lastName)
return Response(201)
@route("/<customerId>",Http.PUT) @route("/<customerId>",Http.PUT)
def put(self,request,customerId,firstName,lastName): def put(self,request,customerId,firstName,lastName):
if customerId in DB.customers: c = DB.getCustomer(customerId)
DB.customers[customerId].firstName = firstName (c.firstName,c.lastName) = (firstName,lastName)
DB.customers[customerId].lastName = lastName return Response(200)
return Response(200)
else:
raise NotFoundException("Customer", customerId)
@route("/<customerId>",Http.DELETE) @route("/<customerId>",Http.DELETE)
def delete(self,request,customerId): def delete(self,request,customerId):
if customerId in DB.customers: DB.deleteCustomer(customerId)
del(DB.customers[customerId]) return Response(200)
return Response(200)
else:
raise NotFoundException("Customer", customerId)
@route("/",Http.DELETE) @route("/",Http.DELETE)
def deleteAll(self,request): def deleteAll(self,request):
DB.customers.clear() DB.deleteAllCustomers()
return Response(200) return Response(200)
class CustomerAddressRESTService():
path = "/customer/<customerId>/address"
@route("/")
def getAll(self,request,customerId):
return DB.getCustomer(customerId).addresses
@route("/<addressId>")
def get(self,request,customerId,addressId):
return DB.getCustomerAddress(customerId, addressId)
@route("/",Http.POST)
def post(self,request,customerId,addressId,streetNumber,streetName,stateCode,countryCode):
c = DB.getCustomer(customerId)
address = CustomerAddress(streetNumber,streetName,stateCode,countryCode)
c.addresses[addressId] = address
return Response(201)
@route("/<addressId>",Http.PUT)
def put(self,request,customerId,addressId,streetNumber,streetName,stateCode,countryCode):
address = DB.getCustomerAddress(customerId, addressId)
(address.streetNumber,address.streetName,address.stateCode,address.countryCode) = (streetNumber,streetName,stateCode,countryCode)
return Response(200)
@route("/<addressId>",Http.DELETE)
def delete(self,request,customerId,addressId):
DB.getCustomerAddress(customerId, addressId) #validate address exists
del(DB.getCustomer(customerId).addresses[addressId])
return Response(200)
@route("/",Http.DELETE)
def deleteAll(self,request,customerId):
c = DB.getCustomer(customerId)
c.addresses = {}
return Response(200)
def run_rest_app(): def run_rest_app():
app = RESTResource((CustomerRestService(),)) app = RESTResource((CustomerRESTService(),CustomerAddressRESTService()))
app.run(8085) app.run(8085)
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment