Skip to content

Commit ae1a4b0

Browse files
committed
add pytest. pruebas de roles de usuario y permisos de acceso a los productos
1 parent 194676a commit ae1a4b0

File tree

7 files changed

+173
-1
lines changed

7 files changed

+173
-1
lines changed

pytest.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[pytest]
2+
DJANGO_SETTINGS_MODULE = myproject.settings
3+
python_files = tests.py test_*.py *_tests.py
4+
addopts = -v -s

requirements.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,18 @@ asgiref==3.11.0
22
Django==4.2.7
33
djangorestframework==3.14.0
44
djangorestframework_simplejwt==5.5.1
5+
factory_boy==3.3.3
56
Faker==38.2.0
67
gunicorn==21.2.0
8+
iniconfig==2.3.0
79
packaging==25.0
10+
pluggy==1.6.0
811
psycopg2-binary==2.9.9
12+
Pygments==2.19.2
913
PyJWT==2.10.1
14+
pytest==9.0.2
15+
pytest-django==4.11.1
16+
pytest-mock==3.15.1
1017
pytz==2025.2
1118
sqlparse==0.5.4
1219
tzdata==2025.2

tests/conftest.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import pytest
2+
from rest_framework.test import APIClient
3+
from django.contrib.auth import get_user_model
4+
from factories import AdminFactory, StaffFactory, UserFactory
5+
6+
User = get_user_model()
7+
8+
9+
@pytest.fixture
10+
def api_client():
11+
return APIClient()
12+
13+
14+
@pytest.fixture
15+
def admin_user():
16+
return AdminFactory()
17+
18+
19+
@pytest.fixture
20+
def staff_user():
21+
return StaffFactory()
22+
23+
24+
@pytest.fixture
25+
def client_user():
26+
return UserFactory()
27+
28+
29+
@pytest.fixture
30+
def get_token(api_client):
31+
def _get_token(user):
32+
response = api_client.post(
33+
"/api/login/",
34+
{
35+
"username": user.username,
36+
"password": "123456"
37+
},
38+
format="json"
39+
)
40+
return response.data["access"]
41+
42+
return _get_token

tests/factories.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import factory
2+
from django.contrib.auth import get_user_model
3+
from products.models import Product
4+
import random
5+
6+
User = get_user_model()
7+
8+
class UserFactory(factory.django.DjangoModelFactory):
9+
class Meta:
10+
model = User
11+
12+
username = factory.Sequence(lambda n: f"user{n}")
13+
email = factory.LazyAttribute(lambda o: f"{o.username}@test.com")
14+
password = factory.PostGenerationMethodCall('set_password', '123456')
15+
role = 'CLIENTE'
16+
17+
18+
class AdminFactory(UserFactory):
19+
role = 'ADMIN'
20+
21+
22+
class StaffFactory(UserFactory):
23+
role = 'STAFF'
24+
25+
26+
class ProductFactory(factory.django.DjangoModelFactory):
27+
class Meta:
28+
model = Product
29+
30+
name = factory.Faker('word')
31+
price = factory.Faker('pydecimal', left_digits=3, right_digits=2, positive=True)
32+
stock = factory.Faker('random_int', min=1, max=100)
33+
is_public = True
34+
owner = factory.SubFactory(UserFactory)

tests/test_auth.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import pytest
2+
3+
@pytest.mark.django_db
4+
def test_jwt_login_success(api_client, client_user):
5+
response = api_client.post(
6+
"/api/login/",
7+
{
8+
"username": client_user.username,
9+
"password": "123456"
10+
},
11+
format="json"
12+
)
13+
14+
assert response.status_code == 200
15+
assert "access" in response.data
16+
assert "refresh" in response.data
17+
18+
@pytest.mark.django_db
19+
def test_protected_without_token(api_client):
20+
response = api_client.get("/api/protected/")
21+
assert response.status_code == 401

tests/test_products.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import pytest
2+
from factories import ProductFactory
3+
4+
5+
@pytest.mark.django_db
6+
def test_client_cannot_create_product(api_client, client_user, get_token):
7+
token = get_token(client_user)
8+
9+
api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}")
10+
11+
response = api_client.post(
12+
"/api/products/",
13+
{
14+
"name": "Producto Prohibido",
15+
"price": "100.00",
16+
"stock": 10,
17+
"is_public": True,
18+
},
19+
format="json"
20+
)
21+
22+
assert response.status_code == 403
23+
24+
25+
@pytest.mark.django_db
26+
def test_staff_can_create_product(api_client, staff_user, get_token):
27+
token = get_token(staff_user)
28+
api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}")
29+
30+
response = api_client.post(
31+
"/api/products/",
32+
{
33+
"name": "Producto Staff",
34+
"price": "50.00",
35+
"stock": 5,
36+
"is_public": True,
37+
},
38+
format="json"
39+
)
40+
41+
assert response.status_code == 201
42+
43+
44+
@pytest.mark.django_db
45+
def test_staff_cannot_delete_product(api_client, staff_user, get_token):
46+
product = ProductFactory()
47+
48+
token = get_token(staff_user)
49+
api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}")
50+
51+
response = api_client.delete(f"/api/products/{product.id}/")
52+
53+
assert response.status_code == 403
54+
55+
@pytest.mark.django_db
56+
def test_admin_can_delete_product(api_client, admin_user, get_token):
57+
product = ProductFactory()
58+
59+
token = get_token(admin_user)
60+
api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}")
61+
62+
response = api_client.delete(f"/api/products/{product.id}/")
63+
64+
assert response.status_code == 204

users/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ class Meta:
2828
ordering = ['-created_at']
2929

3030
def __str__(self):
31-
return self.username
31+
return f"{self.username} - {self.password}"

0 commit comments

Comments
 (0)