import unittest import sqlite3 import os import sys import tempfile import time from datetime import datetime sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from database import get_db_connection, calculate_order_total from app import app class TestOrders(unittest.TestCase): """Тестирование функционала заказов""" @classmethod def setUpClass(cls): """Создаем тестовую базу данных""" cls.db_fd, cls.db_path = tempfile.mkstemp() import database database.DATABASE = cls.db_path from database import create_tables create_tables() cls.conn = sqlite3.connect(cls.db_path) cls.conn.row_factory = sqlite3.Row cursor = cls.conn.cursor() # Добавляем типы товаров cursor.execute("INSERT INTO product_types (type_name) VALUES ('Ручки')") cursor.execute("INSERT INTO product_types (type_name) VALUES ('Тетради')") # Добавляем партнеров (БЕЗ rating) cursor.execute(''' INSERT INTO partners (name, email, inn) VALUES ('ООО Тест', 'test@test.ru', '1234567890') ''') cursor.execute(''' INSERT INTO partners (name, email, inn) VALUES ('ИП Тест', 'test2@test.ru', '0987654321') ''') # Добавляем товары (БЕЗ quantity_in_stock) cursor.execute(''' INSERT INTO products (product_type_id, product_name, article, min_partner_price) VALUES (1, 'Ручка синяя', 'R001', 50.0) ''') cursor.execute(''' INSERT INTO products (product_type_id, product_name, article, min_partner_price) VALUES (1, 'Ручка красная', 'R002', 60.0) ''') cursor.execute(''' INSERT INTO products (product_type_id, product_name, article, min_partner_price) VALUES (2, 'Тетрадь 48л', 'T001', 100.0) ''') # Добавляем заказы (БЕЗ status) cursor.execute(''' INSERT INTO orders (partner_id, order_date, discount_percent) VALUES (1, '2026-01-01', 0) ''') cursor.execute(''' INSERT INTO orders (partner_id, order_date, discount_percent) VALUES (1, '2026-02-01', 15) ''') # Добавляем позиции заказов cursor.execute(''' INSERT INTO order_items (order_id, product_id, quantity, price_at_order) VALUES (1, 1, 10, 50.0) ''') cursor.execute(''' INSERT INTO order_items (order_id, product_id, quantity, price_at_order) VALUES (1, 3, 5, 100.0) ''') cursor.execute(''' INSERT INTO order_items (order_id, product_id, quantity, price_at_order) VALUES (2, 2, 20, 60.0) ''') cls.conn.commit() def test_db_connection(): conn = sqlite3.connect(cls.db_path) conn.row_factory = sqlite3.Row return conn app.config['DATABASE'] = cls.db_path database.get_db_connection = test_db_connection @classmethod def tearDownClass(cls): cls.conn.close() os.close(cls.db_fd) try: os.unlink(cls.db_path) except: pass def setUp(self): self.app = app.test_client() self.app.testing = True def test_1_calculate_order_total(self): """Тест расчета общей суммы заказа с наценкой 10%""" result = calculate_order_total(1) self.assertIsNotNone(result) # 10*50 + 5*100 = 1000 базовая сумма self.assertEqual(result['subtotal_without_markup'], 1000.0) # С наценкой 10%: 1000 * 1.1 = 1100 self.assertEqual(result['subtotal_with_markup'], 1100.0) self.assertEqual(result['discount_percent'], 0) self.assertEqual(result['total'], 1100.0) result = calculate_order_total(2) self.assertIsNotNone(result) # 20*60 = 1200 базовая сумма self.assertEqual(result['subtotal_without_markup'], 1200.0) # С наценкой: 1200 * 1.1 = 1320 self.assertEqual(result['subtotal_with_markup'], 1320.0) # Со скидкой 15%: 1320 * 0.85 = 1122 self.assertEqual(result['discount_percent'], 15) self.assertEqual(result['discount_amount'], 198.0) self.assertEqual(result['total'], 1122.0) def test_2_create_order_page(self): """Тест страницы создания заказа""" response = self.app.get('/add_order') self.assertEqual(response.status_code, 200) self.assertIn('Создание нового заказа', response.data.decode('utf-8')) def test_3_edit_order_page(self): """Тест страницы редактирования заказа""" response = self.app.get('/edit_order/1') self.assertEqual(response.status_code, 200) self.assertIn('Редактирование заказа #1', response.data.decode('utf-8')) def test_4_edit_order_without_items(self): """Тест редактирования заказа без изменения позиций (только дата/примечания)""" response = self.app.post('/edit_order/1', data={ 'order_date': '2026-03-05', 'notes': 'Обновлён без товаров' }, follow_redirects=True) self.assertEqual(response.status_code, 200) self.assertIn('Заказ обновлен', response.data.decode('utf-8')) from database import get_db with get_db() as conn: count = conn.execute('SELECT COUNT(*) FROM order_items WHERE order_id = 1').fetchone()[0] self.assertEqual(count, 2) def test_5_edit_order_add_new_item(self): """Тест добавления новой позиции при редактировании""" response = self.app.post('/edit_order/1', data={ 'order_date': '2026-03-05', 'notes': 'Добавлен новый товар', 'product_id[]': ['1', '2', '2'], 'quantity[]': ['5', '2', '3'], 'price[]': ['50.0', '60.0', '60.0'] }, follow_redirects=True) self.assertEqual(response.status_code, 200) self.assertIn('Заказ обновлен', response.data.decode('utf-8')) from database import get_db with get_db() as conn: new_count = conn.execute('SELECT COUNT(*) FROM order_items WHERE order_id = 1').fetchone()[0] items = conn.execute('SELECT product_id, quantity FROM order_items WHERE order_id = 1').fetchall() self.assertEqual(new_count, 3) expected_items = [ (1, 5), (2, 2), (2, 3) ] for i, (expected_product_id, expected_quantity) in enumerate(expected_items): self.assertEqual(items[i]['product_id'], expected_product_id) self.assertEqual(items[i]['quantity'], expected_quantity) def test_6_no_delete_button(self): """Тест отсутствия кнопки удаления на странице редактирования заказа""" # Сначала создаем заказ response = self.app.post('/add_order', data={ 'partner_id': '1', 'order_date': '2026-03-04', 'notes': 'Заказ для теста', 'product_id[]': ['1'], 'quantity[]': ['1'], 'price[]': ['50.0'] }, follow_redirects=True) self.assertEqual(response.status_code, 200) self.assertIn('Заказ успешно создан', response.data.decode('utf-8')) # Получаем ID созданного заказа from database import get_db with get_db() as conn: order_id = conn.execute('SELECT MAX(id) as id FROM orders').fetchone()['id'] # Проверяем, что на странице редактирования нет кнопки удаления response = self.app.get(f'/edit_order/{order_id}') self.assertEqual(response.status_code, 200) # Ищем текст, который указывает на отсутствие кнопки удаления html_content = response.data.decode('utf-8') # Проверяем, что нет HTML-элемента с текстом "Удалить заказ" self.assertNotIn('>Удалить заказ<', html_content) # Проверяем, что нет кнопки с классом btn-delete в HTML (не в CSS) import re # Ищем теги с классом btn-delete (например,