Skip to content

Commit d8674a8

Browse files
authored
Merge pull request #197 from allanarmstrong/price_rules
Price rules implementation
2 parents 740af94 + a6886e6 commit d8674a8

9 files changed

+197
-1
lines changed

shopify/resources/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,6 @@
5454
from .draft_order import DraftOrder
5555
from .draft_order_invoice import DraftOrderInvoice
5656
from .report import Report
57-
57+
from .price_rule import PriceRule
58+
from .discount_code import DiscountCode
5859
from ..base import ShopifyResource

shopify/resources/discount_code.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from ..base import ShopifyResource
2+
3+
class DiscountCode(ShopifyResource):
4+
_prefix_source = "/admin/price_rules/$price_rule_id/"

shopify/resources/price_rule.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from ..base import ShopifyResource
2+
from .discount_code import DiscountCode
3+
4+
class PriceRule(ShopifyResource):
5+
def add_discount_code(self, discount_code = DiscountCode()):
6+
resource = self.post("discount_codes", discount_code.encode())
7+
return DiscountCode(PriceRule.format.decode(resource.body))
8+
9+
def discount_codes(self):
10+
return DiscountCode.find(price_rule_id=self.id)

test/discount_code_test.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import shopify
2+
import json
3+
from test.test_helper import TestCase
4+
5+
6+
class DiscountCodeTest(TestCase):
7+
def setUp(self):
8+
super(DiscountCodeTest, self).setUp()
9+
self.fake("price_rules/1213131/discount_codes/34", method='GET', body=self.load_fixture('discount_code'))
10+
self.discount_code = shopify.DiscountCode.find(34, price_rule_id=1213131)
11+
12+
def test_find_a_specific_discount_code(self):
13+
discount_code = shopify.DiscountCode.find(34, price_rule_id=1213131)
14+
self.assertEqual("25OFF", discount_code.code)
15+
16+
def test_update_a_specific_discount_code(self):
17+
self.discount_code.code = 'BOGO'
18+
self.fake('price_rules/1213131/discount_codes/34',
19+
method='PUT',
20+
status=200,
21+
body=self.load_fixture('discount_code'),
22+
headers={'Content-type': 'application/json'})
23+
self.discount_code.save()
24+
self.assertEqual('BOGO',
25+
json.loads(self.http.request.data.decode("utf-8"))["discount_code"]["code"]
26+
)
27+
def test_delete_a_specific_discount_code(self):
28+
self.fake('price_rules/1213131/discount_codes/34', method='DELETE', body='destroyed')
29+
self.discount_code.destroy()
30+
self.assertEqual('DELETE', self.http.request.get_method())
31+
32+
33+

test/fixtures/discount_code.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"discount_code": {
3+
"code": "25OFF",
4+
"id": 34,
5+
"usage_count": 3,
6+
"created_at": "2016-09-11T09:00:00-04:00",
7+
"updated_at": "2016-09-11T09:30:00-04:00"
8+
}
9+
}

test/fixtures/discount_codes.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"discount_codes": [
3+
{
4+
"code": "25OFF",
5+
"id": 34,
6+
"usage_count": 3,
7+
"created_at": "2016-09-11T09:00:00-04:00",
8+
"updated_at": "2016-09-11T09:30:00-04:00"
9+
}
10+
]
11+
}

test/fixtures/price_rule.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"price_rule": {
3+
"id": 1213131,
4+
"title": "BOGO",
5+
"target_type": "line_item",
6+
"target_selection": "all",
7+
"allocation_method": "across",
8+
"value_type": "percentage",
9+
"value": -100,
10+
"once_per_customer": true,
11+
"usage_limit": null,
12+
"customer_selection": "all",
13+
"prerequisite_subtotal_range": null,
14+
"prerequisite_shipping_price_range": null,
15+
"starts_at": "2017-05-30T04:13:56Z",
16+
"ends_at": null
17+
}
18+
}

