Files
2022_oknardia/oknardia/web/test_prices.py

265 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from datetime import timedelta
from decimal import Decimal
from unittest.mock import patch
from django.contrib.auth.models import User
from django.db import connection
from django.http import HttpResponse
from django.test import RequestFactory, TestCase
from django.utils import timezone
from oknardia.models import (
Apartment_Type,
Glazing,
MerchantBrand,
MerchantOffice,
MountDim2Apartment,
OurUser,
PVCprofiles,
PriceOffer,
Seria_Info,
SetKit,
)
from web.prices import redirect_one_win_price_legacy, report_one_win_price, report_price_frame
class ReportOneWinPriceTests(TestCase):
"""Регрессионные тесты для ORM-версии report_one_win_price."""
def setUp(self) -> None:
self.factory = RequestFactory()
django_user = User.objects.create_user(username="price-tester", password="secret")
self.our_user = OurUser.objects.create(kDjangoUser=django_user)
# Тестовая SQLite-схема в проекте может быть legacy-вариантом с flap_config вместо sFlapConfig.
# Для тестов report_one_win_price явно добавляем sFlapConfig, чтобы код проверялся в целевом режиме.
with connection.cursor() as cursor:
cursor.execute("PRAGMA table_info(oknardia_win_mountdim)")
existing_columns = {row[1] for row in cursor.fetchall()}
if "sFlapConfig" not in existing_columns:
cursor.execute("ALTER TABLE oknardia_win_mountdim ADD COLUMN sFlapConfig varchar(32)")
# if "flap_config" in existing_columns:
# cursor.execute(
# "UPDATE oknardia_win_mountdim SET sFlapConfig = flap_config "
# "WHERE sFlapConfig IS NULL"
# )
self.brand = MerchantBrand.objects.create(
sMerchantName="Оконный бренд",
sMerchantMainURL="https://example.com",
)
self.office = MerchantOffice.objects.create(
sOfficeName="Оконный бренд — офис",
kMerchantName=self.brand,
sOfficePhones="+7(495)123-45-67",
sOfficeAddress="Москва, Тестовая улица, 1",
sOfficeDiscountMetaFormula="{'discount': {'10000': 5}}",
)
self.our_user.kMerchantOffice = self.office
self.our_user.save(update_fields=["kMerchantOffice"])
with connection.cursor() as cursor:
insert_columns = [
"iWinWidth",
"iWinHight",
"iWinDepth",
"sFlapConfig",
"sDescripion",
"bIsDoor",
"bIsNearDoor",
"iWinLimit",
"dMountXYZDataCreate",
"dMountXYZModify",
]
insert_values = [
Decimal("67.0"),
Decimal("216.0"),
Decimal("15.0"),
"[>]",
"Тестовый проём",
0,
0,
Decimal("5.0"),
]
if "flap_config" in existing_columns:
insert_columns.insert(3, "flap_config")
insert_values.insert(3, "[>]")
columns_sql = ", ".join(insert_columns)
placeholders_sql = ", ".join(["?"] * len(insert_values)) + ", CURRENT_TIMESTAMP, CURRENT_TIMESTAMP"
cursor.execute(
f"INSERT INTO oknardia_win_mountdim ({columns_sql}) VALUES ({placeholders_sql})",
insert_values,
)
self.window_id = cursor.lastrowid
self.seria = Seria_Info.objects.create(sName="П-44")
self.apartment = Apartment_Type.objects.create(
sNameApartment="1-комнатная",
kSeria=self.seria,
)
MountDim2Apartment.objects.create(
kApartment=self.apartment,
kMountDim_id=self.window_id,
iQuantity=1,
)
self.glazing = Glazing.objects.create(
sGlazingName="Тестовый стеклопакет",
sGlazingBriefDescription="Двухкамерный стеклопакет",
sGlazingMark="4-10-4-10-4",
sGlazingToning="нет",
kGlazing2User=self.our_user,
)
self.profile = PVCprofiles.objects.create(
sProfileName="Profile Test",
sProfileBriefDescription="Профиль для теста",
sProfileManufacturer="Test Manufacturer",
sProfileSealDescription="чёрный",
sProfileReinforcement="сталь",
kProfile2User=self.our_user,
fProfileRating=4.2,
)
self.set_kit = SetKit.objects.create(
sSetName="Тестовый набор",
kSet2User=self.our_user,
kSet2PVCprofiles=self.profile,
kSet2Glazing=self.glazing,
sSetImplementAll="Фурнитура",
sSetImplementHandles="Ручки",
sSetImplementHinges="Петли",
sSetImplementLatch="Запоры",
sSetImplementLimiter="Ограничитель",
sSetImplementCatch="Фиксатор",
sSetSill="Подоконник",
sSetSlope="Откос",
sSetPanes="Отлив",
sSetDelivery="Доставка",
bSetDelivery=True,
sSetUninstallInstall="Монтаж",
bSetUninstallInstall=True,
sSetOtherConditions="Прочие условия",
sSetClimateControl="Климат",
fSetRating=4.5,
dSetCommercialUntil=timezone.now() + timedelta(days=30),
)
self.active_offer = PriceOffer.objects.create(
kOffer2MountDim_id=self.window_id,
kOfferFromUser=self.our_user,
kOffer2SetKit=self.set_kit,
sOfferFlapConfig="[>]",
fOfferPrice=Decimal("12345.00"),
sOfferActive=True,
)
self.archived_offer = PriceOffer.objects.create(
kOffer2MountDim_id=self.window_id,
kOfferFromUser=self.our_user,
kOffer2SetKit=self.set_kit,
sOfferFlapConfig="[<]",
fOfferPrice=Decimal("11111.00"),
sOfferActive=False,
)
@patch("web.prices.get_flaps_for_mini_pictures", return_value="img/test-mini.png")
@patch(
"web.prices.get_flaps_for_big_pictures",
return_value={
"FLAP_DIM": [{
"iWinWidth": Decimal("67.0"),
"iWinHight": Decimal("216.0"),
"iWinWidth_mm": 670,
"iWinHight_mm": 2160,
}],
"WIN_DIM": [],
},
)
def test_report_one_win_price_renders_expected_context(
self,
mocked_big_pictures,
mocked_mini_pictures,
):
"""Вьюха должна собирать тот же ключевой контекст, но уже без raw SQL."""
request = self.factory.get(
f"/catalog/standard_opening/price-670x2160mm-tip{self.window_id}",
)
captured = {}
def fake_render(_request, template_name, context):
captured["template_name"] = template_name
captured["context"] = context
return HttpResponse("ok")
with patch("web.prices.render", side_effect=fake_render):
response = report_one_win_price(request, "670", "2160", str(self.window_id))
context = captured["context"]
self.assertEqual(response.status_code, 200)
self.assertEqual(captured["template_name"], "price/price_offers_for_one_window.html")
self.assertEqual(context["WIN_ID"], self.window_id)
self.assertEqual(context["MOUNT_DIM_PER_OFFER"], 1)
self.assertEqual(context["NUM_ARCHIVE_OFFER"], 1)
self.assertIn("2", context["NUM_TOTAL_OFFER_N_WORD"])
self.assertEqual(len(context["LIST_FLAP_VARIATION"]), 1)
self.assertEqual(context["LIST_FLAP_VARIATION"][0].sOfferFlapConfig, "[>]")
self.assertTrue(context["LIST_FLAP_VARIATION"][0].STR_NUM.startswith("вариант"))
self.assertEqual(context["LIST_FLAP_VARIATION"][0].IMG_MINI, "img/test-mini.png")
self.assertEqual(len(context["SERIA_FOR_WIN"]), 1)
self.assertEqual(context["SERIA_FOR_WIN"][0].sName, self.seria.sName)
self.assertEqual(len(context["PRICE_FRAME"]), 1)
self.assertEqual(context["PRICE_FRAME"][0]["SETS_NAME"], self.set_kit.sSetName)
self.assertEqual(context["PRICE_FRAME"][0]["MERCHANT"], self.brand.sMerchantName)
self.assertEqual(context["PRICE_FRAME"][0]["DIM"][0]["IMG_MINI"], "img/test-mini.png")
self.assertIn("META_DATA_PUBLISH", context)
self.assertTrue(mocked_big_pictures.called)
self.assertTrue(mocked_mini_pictures.called)
def test_report_one_win_price_redirects_to_canonical_dimensions(self):
"""Если SEO-размеры в URL неверные, вьюха должна редиректить на канонический URL."""
request = self.factory.get(
f"/catalog/standard_opening/price-999x999mm-tip{self.window_id}",
)
response = report_one_win_price(request, "999", "999", str(self.window_id))
self.assertEqual(response.status_code, 301)
self.assertEqual(
response["Location"],
f"/catalog/standard_opening/price-670x2160mm-tip{self.window_id}/",
)
def test_legacy_one_win_url_redirects_to_canonical_url(self):
"""Старый URL страницы одного окна должен отдавать 301 на новый канонический путь."""
request = self.factory.get(
f"/tsena-odnogo-okna/670x2160mm/tip{self.window_id}",
)
response = redirect_one_win_price_legacy(request, "670", "2160", str(self.window_id))
self.assertEqual(response.status_code, 301)
self.assertEqual(
response["Location"],
f"/catalog/standard_opening/price-670x2160mm-tip{self.window_id}/",
)
def test_report_price_frame_for_apartment_keeps_template_contract(self):
"""ORM-ветка для квартир должна сохранять ключи контекста для price_list*."""
frame = report_price_frame(
apartment_id=self.apartment.id,
mount_dim_per_offer=1,
address_longitude=0,
address_latitude=0,
frame_begin_n=0,
brand_id=0,
win_id=0,
)
self.assertIn("META_DATA_PUBLISH", frame)
self.assertIn("PRICE_FRAME", frame)
self.assertIn("N", frame)
self.assertEqual(len(frame["PRICE_FRAME"]), 1)
offer = frame["PRICE_FRAME"][0]
self.assertEqual(offer["SETS_ID"], self.set_kit.id)
self.assertEqual(offer["MERCHANT"], self.brand.sMerchantName)
self.assertEqual(offer["FIN_PRICE"], self.active_offer.fOfferPrice)
self.assertEqual(len(offer["DIM"]), 1)
self.assertEqual(offer["DIM"][0]["QUANTITY"], 1)