Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Python
__pycache__/
*.py[cod]
*.pyo
.pytest_cache/
*.egg-info/
dist/
build/
.eggs/

# Virtual environment
venv/
.venv/
env/

# IDE
.idea/
.vscode/
*.iml

# OS
.DS_Store
Thumbs.db

# Logs and reports
*.log
reports/
allure-results/

# Selenium / browser
chromedriver
geckodriver
54 changes: 54 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import pytest
from selenium import webdriver
from unittest.mock import MagicMock

from praktikum.burger import Burger
from praktikum.bun import Bun
from praktikum.ingredient import Ingredient
from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING

from test_data import (
BUN_PRICE, BUN_NAME,
SAUCE_PRICE, SAUCE_NAME,
FILLING_PRICE, FILLING_NAME
)


@pytest.fixture
def driver():
driver = webdriver.Chrome()
yield driver
driver.quit()


@pytest.fixture
def mock_bun():
bun = MagicMock(spec=Bun)
bun.get_name.return_value = BUN_NAME
bun.get_price.return_value = BUN_PRICE
return bun


@pytest.fixture
def mock_sauce():
ingredient = MagicMock(spec=Ingredient)
ingredient.get_name.return_value = SAUCE_NAME
ingredient.get_price.return_value = SAUCE_PRICE
ingredient.get_type.return_value = INGREDIENT_TYPE_SAUCE
return ingredient


@pytest.fixture
def mock_filling():
ingredient = MagicMock(spec=Ingredient)
ingredient.get_name.return_value = FILLING_NAME
ingredient.get_price.return_value = FILLING_PRICE
ingredient.get_type.return_value = INGREDIENT_TYPE_FILLING
return ingredient


@pytest.fixture
def burger_with_bun(mock_bun):
burger = Burger()
burger.set_buns(mock_bun)
return burger
7 changes: 0 additions & 7 deletions ingredient_types.py

This file was deleted.

Empty file added praktikum/__init__.py
Empty file.
5 changes: 0 additions & 5 deletions bun.py → praktikum/bun.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
class Bun:
"""
Модель булочки для бургера.
Булочке можно дать название и назначить цену.
"""

def __init__(self, name: str, price: float):
self.name = name
self.price = price
Expand Down
14 changes: 0 additions & 14 deletions burger.py → praktikum/burger.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
from typing import List

from praktikum.bun import Bun
from praktikum.ingredient import Ingredient


class Burger:
"""
Модель бургера.
Бургер состоит из булочек и ингредиентов (начинка или соус).
Ингредиенты можно перемещать и удалять.
Можно распечать чек с информацией о бургере.
"""

def __init__(self):
self.bun = None
self.ingredients: List[Ingredient] = []
Expand All @@ -30,19 +21,14 @@ def move_ingredient(self, index: int, new_index: int):

def get_price(self) -> float:
price = self.bun.get_price() * 2

for ingredient in self.ingredients:
price += ingredient.get_price()

return price

def get_receipt(self) -> str:
receipt: List[str] = [f'(==== {self.bun.get_name()} ====)']

for ingredient in self.ingredients:
receipt.append(f'= {str(ingredient.get_type()).lower()} {ingredient.get_name()} =')

receipt.append(f'(==== {self.bun.get_name()} ====)\n')
receipt.append(f'Price: {self.get_price()}')

return '\n'.join(receipt)
6 changes: 0 additions & 6 deletions database.py → praktikum/database.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
from typing import List

from praktikum.bun import Bun
from praktikum.ingredient import Ingredient
from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE, INGREDIENT_TYPE_FILLING


class Database:
"""
Класс с методами по работе с базой данных.
"""

def __init__(self):
self.buns: List[Bun] = []
self.ingredients: List[Ingredient] = []
Expand Down
6 changes: 0 additions & 6 deletions ingredient.py → praktikum/ingredient.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
class Ingredient:
"""
Модель ингредиента.
Ингредиент: начинка или соус.
У ингредиента есть тип (начинка или соус), название и цена.
"""

def __init__(self, ingredient_type: str, name: str, price: float):
self.type = ingredient_type
self.name = name
Expand Down
2 changes: 2 additions & 0 deletions praktikum/ingredient_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
INGREDIENT_TYPE_SAUCE = 'SAUCE'
INGREDIENT_TYPE_FILLING = 'FILLING'
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
pythonpath = .
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytest==8.2.0
pytest-cov==5.0.0
7 changes: 7 additions & 0 deletions test_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
BUN_PRICE = 100
SAUCE_PRICE = 50
FILLING_PRICE = 100

BUN_NAME = 'black bun'
SAUCE_NAME = 'hot sauce'
FILLING_NAME = 'cutlet'
Empty file added tests/__init__.py
Empty file.
23 changes: 23 additions & 0 deletions tests/test_bun.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pytest
from praktikum.bun import Bun


class TestBun:

@pytest.mark.parametrize('name', [
'black bun',
'white bun',
'red bun',
])
def test_get_name(self, name):
bun = Bun(name, 100)
assert bun.get_name() == name

@pytest.mark.parametrize('price', [
100,
200.5,
0,
])
def test_get_price(self, price):
bun = Bun('test bun', price)
assert bun.get_price() == price
118 changes: 118 additions & 0 deletions tests/test_burger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import pytest
from unittest.mock import MagicMock

