P5-4418 validate Pwinty SKU code
This commit is contained in:
+12
-11
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
from api.lib.utils import round_half_up
|
from api.lib.utils import round_half_up
|
||||||
from api.lib.limits import calculate_canvas_limits
|
from api.lib.limits import calculate_canvas_limits
|
||||||
|
from api.lib import pwinty
|
||||||
|
|
||||||
|
|
||||||
def m2_price(
|
def m2_price(
|
||||||
@@ -300,17 +301,17 @@ def framed_print_price(
|
|||||||
sku, market, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True
|
sku, market, designer=None, reseller=None, inquiry=None, rounded=True, inc_vat=True
|
||||||
):
|
):
|
||||||
sku_prices = {
|
sku_prices = {
|
||||||
"GLOBAL-CFP-12x12": 446,
|
pwinty.GLOBAL_CFP_12x12: 446,
|
||||||
"GLOBAL-CFP-11x14": 478,
|
pwinty.GLOBAL_CFP_11x14: 478,
|
||||||
"GLOBAL-CFP-12x16": 494,
|
pwinty.GLOBAL_CFP_12x16: 494,
|
||||||
"GLOBAL-CFP-16x20": 574,
|
pwinty.GLOBAL_CFP_16x20: 574,
|
||||||
"GLOBAL-CFP-20x20": 690,
|
pwinty.GLOBAL_CFP_20x20: 690,
|
||||||
"GLOBAL-CFP-18x24": 708,
|
pwinty.GLOBAL_CFP_18x24: 708,
|
||||||
"GLOBAL-CFP-20x28": 761,
|
pwinty.GLOBAL_CFP_20x28: 761,
|
||||||
"GLOBAL-CFP-24x32": 831,
|
pwinty.GLOBAL_CFP_24x32: 831,
|
||||||
"GLOBAL-CFP-28x28": 867,
|
pwinty.GLOBAL_CFP_28x28: 867,
|
||||||
"GLOBAL-CFP-24x36": 1035,
|
pwinty.GLOBAL_CFP_24x36: 1035,
|
||||||
"GLOBAL-CFP-28x40": 1127,
|
pwinty.GLOBAL_CFP_28x40: 1127,
|
||||||
}
|
}
|
||||||
|
|
||||||
if not sku in sku_prices:
|
if not sku in sku_prices:
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
GLOBAL_CFP_12x12 = "GLOBAL-CFP-12x12"
|
||||||
|
GLOBAL_CFP_11x14 = "GLOBAL-CFP-11x14"
|
||||||
|
GLOBAL_CFP_12x16 = "GLOBAL-CFP-12x16"
|
||||||
|
GLOBAL_CFP_16x20 = "GLOBAL-CFP-16x20"
|
||||||
|
GLOBAL_CFP_20x20 = "GLOBAL-CFP-20x20"
|
||||||
|
GLOBAL_CFP_18x24 = "GLOBAL-CFP-18x24"
|
||||||
|
GLOBAL_CFP_20x28 = "GLOBAL-CFP-20x28"
|
||||||
|
GLOBAL_CFP_24x32 = "GLOBAL-CFP-24x32"
|
||||||
|
GLOBAL_CFP_28x28 = "GLOBAL-CFP-28x28"
|
||||||
|
GLOBAL_CFP_24x36 = "GLOBAL-CFP-24x36"
|
||||||
|
GLOBAL_CFP_28x40 = "GLOBAL-CFP-28x40"
|
||||||
|
|
||||||
|
SKU_CODES = [
|
||||||
|
GLOBAL_CFP_12x12,
|
||||||
|
GLOBAL_CFP_11x14,
|
||||||
|
GLOBAL_CFP_12x16,
|
||||||
|
GLOBAL_CFP_16x20,
|
||||||
|
GLOBAL_CFP_20x20,
|
||||||
|
GLOBAL_CFP_18x24,
|
||||||
|
GLOBAL_CFP_20x28,
|
||||||
|
GLOBAL_CFP_24x32,
|
||||||
|
GLOBAL_CFP_28x28,
|
||||||
|
GLOBAL_CFP_24x36,
|
||||||
|
GLOBAL_CFP_28x40,
|
||||||
|
]
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
from flask import Blueprint, request, jsonify, abort
|
from flask import Blueprint, request, jsonify, abort
|
||||||
from api.helpers import check_api_key
|
from api.helpers import check_api_key
|
||||||
from api.validators import validate_territory, validate_number
|
from api.validators import validate_territory, validate_number, validate_any_of
|
||||||
from api.models.inquiry import Inquiry
|
from api.models.inquiry import Inquiry
|
||||||
from api.models.product import Material, Product
|
from api.models.product import Material, Product
|
||||||
from api.models.contract_customer import ContractCustomer
|
from api.models.contract_customer import ContractCustomer
|
||||||
from api.models import market as market_model
|
from api.models import market as market_model
|
||||||
|
from api.lib import pwinty
|
||||||
from api.lib.prices import (
|
from api.lib.prices import (
|
||||||
wallpaper_price,
|
wallpaper_price,
|
||||||
canvas_price,
|
canvas_price,
|
||||||
@@ -242,6 +243,7 @@ def poster_hanger():
|
|||||||
|
|
||||||
@mod.route("/framed-print", methods=["GET"])
|
@mod.route("/framed-print", methods=["GET"])
|
||||||
@validate_territory("territory")
|
@validate_territory("territory")
|
||||||
|
@validate_any_of("sku", pwinty.SKU_CODES)
|
||||||
def framed_print():
|
def framed_print():
|
||||||
sku = request.args.get("sku", type=str)
|
sku = request.args.get("sku", type=str)
|
||||||
market = market_model.from_territory(request.args.get("territory"))
|
market = market_model.from_territory(request.args.get("territory"))
|
||||||
|
|||||||
@@ -94,3 +94,22 @@ def validate_territory(*keys):
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
def validate_any_of(key, values):
|
||||||
|
def decorator(f):
|
||||||
|
@wraps(f)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
_check_parameter_exists(key)
|
||||||
|
value = request.args.get(key)
|
||||||
|
if not value in values:
|
||||||
|
raise ValidationError(
|
||||||
|
"{} contains an invalid value, must be one of: {}".format(
|
||||||
|
key, values
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from api import create_app, db
|
|||||||
from api.models.product import Material, Product
|
from api.models.product import Material, Product
|
||||||
from api.models.inquiry import Inquiry
|
from api.models.inquiry import Inquiry
|
||||||
from api.models.designer import Designer
|
from api.models.designer import Designer
|
||||||
|
from api.lib import pwinty
|
||||||
|
|
||||||
|
|
||||||
class TestEndpoints(flask_testing.TestCase):
|
class TestEndpoints(flask_testing.TestCase):
|
||||||
@@ -209,3 +210,13 @@ class TestEndpoints(flask_testing.TestCase):
|
|||||||
self.assert200(response)
|
self.assert200(response)
|
||||||
expected = [{"price": 557.5, "price_excl_vat": 446, "sku": "GLOBAL-CFP-12x12"}]
|
expected = [{"price": 557.5, "price_excl_vat": 446, "sku": "GLOBAL-CFP-12x12"}]
|
||||||
self.assertEqual(expected, response.json["data"])
|
self.assertEqual(expected, response.json["data"])
|
||||||
|
|
||||||
|
def test_framed_print_invalid_sku(self):
|
||||||
|
response = self.client.get("/prices/framed-print?sku=invalid&territory=SE")
|
||||||
|
self.assert400(response)
|
||||||
|
self.assertEqual(
|
||||||
|
"sku contains an invalid value, must be one of: {}".format(
|
||||||
|
pwinty.SKU_CODES
|
||||||
|
),
|
||||||
|
response.json["message"],
|
||||||
|
)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from api.validators import (
|
|||||||
validate_number,
|
validate_number,
|
||||||
validate_territory,
|
validate_territory,
|
||||||
validate_jsonschema,
|
validate_jsonschema,
|
||||||
|
validate_any_of,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -138,3 +139,18 @@ class TestValidators(flask_testing.TestCase):
|
|||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
).data,
|
).data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_validate_any_of(self):
|
||||||
|
app = self.app
|
||||||
|
|
||||||
|
@app.route("/", methods=["GET"])
|
||||||
|
@validate_any_of("color", ["red", "green", "blue"])
|
||||||
|
def index():
|
||||||
|
return "ok"
|
||||||
|
|
||||||
|
self.assertEqual(b"No color is specified", self.client.get("/").data)
|
||||||
|
self.assertEqual(
|
||||||
|
b"color contains an invalid value, must be one of: ['red', 'green', 'blue']",
|
||||||
|
self.client.get("/?color=black").data,
|
||||||
|
)
|
||||||
|
self.assertEqual(b"ok", self.client.get("/?color=blue").data)
|
||||||
|
|||||||
Reference in New Issue
Block a user