All checks were successful
Build and Push Docker Image / build (push) Successful in 52s
245 lines
9.8 KiB
Python
245 lines
9.8 KiB
Python
from django.conf import settings
|
||
from django.core import mail
|
||
from django.test import SimpleTestCase, TestCase, override_settings
|
||
from django.urls import reverse, resolve
|
||
|
||
from items.models import Category, Item
|
||
|
||
|
||
@override_settings(EMAIL_BACKEND="django.core.mail.backends.locmem.EmailBackend", ADMINISTRATOR_EMAIL="admin@example.com")
|
||
class FaqQuestionTests(TestCase):
|
||
def test_faq_question_form_sends_email_to_administrator(self):
|
||
response = self.client.post(
|
||
reverse("home"),
|
||
data={
|
||
"name": "Иван Петров",
|
||
"phone": "+375291112233",
|
||
"question": "Сколько стоит доставка?",
|
||
"accept": "on",
|
||
},
|
||
)
|
||
|
||
self.assertEqual(response.status_code, 302)
|
||
self.assertEqual(response["Location"], reverse("home") + "#faq-section")
|
||
self.assertEqual(len(mail.outbox), 1)
|
||
self.assertEqual(mail.outbox[0].to, ["admin@example.com"])
|
||
self.assertIn("Иван Петров", mail.outbox[0].body)
|
||
self.assertIn("Сколько стоит доставка?", mail.outbox[0].body)
|
||
|
||
def test_faq_question_form_requires_consent(self):
|
||
response = self.client.post(
|
||
reverse("home"),
|
||
data={
|
||
"name": "Иван Петров",
|
||
"phone": "+375291112233",
|
||
"question": "Сколько стоит доставка?",
|
||
},
|
||
)
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertEqual(len(mail.outbox), 0)
|
||
self.assertContains(response, "Необходимо согласие на обработку персональных данных.")
|
||
|
||
def test_faq_question_form_rejects_digits_in_name(self):
|
||
response = self.client.post(
|
||
reverse("home"),
|
||
data={
|
||
"name": "Иван123",
|
||
"phone": "+375291112233",
|
||
"question": "Сколько стоит доставка?",
|
||
"accept": "on",
|
||
},
|
||
)
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertEqual(len(mail.outbox), 0)
|
||
self.assertContains(response, "Имя не должно содержать цифры.")
|
||
|
||
def test_faq_question_form_rejects_invalid_phone_characters(self):
|
||
response = self.client.post(
|
||
reverse("home"),
|
||
data={
|
||
"name": "Иван Петров",
|
||
"phone": "+375 (29) abc",
|
||
"question": "Сколько стоит доставка?",
|
||
"accept": "on",
|
||
},
|
||
)
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertEqual(len(mail.outbox), 0)
|
||
self.assertContains(response, "Телефон может содержать только цифры и дефисы.")
|
||
|
||
def test_faq_question_form_accepts_phone_with_plus_and_dashes(self):
|
||
response = self.client.post(
|
||
reverse("home"),
|
||
data={
|
||
"name": "Иван Петров",
|
||
"phone": "+375-29-111-22-33",
|
||
"question": "Сколько стоит доставка?",
|
||
"accept": "on",
|
||
},
|
||
)
|
||
|
||
self.assertEqual(response.status_code, 302)
|
||
self.assertEqual(len(mail.outbox), 1)
|
||
|
||
def test_faq_question_form_accepts_phone_starting_with_digit(self):
|
||
response = self.client.post(
|
||
reverse("home"),
|
||
data={
|
||
"name": "Иван Петров",
|
||
"phone": "375291112233",
|
||
"question": "Сколько стоит доставка?",
|
||
"accept": "on",
|
||
},
|
||
)
|
||
|
||
self.assertEqual(response.status_code, 302)
|
||
self.assertEqual(len(mail.outbox), 1)
|
||
|
||
def test_faq_question_form_rejects_phone_with_invalid_digits_count(self):
|
||
response = self.client.post(
|
||
reverse("home"),
|
||
data={
|
||
"name": "Иван Петров",
|
||
"phone": "+12345",
|
||
"question": "Сколько стоит доставка?",
|
||
"accept": "on",
|
||
},
|
||
)
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertEqual(len(mail.outbox), 0)
|
||
self.assertContains(response, "Телефон должен содержать от 9 до 15 цифр.")
|
||
|
||
|
||
class HomePopularProductsTests(TestCase):
|
||
def setUp(self):
|
||
self.category = Category.objects.create(name="Plumbing", slug="plumbing")
|
||
|
||
def test_home_page_renders_available_products(self):
|
||
visible_item = Item.objects.create(
|
||
name="Visible sink",
|
||
slug="visible-sink",
|
||
category=self.category,
|
||
price="1600.00",
|
||
is_available=True,
|
||
)
|
||
Item.objects.create(
|
||
name="Hidden sink",
|
||
slug="hidden-sink",
|
||
category=self.category,
|
||
price="1800.00",
|
||
is_available=False,
|
||
)
|
||
|
||
response = self.client.get(reverse("home"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertContains(response, visible_item.name)
|
||
self.assertContains(response, reverse("detail", args=[self.category.slug, visible_item.slug]))
|
||
self.assertContains(
|
||
response,
|
||
f'<a class="product-card-link" href="{reverse("detail", args=[self.category.slug, visible_item.slug])}"',
|
||
html=False,
|
||
)
|
||
self.assertContains(response, "1600,00 руб.")
|
||
self.assertNotContains(response, "Hidden sink")
|
||
|
||
def test_home_page_limits_popular_products_to_six(self):
|
||
for index in range(7):
|
||
Item.objects.create(
|
||
name=f"Product {index}",
|
||
slug=f"product-{index}",
|
||
category=self.category,
|
||
price="1000.00",
|
||
is_available=True,
|
||
)
|
||
|
||
response = self.client.get(reverse("home"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertEqual(len(response.context["home_products"]), 6)
|
||
|
||
@override_settings(
|
||
HOME_ADVANTAGES_LEFT_CATEGORY_SLUG="custom-left",
|
||
HOME_ADVANTAGES_RIGHT_CATEGORY_SLUG="custom-right",
|
||
)
|
||
def test_home_advantages_buttons_use_configured_category_slugs(self):
|
||
Category.objects.create(name="Custom left", slug="custom-left")
|
||
Category.objects.create(name="Custom right", slug="custom-right")
|
||
|
||
response = self.client.get(reverse("home"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertContains(response, 'href="/catalog/custom-left/?new=1"', html=False)
|
||
self.assertContains(response, 'href="/catalog/custom-right/?sale=1"', html=False)
|
||
|
||
@override_settings(
|
||
HOME_ADVANTAGES_LEFT_CATEGORY_SLUG="custom-left",
|
||
HOME_ADVANTAGES_RIGHT_CATEGORY_SLUG="custom-right",
|
||
HOME_ADVANTAGES_LEFT_NEW_FILTER=False,
|
||
HOME_ADVANTAGES_RIGHT_SALE_FILTER=False,
|
||
)
|
||
def test_home_advantages_filter_flags_are_optional(self):
|
||
Category.objects.create(name="Custom left", slug="custom-left")
|
||
Category.objects.create(name="Custom right", slug="custom-right")
|
||
|
||
response = self.client.get(reverse("home"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertContains(response, 'href="/catalog/custom-left/"', html=False)
|
||
self.assertContains(response, 'href="/catalog/custom-right/"', html=False)
|
||
self.assertNotContains(response, 'href="/catalog/custom-left/?new=1"', html=False)
|
||
self.assertNotContains(response, 'href="/catalog/custom-right/?sale=1"', html=False)
|
||
|
||
|
||
class FaviconTests(SimpleTestCase):
|
||
def test_favicon_route_returns_icon(self):
|
||
response = self.client.get(reverse("favicon"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertEqual(response["Content-Type"], "image/svg+xml")
|
||
self.assertIn(b"<svg", response.content)
|
||
|
||
|
||
class MediaUrlTests(SimpleTestCase):
|
||
def test_media_route_is_registered(self):
|
||
match = resolve(f"{settings.MEDIA_URL}items/example.jpg")
|
||
|
||
self.assertEqual(match.func.__module__, "django.views.static")
|
||
self.assertEqual(match.func.__name__, "serve")
|
||
|
||
|
||
class ContactsPageTests(TestCase):
|
||
def test_contacts_page_renders_contact_details(self):
|
||
response = self.client.get(reverse("contacts"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertContains(response, "КОНТАКТЫ")
|
||
self.assertContains(response, "Беларусь, г. Минск, ул. Тимирязева, д. 123, к.1, пав. 59")
|
||
self.assertContains(response, "info@santehray.by")
|
||
self.assertContains(response, "+375 (29) 688-18-19")
|
||
self.assertContains(response, "+375 (33) 337-67-81")
|
||
|
||
def test_contacts_page_includes_leaflet_map_assets(self):
|
||
response = self.client.get(reverse("contacts"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertContains(response, "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css")
|
||
self.assertContains(response, "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js")
|
||
self.assertContains(response, 'id="contacts-map"', html=False)
|
||
self.assertContains(response, "L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'")
|
||
self.assertContains(response, "OpenStreetMap")
|
||
|
||
def test_contacts_page_does_not_include_yandex_api(self):
|
||
response = self.client.get(reverse("contacts"))
|
||
|
||
self.assertEqual(response.status_code, 200)
|
||
self.assertNotContains(response, "api-maps.yandex.ru")
|
||
self.assertNotContains(response, "YANDEX_MAPS_API_KEY")
|
||
self.assertContains(response, 'data-lat="53.9334960"', html=False)
|
||
self.assertContains(response, 'data-lon="27.4551021"', html=False)
|
||
self.assertContains(response, "Открыть адрес в OpenStreetMap")
|