Skip to content

Commit 0172a02

Browse files
Merge pull request #643 from recurly/external-product-support
Support for external products & references
2 parents ad6cda7 + 97c5333 commit 0172a02

File tree

8 files changed

+165
-5
lines changed

8 files changed

+165
-5
lines changed

recurly/__init__.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2177,13 +2177,26 @@ class ExternalProduct(Resource):
21772177
collection_path = 'external_products'
21782178

21792179
attributes = (
2180-
'plan',
2180+
'plan_code',
21812181
'name',
21822182
'created_at',
21832183
'updated_at',
21842184
'external_product_references'
21852185
)
21862186

2187+
def create_external_product_reference(self, external_product_reference):
2188+
"""Creates an external_product_reference on an existing product_reference. If you are
2189+
creating an product_reference, you can embed the external_product_references with the
2190+
request"""
2191+
url = urljoin(self._url, '/external_product_references')
2192+
return external_product_reference.post(url)
2193+
2194+
def get_external_product_reference(self, external_product_reference_uuid):
2195+
"""Fetch an external product reference from an external account."""
2196+
url = urljoin(self._url, '/external_product_references/{}'.format(external_product_reference_uuid))
2197+
resp, elem = ExternalProductReference().element_for_url(url)
2198+
return ExternalProductReference().from_element(elem)
2199+
21872200
class ExportDate(Resource):
21882201
nodename = 'export_date'
21892202
collection_path = 'export_dates'
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
POST https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references HTTP/1.1
2+
X-Api-Version: {api-version}
3+
Accept: application/xml
4+
Authorization: Basic YXBpa2V5Og==
5+
User-Agent: {user-agent}
6+
Content-Type: application/xml; charset=utf-8
7+
8+
<?xml version="1.0" encoding="UTF-8"?>
9+
<external_product_reference>
10+
<external_connection_type>google_play_store</external_connection_type>
11+
<reference_code>948eb638-bef5-4e48-a955-2646d7e353e5</reference_code>
12+
</external_product_reference>
13+

14+
HTTP/1.1 201 Created
15+
Content-Type: application/xml; charset=utf-8
16+
Location: https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/swafyj8wqw6n
17+
18+
<?xml version="1.0" encoding="UTF-8"?>
19+
<external_product_reference href="https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/swafyj8wqw6n">
20+
<id>swafyj8wqw6n</id>
21+
<reference_code>948eb638-bef5-4e48-a955-2646d7e353e5</reference_code>
22+
<external_connection_type>google_play_store</external_connection_type>
23+
<created_at type="datetime">2023-05-15T18:46:48Z</created_at>
24+
<updated_at type="datetime">2023-05-15T18:46:48Z</updated_at>
25+
</external_product_reference>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
DELETE https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/ru1u1gn5otsv HTTP/1.1
2+
X-Api-Version: {api-version}
3+
Accept: application/xml
4+
Authorization: Basic YXBpa2V5Og==
5+
User-Agent: {user-agent}
6+
7+

8+
HTTP/1.1 204 No Content
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
GET https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/ru1u1gn5otsv HTTP/1.1
2+
X-Api-Version: {api-version}
3+
Accept: application/xml
4+
Authorization: Basic YXBpa2V5Og==
5+
User-Agent: {user-agent}
6+
7+

8+
HTTP/1.1 200 OK
9+
Content-Type: application/xml; charset=utf-8
10+
11+
<?xml version="1.0" encoding="UTF-8"?>
12+
<external_product_reference href="https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/ru1u1gn5otsv">
13+
<id>ru1u1gn5otsv</id>
14+
<reference_code>code_test_google</reference_code>
15+
<external_connection_type>google_play_store</external_connection_type>
16+
<created_at type="datetime">2022-11-03T21:12:35Z</created_at>
17+
<updated_at type="datetime">2022-11-03T21:12:35Z</updated_at>
18+
</external_product_reference>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
DELETE https://api.recurly.com/v2/external_products/ru1u1gms4msk HTTP/1.1
2+
X-Api-Version: {api-version}
3+
Accept: application/xml
4+
Authorization: Basic YXBpa2V5Og==
5+
User-Agent: {user-agent}
6+
7+

8+
HTTP/1.1 204 No Content

tests/fixtures/external-product/get.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,23 @@ HTTP/1.1 200 OK
99
Content-Type: application/xml; charset=utf-8
1010

1111
<?xml version="1.0" encoding="UTF-8"?>
12-
<external_product href="https://paulo.recurly.dev:3000/v2/external_products/ru1u1gms4msk">
13-
<plan href="https://paulo.recurly.dev:3000/v2/plans/5_abril">
12+
<external_product href="https://api.recurly.com/v2/external_products/ru1u1gms4msk">
13+
<plan href="https://api.recurly.com/v2/plans/5_abril">
1414
<plan_code>5_abril</plan_code>
1515
<name>5 de abril</name>
1616
</plan>
1717
<name>product_name_teste</name>
1818
<created_at type="datetime">2022-11-03T21:12:35Z</created_at>
1919
<updated_at type="datetime">2022-11-03T21:12:35Z</updated_at>
2020
<external_product_references type="array">
21-
<external_product_reference>
21+
<external_product_reference href="https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/ru1u1gn5otsv">
2222
<id>ru1u1gn5otsv</id>
2323
<reference_code>code_teste_google</reference_code>
2424
<external_connection_type>google_play_store</external_connection_type>
2525
<created_at type="datetime">2022-11-03T21:12:35Z</created_at>
2626
<updated_at type="datetime">2022-11-03T21:12:35Z</updated_at>
2727
</external_product_reference>
28-
<external_product_reference>
28+
<external_product_reference href="https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/ru1u1gn7ebod">
2929
<id>ru1u1gn7ebod</id>
3030
<reference_code>code_teste_apple</reference_code>
3131
<external_connection_type>apple_app_store</external_connection_type>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
PUT https://api.recurly.com/v2/external_products/ru1u1gms4msk HTTP/1.1
2+
X-Api-Version: {api-version}
3+
Accept: application/xml
4+
Authorization: Basic YXBpa2V5Og==
5+
User-Agent: {user-agent}
6+
Content-Type: application/xml; charset=utf-8
7+
8+
<?xml version="1.0" encoding="UTF-8"?>
9+
<external_product>
10+
<plan_code>test-plan</plan_code>
11+
</external_product>
12+

