Skip to content

Commit d8748b4

Browse files
test: Add tests for /api/user/feed endpoint
1. Integration of comprehensive functional tests (`TestUserPromoFeed`) that verify core endpoint behaviors: - Accurate user-specific promo targeting based on age and country. - Correct dynamic calculation of promo 'active' status (considering dates, usage counts, and unique code availability). - Effective filtering via `active` (boolean) and `category` (case-insensitive) query parameters. - Proper pagination functionality using `limit` and `offset`, including `X-Total-Count` header validation. - Verification of response data structure, ensuring exclusion of sensitive promo code values. - Correct reflection of promo data updates (e.g., a promo becoming inactive after an edit) in the feed. 2. Addition of new focused validation tests (`TestUserPromoFeed`) using parameterized inputs to cover edge cases and invalid requests: - Authentication checks, specifically ensuring `401 Unauthorized` for requests lacking a token. - Rigorous validation of query parameters (`limit`, `offset`, `category`, `active`): - Invalid data types and formats (e.g., non-numeric for `limit`/`offset`, non-boolean for `active`). - Values outside defined constraints (e.g., negative `limit`/`offset`, category string length violations). - Empty string inputs for parameters that require specific formats. - Rejection of requests containing unexpected or unsupported query parameters, returning a `400 Bad Request`.
1 parent bacab51 commit d8748b4

File tree

5 files changed

+848
-4
lines changed

5 files changed

+848
-4
lines changed

promo_code/user/serializers.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,19 @@ def validate(self, attrs):
297297

298298
return attrs
299299

300+
def validate_category(self, value):
301+
cotegory = self.initial_data.get('category')
302+
303+
if cotegory is None:
304+
return value
305+
306+
if value == '':
307+
raise rest_framework.exceptions.ValidationError(
308+
'Invalid category format.',
309+
)
310+
311+
return value
312+
300313
def _validate_int_field(self, field_name, attrs, field_errors):
301314
value_str = self.initial_data.get(field_name)
302315
if value_str is None:

promo_code/user/tests/user/base.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ def setUpTestData(cls):
1414
cls.user_signup_url = django.urls.reverse('api-user:user-sign-up')
1515
cls.user_signin_url = django.urls.reverse('api-user:user-sign-in')
1616
cls.user_profile_url = django.urls.reverse('api-user:user-profile')
17+
cls.user_feed_url = django.urls.reverse('api-user:user-feed')
18+
19+
cls.company_signin_url = django.urls.reverse(
20+
'api-business:company-sign-in',
21+
)
1722
cls.promo_list_create_url = django.urls.reverse(
1823
'api-business:promo-list-create',
1924
)
@@ -28,16 +33,36 @@ def setUpTestData(cls):
2833
email=company1_data['email'],
2934
)
3035
response1 = cls.client.post(
31-
django.urls.reverse(
32-
'api-business:company-sign-in',
33-
),
36+
cls.company_signin_url,
3437
{
3538
'email': company1_data['email'],
3639
'password': company1_data['password'],
3740
},
3841
format='json',
3942
)
4043
cls.company1_token = response1.data['access']
44+
cls.company1_name = cls.company1.name
45+
46+
company2_data = {
47+
'name': 'Synergy Solutions Co.',
48+
'email': '[email protected]',
49+
'password': 'AnotherSecurePass456!',
50+
}
51+
business.models.Company.objects.create_company(**company2_data)
52+
53+
cls.company2 = business.models.Company.objects.get(
54+
email=company2_data['email'],
55+
)
56+
response2 = cls.client.post(
57+
cls.company_signin_url,
58+
{
59+
'email': company2_data['email'],
60+
'password': company2_data['password'],
61+
},
62+
format='json',
63+
)
64+
cls.company2_token = response2.data['access']
65+
cls.company2_name = cls.company2.name
4166

4267
def tearDown(self):
4368
business.models.Company.objects.all().delete()
@@ -54,3 +79,10 @@ def promo_detail_url(cls, promo_id):
5479
'api-user:user-promo-detail',
5580
kwargs={'id': promo_id},
5681
)
82+
83+
@classmethod
84+
def get_promo_business_detail_url(cls, promo_id):
85+
return django.urls.reverse(
86+
'api-business:promo-detail',
87+
kwargs={'id': promo_id},
88+
)

promo_code/user/tests/user/operations/test_detail.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ def setUp(self):
5959

6060
promo_us = {
6161
'description': 'Gift sleeping mask with car loan application',
62-
'target': {'age_from': 28, 'age_until': 50, 'country': 'us'},
62+
'target': {
63+
'age_from': 28,
64+
'age_until': 50,
65+
'country': 'us',
66+
'categories': ['cars'],
67+
},
6368
'max_count': 1,
6469
'active_from': '2025-01-01',
6570
'active_until': '2028-12-30',

0 commit comments

Comments
 (0)