diff --git a/.gitignore b/.gitignore index e69de29..1a9aabe 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,2 @@ +.venv +.idea \ No newline at end of file diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..2bc05ab --- /dev/null +++ b/conftest.py @@ -0,0 +1,32 @@ +import requests +import pytest +from faker import Faker +from urls.urls import CREATE_USER_URL, INGREDIENTS_URL +from random import randrange + + +@pytest.fixture() +def user(): + fake = Faker("ru_RU") + payload = { + "email": fake.email(), + "password": fake.password(), + "name": fake.name() + } + response = requests.post(CREATE_USER_URL, data=payload) + body = response.json() + return { + **payload, + "accessToken": body["accessToken"], + "refreshToken": body["refreshToken"], + } + + +@pytest.fixture() +def random_ingredients(): + response = requests.get(INGREDIENTS_URL) + ingredients = response.json()["data"] + buns = list(filter(lambda ing: ing["type"] == "bun", ingredients)) + mains = list(filter(lambda ing: ing["type"] == "main", ingredients)) + sauces = list(filter(lambda ing: ing["type"] == "sauce", ingredients)) + return [buns[randrange(len(buns))]["_id"], mains[randrange(len(mains))]["_id"], sauces[randrange(len(sauces))]["_id"]] diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..03f586d --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +pythonpath = . \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5627444 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,18 @@ +allure-pytest==2.13.5 +allure-python-commons==2.13.5 +attrs==24.2.0 +certifi==2024.8.30 +charset-normalizer==3.4.0 +exceptiongroup==1.2.2 +Faker==33.0.0 +idna==3.10 +iniconfig==2.0.0 +packaging==24.2 +pluggy==1.5.0 +pytest==8.3.3 +python-dateutil==2.9.0.post0 +requests==2.32.3 +six==1.16.0 +tomli==2.1.0 +typing_extensions==4.12.2 +urllib3==2.2.3 diff --git a/tests/test_create_order.py b/tests/test_create_order.py new file mode 100644 index 0000000..57ec18f --- /dev/null +++ b/tests/test_create_order.py @@ -0,0 +1,48 @@ +import requests +import allure +from urls.urls import CREATE_ORDER_URL +import pytest + + +MESSAGE_NO_INGREDIENTS = "Ingredient ids must be provided" + + +class TestCreateOrder: + + @allure.title('Проверка создания заказа с авторизацией и без') + @pytest.mark.parametrize('need_auth', [True, False]) + def test_can_create_order(self, user, random_ingredients, need_auth): + payload = { + "ingredients": random_ingredients + } + headers = {"Authorization": user['accessToken']} if need_auth else {} + response = requests.post(CREATE_ORDER_URL, data=payload, headers=headers) + body = response.json() + + assert response.status_code == 200 + assert body["success"] is True + assert len(body["name"]) > 0 + assert body["order"]["number"] > 0 + + @allure.title('Проверка создания заказа с авторизацией, но без ингредиентов') + def test_cant_create_order_without_ingredients(self, user): + payload = { + "ingredients": [] + } + response = requests.post(CREATE_ORDER_URL, data=payload, headers={"Authorization": user['accessToken']}) + body = response.json() + + assert response.status_code == 400 + assert body["success"] is False + assert body["message"] == MESSAGE_NO_INGREDIENTS + + @allure.title('Проверка создания заказа с неверными ингредиентами') + def test_cant_create_order_without_ingredients(self, user): + payload = { + "ingredients": ["wrong", "ingredient"] + } + response = requests.post(CREATE_ORDER_URL, data=payload, headers={"Authorization": user['accessToken']}) + + assert response.status_code == 500 + + diff --git a/tests/test_create_user.py b/tests/test_create_user.py new file mode 100644 index 0000000..16007d8 --- /dev/null +++ b/tests/test_create_user.py @@ -0,0 +1,69 @@ +import requests +import allure +from faker import Faker +from urls.urls import CREATE_USER_URL +import pytest + + +MESSAGE_USER_ALREADY_EXISTS = "User already exists" +MESSAGE_REQUIRED_FIELDS = "Email, password and name are required fields" + + +class TestCreateUser: + + payload = [ + { + "email": "test@email.com", + "password": "password" + }, + { + "email": "test@email.com", + "name": "John Doe" + }, + { + "password": "password", + "name": "John Doe" + } + ] + + @allure.title('Проверка создания уникального пользователя') + def test_can_create_new_user(self): + fake = Faker("ru_RU") + payload = { + "email": fake.email(), + "password": fake.password(), + "name": fake.name() + } + + response = requests.post(CREATE_USER_URL, data=payload) + body = response.json() + + assert response.status_code == 200 + assert body["success"] is True + assert body["user"]["email"] == payload["email"] + assert body["user"]["name"] == payload["name"] + + @allure.title('Проверка наличия ошибки создания пользователя, который уже зарегистрирован') + def test_cant_create_same_user(self, user): + payload = { + "email": user["email"], + "password": user["password"], + "name": user["name"] + } + + response = requests.post(CREATE_USER_URL, data=payload) + body = response.json() + + assert response.status_code == 403 + assert body["success"] is False + assert body["message"] == MESSAGE_USER_ALREADY_EXISTS + + @allure.title('Проверка наличия ошибки создания пользователя, у которого не указаны все обязательные поля') + @pytest.mark.parametrize('payload', payload) + def test_cant_create_user_without_any_field(self, payload): + response = requests.post(CREATE_USER_URL, data=payload) + body = response.json() + + assert response.status_code == 403 + assert body["success"] is False + assert body["message"] == MESSAGE_REQUIRED_FIELDS diff --git a/tests/test_get_user_orders.py b/tests/test_get_user_orders.py new file mode 100644 index 0000000..9433d81 --- /dev/null +++ b/tests/test_get_user_orders.py @@ -0,0 +1,37 @@ +import requests +import allure +from urls.urls import USER_ORDER_URL, CREATE_ORDER_URL + + +MESSAGE_USER_UNAUTHORIZED = "You should be authorised" + + +class TestGetUserOrders: + + @allure.title('Проверка получения заказов пользователя с авторизацией') + def test_can_update_user_data(self, user, random_ingredients): + payload = { + "ingredients": random_ingredients + } + requests.post(CREATE_ORDER_URL, data=payload, headers={"Authorization": user['accessToken']}) + response = requests.get(USER_ORDER_URL, headers={"Authorization": user['accessToken']}) + body = response.json() + + assert response.status_code == 200 + assert body["success"] is True + assert body["total"] == 1 + assert body["totalToday"] == 1 + assert len(body["orders"]) == 1 + + @allure.title('Проверка получения заказов пользователя без авторизации') + def test_can_update_user_data(self, user, random_ingredients): + payload = { + "ingredients": random_ingredients + } + requests.post(CREATE_ORDER_URL, data=payload, headers={"Authorization": user['accessToken']}) + response = requests.get(USER_ORDER_URL) + body = response.json() + + assert response.status_code == 401 + assert body["success"] is False + assert body["message"] == MESSAGE_USER_UNAUTHORIZED diff --git a/tests/test_update_user_data.py b/tests/test_update_user_data.py new file mode 100644 index 0000000..82d1f44 --- /dev/null +++ b/tests/test_update_user_data.py @@ -0,0 +1,46 @@ +import requests +import allure +from faker import Faker +from urls.urls import USER_INFO_URL +import pytest + + +MESSAGE_USER_UNAUTHORIZED = "You should be authorised" + + +class TestUpdateUserData: + + fake = Faker("ru_RU") + + update_data = [ + ("email", fake.email()), + ("name", fake.name()), + ("password", fake.password()) + ] + + @allure.title('Проверка изменения данных пользователя с авторизацией') + @pytest.mark.parametrize('update_data', update_data) + def test_can_update_user_data(self, user, update_data): + payload = { + f"{update_data[0]}": update_data[1] + } + response = requests.patch(USER_INFO_URL, data=payload, headers={"Authorization": user['accessToken']}) + body = response.json() + + assert response.status_code == 200 + assert body["success"] is True + if update_data[0] != "password": + assert body["user"][update_data[0]] == update_data[1] + + @allure.title('Проверка изменения данных пользователя без авторизации') + @pytest.mark.parametrize('update_data', update_data) + def test_cant_update_user_data(self, user, update_data): + payload = { + f"{update_data[0]}": update_data[1] + } + response = requests.patch(USER_INFO_URL, data=payload) + body = response.json() + + assert response.status_code == 401 + assert body["success"] is False + assert body["message"] == MESSAGE_USER_UNAUTHORIZED diff --git a/tests/test_user_login.py b/tests/test_user_login.py new file mode 100644 index 0000000..23ee621 --- /dev/null +++ b/tests/test_user_login.py @@ -0,0 +1,41 @@ +import requests +import allure +from urls.urls import LOGIN_URL + + +MESSAGE_INCORRECT_CREDENTIALS = "email or password are incorrect" + + +class TestUserLogin: + + @allure.title('Проверка логина существующего пользователя') + def test_can_login_as_existing_user(self, user): + payload = { + "email": user["email"], + "password": user["password"] + } + + response = requests.post(LOGIN_URL, data=payload) + body = response.json() + + assert response.status_code == 200 + assert body["success"] is True + assert body["user"]["email"] == user["email"] + assert body["user"]["name"] == user["name"] + assert len(body["accessToken"]) > 0 + assert len(body["refreshToken"]) > 0 + + @allure.title('Проверка ошибки логина несуществующего пользователя') + def test_cant_login_as_wrong_user(self, user): + payload = { + "email": user["email"] + "123", + "password": user["password"] + "123" + } + + response = requests.post(LOGIN_URL, data=payload) + body = response.json() + + assert response.status_code == 401 + assert body["success"] is False + assert body["message"] == MESSAGE_INCORRECT_CREDENTIALS + diff --git a/urls/urls.py b/urls/urls.py new file mode 100644 index 0000000..7a79330 --- /dev/null +++ b/urls/urls.py @@ -0,0 +1,7 @@ +BASE_URL = "https://stellarburgers.nomoreparties.site" +CREATE_USER_URL = f"{BASE_URL}/api/auth/register" +LOGIN_URL = f"{BASE_URL}/api/auth/login" +USER_INFO_URL = f"{BASE_URL}/api/auth/user" +INGREDIENTS_URL = f"{BASE_URL}/api/ingredients" +CREATE_ORDER_URL = f"{BASE_URL}/api/orders" +USER_ORDER_URL = f"{BASE_URL}/api/orders"