13+
HTTP/1.1 200 OK
14+
Content-Type: application/xml; charset=utf-8
15+
Location: https://api.recurly.com/v2/external_products/ru1u1gms4msk
16+
17+
<?xml version="1.0" encoding="UTF-8"?>
18+
<external_product href="https://api.recurly.com/v2/external_products/ru1u1gms4msk">
19+
<id>sol7gvrm8vkh</id>
20+
<plan href="https://api.recurly.com/v2/plans/5_abril">
21+
<plan_code>5_abril</plan_code>
22+
<name>5 de abril</name>
23+
</plan>
24+
<name>product_name_teste</name>
25+
<created_at type="datetime">2022-11-03T21:12:35Z</created_at>
26+
<updated_at type="datetime">2022-11-03T21:12:35Z</updated_at>
27+
<external_product_references type="array">
28+
<external_product_reference href="https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/ru1u1gn5otsv">
29+
<id>ru1u1gn5otsv</id>
30+
<reference_code>code_teste_google</reference_code>
31+
<external_connection_type>google_play_store</external_connection_type>
32+
<created_at type="datetime">2022-11-03T21:12:35Z</created_at>
33+
<updated_at type="datetime">2022-11-03T21:12:35Z</updated_at>
34+
</external_product_reference>
35+
<external_product_reference href="https://api.recurly.com/v2/external_products/ru1u1gms4msk/external_product_references/ru1u1gn7ebod">
36+
<id>ru1u1gn7ebod</id>
37+
<reference_code>code_teste_apple</reference_code>
38+
<external_connection_type>apple_app_store</external_connection_type>
39+
<created_at type="datetime">2022-11-03T21:12:35Z</created_at>
40+
<updated_at type="datetime">2022-11-03T21:12:35Z</updated_at>
41+
</external_product_reference>
42+
</external_product_references>
43+
</external_product>

tests/test_resources.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3165,6 +3165,51 @@ def test_get_external_product(self):
31653165
self.assertEqual(second_external_product_reference.created_at, datetime(2022, 11, 3, 21, 12, 35, tzinfo=second_external_product_reference.created_at.tzinfo))
31663166
self.assertEqual(second_external_product_reference.updated_at, datetime(2022, 11, 3, 21, 12, 35, tzinfo=second_external_product_reference.updated_at.tzinfo))
31673167

3168+
def test_update_external_product(self):
3169+
with self.mock_request('external-product/get.xml'):
3170+
external_product = ExternalProduct.get('ru1u1gms4msk')
3171+
3172+
external_product.plan_code = "test-plan"
3173+
with self.mock_request('external-product/updated.xml'):
3174+
external_product.save()
3175+
3176+
def test_delete_external_product(self):
3177+
with self.mock_request('external-product/get.xml'):
3178+
external_product = ExternalProduct.get('ru1u1gms4msk')
3179+
3180+
with self.mock_request('external-product/deleted.xml'):
3181+
external_product.delete()
3182+
3183+
def test_create_external_product_reference(self):
3184+
with self.mock_request('external-product/get.xml'):
3185+
external_product = ExternalProduct.get('ru1u1gms4msk')
3186+
3187+
external_product_reference = recurly.ExternalProductReference(
3188+
reference_code = '948eb638-bef5-4e48-a955-2646d7e353e5',
3189+
external_connection_type = 'google_play_store'
3190+
)
3191+
with self.mock_request('external-product-references/create.xml'):
3192+
external_product.create_external_product_reference(external_product_reference)
3193+
3194+
def test_get_external_product_reference(self):
3195+
with self.mock_request('external-product/get.xml'):
3196+
external_product = ExternalProduct.get('ru1u1gms4msk')
3197+
with self.mock_request('external-product-references/get.xml'):
3198+
external_product_reference = external_product.get_external_product_reference('ru1u1gn5otsv')
3199+
3200+
self.assertEqual(external_product_reference.reference_code, "code_test_google")
3201+
self.assertEqual(external_product_reference.external_connection_type, "google_play_store")
3202+
3203+
def test_delete_external_product_reference(self):
3204+
with self.mock_request('external-product/get.xml'):
3205+
external_product = ExternalProduct.get('ru1u1gms4msk')
3206+
3207+
with self.mock_request('external-product-references/get.xml'):
3208+
external_product_reference = external_product.get_external_product_reference('ru1u1gn5otsv')
3209+
3210+
with self.mock_request('external-product-references/deleted.xml'):
3211+
external_product_reference.delete()
3212+
31683213
def test_list_external_accounts(self):
31693214
account_code = 'testmock'
31703215
with self.mock_request('account/exists.xml'):

0 commit comments

Comments
 (0)