test/fixtures/price_rules.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"price_rules": [
3+
{
4+
"id": 1213131,
5+
"title": "BOGO",
6+
"target_type": "line_item",
7+
"target_selection": "all",
8+
"allocation_method": "across",
9+
"value_type": "percentage",
10+
"value": -100,
11+
"once_per_customer": true,
12+
"usage_limit": null,
13+
"customer_selection": "all",
14+
"prerequisite_subtotal_range": null,
15+
"prerequisite_shipping_price_range": null,
16+
"starts_at": "2017-05-30T04:13:56Z",
17+
"ends_at": null
18+
},
19+
{
20+
"id": 1213132,
21+
"title": "TENOFF",
22+
"target_type": "line_item",
23+
"target_selection": "all",
24+
"allocation_method": "each",
25+
"value_type": "percentage",
26+
"value": -10,
27+
"once_per_customer": true,
28+
"usage_limit": null,
29+
"customer_selection": "all",
30+
"prerequisite_subtotal_range": null,
31+
"prerequisite_shipping_price_range": null,
32+
"starts_at": "2017-05-30T04:13:56Z",
33+
"ends_at": null
34+
}
35+
]
36+
}

test/price_rules_test.py

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import json
2+
from test.test_helper import TestCase
3+
4+
import shopify
5+
6+
7+
class PriceRuleTest(TestCase):
8+
9+
def setUp(self):
10+
super(PriceRuleTest, self).setUp()
11+
self.fake('price_rules/1213131', body=self.load_fixture('price_rule'))
12+
self.price_rule = shopify.PriceRule.find(1213131)
13+
14+
def test_get_price_rule(self):
15+
self.fake('price_rule/1213131', method='GET', status=200, body=self.load_fixture('price_rule'))
16+
price_rule = shopify.PriceRule.find(1213131)
17+
self.assertEqual(1213131, price_rule.id)
18+
19+
def test_get_all_price_rules(self):
20+
self.fake('price_rules',
21+
method='GET',
22+
code=200,
23+
body=self.load_fixture('price_rules'))
24+
price_rules = shopify.PriceRule.find()
25+
self.assertEqual(2, len(price_rules))
26+
27+
def test_update_price_rule(self):
28+
self.price_rule.title = "Buy One Get One"
29+
self.fake('price_rules/1213131', method='PUT', status=200, body=self.load_fixture('price_rule'), headers={'Content-type': 'application/json'})
30+
self.price_rule.save()
31+
self.assertEqual('Buy One Get One', json.loads(self.http.request.data.decode("utf-8"))['price_rule']['title'])
32+
33+
34+
def test_delete_price_rule(self):
35+
self.fake('price_rules/1213131', method='DELETE', body='destroyed')
36+
self.price_rule.destroy()
37+
self.assertEqual('DELETE', self.http.request.get_method())
38+
39+
def test_price_rule_creation(self):
40+
self.fake('price_rules',
41+
method='POST',
42+
code=202,
43+
body=self.load_fixture('price_rule'),
44+
headers={'Content-type': 'application/json'})
45+
price_rule = shopify.PriceRule.create({
46+
"title": "BOGO",
47+
"target_type": "line_item",
48+
"target_selection": "all",
49+
"allocation_method": "across",
50+
"value_type": "percentage",
51+
"value": -100,
52+
"once_per_customer": 'true',
53+
"customer_selection": 'all'
54+
})
55+
self.assertEqual("BOGO", price_rule.title)
56+
self.assertEqual("line_item", price_rule.target_type)
57+
58+
def test_get_discount_codes(self):
59+
self.fake('price_rules/1213131/discount_codes', method='GET', status=200, body=self.load_fixture('discount_codes'))
60+
discount_codes = self.price_rule.discount_codes()
61+
self.assertEqual(1, len(discount_codes))
62+
63+
def test_add_discount_code(self):
64+
price_rule_discount_fixture = self.load_fixture('discount_code')
65+
discount_code = json.loads(price_rule_discount_fixture.decode("utf-8"))
66+
self.fake('price_rules/1213131/discount_codes',
67+
method='POST',
68+
body=price_rule_discount_fixture,
69+
headers={'Content-type': 'application/json'})
70+
price_rule_discount_response = self.price_rule.add_discount_code(shopify.DiscountCode(discount_code['discount_code']))
71+
self.assertEqual(discount_code, json.loads(self.http.request.data.decode("utf-8")))
72+
self.assertIsInstance(price_rule_discount_response, shopify.DiscountCode)
73+
self.assertEqual(discount_code['discount_code']['code'], price_rule_discount_response.code)
74+

0 commit comments

Comments
 (0)