from praktikum.burger import Burger
from praktikum.bun import Bun
from praktikum.ingredient import Ingredient
from praktikum.ingredient_types import INGREDIENT_TYPE_SAUCE

from test_data import (
BUN_PRICE, BUN_NAME,
SAUCE_NAME
)


class TestBurgerSetBuns:

def test_set_buns(self, mock_bun):
burger = Burger()
burger.set_buns(mock_bun)
assert burger.bun == mock_bun


class TestBurgerAddIngredient:

def test_add_ingredient(self, burger_with_bun, mock_sauce):
burger_with_bun.add_ingredient(mock_sauce)
assert mock_sauce in burger_with_bun.ingredients

def test_add_multiple_ingredients(self, burger_with_bun, mock_sauce, mock_filling):
burger_with_bun.add_ingredient(mock_sauce)
burger_with_bun.add_ingredient(mock_filling)
assert len(burger_with_bun.ingredients) == 2


class TestBurgerRemoveIngredient:

def test_remove_ingredient(self, burger_with_bun, mock_sauce, mock_filling):
burger_with_bun.add_ingredient(mock_sauce)
burger_with_bun.add_ingredient(mock_filling)
burger_with_bun.remove_ingredient(0)
assert mock_sauce not in burger_with_bun.ingredients

def test_remove_ingredient_reduces_count(self, burger_with_bun, mock_sauce):
burger_with_bun.add_ingredient(mock_sauce)
burger_with_bun.remove_ingredient(0)
assert len(burger_with_bun.ingredients) == 0


class TestBurgerMoveIngredient:

def test_move_ingredient(self, burger_with_bun, mock_sauce, mock_filling):
burger_with_bun.add_ingredient(mock_sauce)
burger_with_bun.add_ingredient(mock_filling)
burger_with_bun.move_ingredient(1, 0)
assert burger_with_bun.ingredients[0] == mock_filling
assert burger_with_bun.ingredients[1] == mock_sauce


class TestBurgerGetPrice:

def test_get_price_bun_only(self, burger_with_bun):
expected = BUN_PRICE * 2
assert burger_with_bun.get_price() == expected

def test_get_price_with_ingredients(self, burger_with_bun, mock_sauce, mock_filling):
burger_with_bun.add_ingredient(mock_sauce)
burger_with_bun.add_ingredient(mock_filling)
expected = BUN_PRICE * 2 + mock_sauce.get_price() + mock_filling.get_price()
assert burger_with_bun.get_price() == expected

@pytest.mark.parametrize('bun_price, ingredient_prices, expected', [
(100, [], 200),
(100, [50], 250),
(200, [100, 150], 650),
])
def test_get_price_parametrized(self, bun_price, ingredient_prices, expected):
bun = MagicMock(spec=Bun)
bun.get_price.return_value = bun_price
bun.get_name.return_value = 'bun'

burger = Burger()
burger.set_buns(bun)

for price in ingredient_prices:
ingredient = MagicMock(spec=Ingredient)
ingredient.get_price.return_value = price
ingredient.get_name.return_value = 'ing'
ingredient.get_type.return_value = INGREDIENT_TYPE_SAUCE
burger.add_ingredient(ingredient)

assert burger.get_price() == expected


class TestBurgerGetReceipt:

def test_get_receipt_contains_bun_name(self, burger_with_bun):
assert BUN_NAME in burger_with_bun.get_receipt()

def test_get_receipt_contains_price(self, burger_with_bun):
expected_price = BUN_PRICE * 2
assert f'Price: {expected_price}' in burger_with_bun.get_receipt()

def test_get_receipt_contains_ingredient_name(self, burger_with_bun, mock_sauce):
burger_with_bun.add_ingredient(mock_sauce)
assert SAUCE_NAME in burger_with_bun.get_receipt()

def test_get_receipt_contains_ingredient_type(self, burger_with_bun, mock_sauce):
burger_with_bun.add_ingredient(mock_sauce)
assert mock_sauce.get_type().lower() in burger_with_bun.get_receipt()

def test_get_receipt_format(self, burger_with_bun, mock_sauce):
burger_with_bun.add_ingredient(mock_sauce)
receipt = burger_with_bun.get_receipt()

lines = receipt.split('\n')

assert lines[0] == f'(==== {BUN_NAME} ====)'
assert f'(==== {BUN_NAME} ====)' in lines
32 changes: 32 additions & 0 deletions tests/test_database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from praktikum.database import Database
from praktikum.bun import Bun
from praktikum.ingredient import Ingredient


class TestDatabase:

def test_available_buns_returns_list(self):
db = Database()
assert isinstance(db.available_buns(), list)

def test_available_buns_not_empty(self):
db = Database()
assert len(db.available_buns()) > 0

def test_available_buns_contains_bun_instances(self):
db = Database()
for bun in db.available_buns():
assert isinstance(bun, Bun)

def test_available_ingredients_returns_list(self):
db = Database()
assert isinstance(db.available_ingredients(), list)

def test_available_ingredients_not_empty(self):
db = Database()
assert len(db.available_ingredients()) > 0

def test_available_ingredients_contains_ingredient_instances(self):
db = Database()
for ingredient in db.available_ingredients():
assert isinstance(ingredient, Ingredient)
Loading