Skip to content

Commit

Permalink
feat(Prices): API: allow editing category-related fields (#677)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphodn authored Jan 12, 2025
1 parent 8985244 commit fc157a6
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 19 deletions.
53 changes: 41 additions & 12 deletions open_prices/api/prices/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
}

PRICE_APPLES = {
"type": price_constants.TYPE_CATEGORY,
"category_tag": "en:apples",
"price_per": price_constants.PRICE_PER_UNIT,
"price": 1,
Expand Down Expand Up @@ -120,21 +121,18 @@ def setUpTestData(cls):
owner=cls.user_session.user.user_id,
)
PriceFactory(
type=price_constants.TYPE_CATEGORY,
**PRICE_APPLES,
labels_tags=[],
origins_tags=["en:spain"],
owner=cls.user_session.user.user_id,
)
PriceFactory(
type=price_constants.TYPE_CATEGORY,
**PRICE_APPLES,
labels_tags=["en:organic"],
origins_tags=["en:unknown"],
owner=cls.user_session.user.user_id,
)
PriceFactory(
type=price_constants.TYPE_CATEGORY,
**PRICE_APPLES,
labels_tags=["en:organic"],
origins_tags=["en:france"],
Expand Down Expand Up @@ -527,46 +525,75 @@ class PriceUpdateApiTest(TestCase):
def setUpTestData(cls):
cls.user_session_1 = SessionFactory()
cls.user_session_2 = SessionFactory()
cls.price = PriceFactory(
cls.price_product = PriceFactory(
**PRICE_8001505005707, owner=cls.user_session_1.user.user_id
)
cls.url = reverse("api:prices-detail", args=[cls.price.id])
cls.price_category = PriceFactory(
**PRICE_APPLES, owner=cls.user_session_1.user.user_id
)
cls.url_price_product = reverse(
"api:prices-detail", args=[cls.price_product.id]
)
cls.url_price_category = reverse(
"api:prices-detail", args=[cls.price_category.id]
)
cls.data = {"currency": "USD", "product_code": "123"}

def test_price_update(self):
def test_price_update_authentication_errors(self):
# anonymous
response = self.client.patch(
self.url, self.data, content_type="application/json"
self.url_price_product, self.data, content_type="application/json"
)
self.assertEqual(response.status_code, 403)
# wrong token
response = self.client.patch(
self.url,
self.url_price_product,
self.data,
headers={"Authorization": f"Bearer {self.user_session_1.token}X"},
content_type="application/json",
)
self.assertEqual(response.status_code, 403)
# not price owner
response = self.client.patch(
self.url,
self.url_price_product,
self.data,
headers={"Authorization": f"Bearer {self.user_session_2.token}"},
content_type="application/json",
)
self.assertEqual(response.status_code, 404) # 403 ?

def test_price_update_ok(self):
# authenticated
response = self.client.patch(
self.url,
self.url_price_product,
self.data,
headers={"Authorization": f"Bearer {self.user_session_1.token}"},
content_type="application/json",
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["currency"], "USD")
self.assertEqual(
Price.objects.get(id=self.price.id).product_code, "8001505005707"
Price.objects.get(id=self.price_product.id).product_code, "8001505005707"
) # ignored
# update price category
response = self.client.patch(
self.url_price_category,
{"category_tag": "en:tomatoes"},
headers={"Authorization": f"Bearer {self.user_session_1.token}"},
content_type="application/json",
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["category_tag"], "en:tomatoes")

def test_price_update_type_mismatch(self):
# cannot add 'category' fields to a 'product' price
response = self.client.patch(
self.url_price_product,
{"category_tag": "en:tomatoes"},
headers={"Authorization": f"Bearer {self.user_session_1.token}"},
content_type="application/json",
)
self.assertEqual(response.status_code, 400)


class PriceDeleteApiTest(TestCase):
Expand All @@ -579,7 +606,7 @@ def setUpTestData(cls):
)
cls.url = reverse("api:prices-detail", args=[cls.price.id])

def test_price_delete(self):
def test_price_delete_authentication_errors(self):
# anonymous
response = self.client.delete(self.url)
self.assertEqual(response.status_code, 403)
Expand All @@ -593,6 +620,8 @@ def test_price_delete(self):
self.url, headers={"Authorization": f"Bearer {self.user_session_2.token}"}
)
self.assertEqual(response.status_code, 404) # 403 ?

def test_price_delete_ok(self):
# authenticated
response = self.client.delete(
self.url, headers={"Authorization": f"Bearer {self.user_session_1.token}"}
Expand Down
10 changes: 3 additions & 7 deletions open_prices/prices/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def calculate_stats(self):

class Price(models.Model):
UPDATE_FIELDS = [
"category_tag",
"labels_tags",
"origins_tags",
"price",
"price_is_discounted",
"price_without_discount",
Expand Down Expand Up @@ -187,7 +190,6 @@ def clean(self, *args, **kwargs):
# product rules
# - if product_code is set, then should be a valid string
# - if product_code is set, then category_tag/labels_tags/origins_tags should not be set # noqa
# - if product_code is set, then price_per should not be set
if self.product_code:
if self.type != price_constants.TYPE_PRODUCT:
validation_errors = utils.add_validation_error(
Expand Down Expand Up @@ -229,12 +231,6 @@ def clean(self, *args, **kwargs):
"origins_tags",
"Should not be set if `product_code` is filled",
)
if self.price_per:
validation_errors = utils.add_validation_error(
validation_errors,
"price_per",
"Should not be set if `product_code` is filled",
)
# Tag rules:
# - if category_tag is set, it should be language-prefixed
# - if labels_tags is set, then all labels_tags should be valid taxonomy strings # noqa
Expand Down

0 comments on commit fc157a6

Please sign in to comment.