initial commit

This commit is contained in:
mohamad
2026-06-21 17:54:19 +03:30
commit 20d6df3b27
191 changed files with 14362 additions and 0 deletions
View File
+158
View File
@@ -0,0 +1,158 @@
import io
import zipfile
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import Client, TestCase, override_settings
from django.urls import reverse
from PIL import Image
from apps.pages.contact_uploads import (
MAX_ATTACHMENTS,
MAX_FILE_SIZE,
validate_contact_attachments,
)
from apps.pages.models import ContactSubmission, ContactSubmissionAttachment
def _png_file(name="screenshot.png"):
buffer = io.BytesIO()
Image.new("RGB", (8, 8), color="red").save(buffer, format="PNG")
buffer.seek(0)
return SimpleUploadedFile(name, buffer.read(), content_type="image/png")
def _zip_file(name="logs.zip", entries=None):
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED) as archive:
for entry_name, content in (entries or {"app.log": "line one\n"}).items():
archive.writestr(entry_name, content)
buffer.seek(0)
return SimpleUploadedFile(name, buffer.read(), content_type="application/zip")
class ContactUploadValidationTest(TestCase):
def test_accepts_valid_png(self):
validated = validate_contact_attachments([_png_file()])
self.assertEqual(len(validated), 1)
self.assertEqual(validated[0][1], "screenshot.png")
def test_accepts_valid_zip(self):
validated = validate_contact_attachments([_zip_file()])
self.assertEqual(len(validated), 1)
def test_accepts_valid_text_log(self):
uploaded = SimpleUploadedFile(
"error.log",
b"2026-06-07 ERROR something failed\n",
content_type="text/plain",
)
validated = validate_contact_attachments([uploaded])
self.assertEqual(validated[0][1], "error.log")
def test_rejects_executable_extension(self):
uploaded = SimpleUploadedFile(
"malware.exe",
b"MZfake",
content_type="application/octet-stream",
)
with self.assertRaises(Exception):
validate_contact_attachments([uploaded])
def test_rejects_php_disguised_as_png(self):
uploaded = SimpleUploadedFile(
"image.png",
b"<?php echo 'bad'; ?>",
content_type="image/png",
)
with self.assertRaises(Exception):
validate_contact_attachments([uploaded])
def test_rejects_oversized_file(self):
uploaded = SimpleUploadedFile(
"big.log",
b"x" * (MAX_FILE_SIZE + 1),
content_type="text/plain",
)
with self.assertRaises(Exception):
validate_contact_attachments([uploaded])
def test_rejects_too_many_files(self):
files = [_png_file(f"shot-{index}.png") for index in range(MAX_ATTACHMENTS + 1)]
with self.assertRaises(Exception):
validate_contact_attachments(files)
def test_rejects_zip_with_path_traversal(self):
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, "w") as archive:
archive.writestr("../escape.txt", "bad")
buffer.seek(0)
uploaded = SimpleUploadedFile(
"bad.zip",
buffer.read(),
content_type="application/zip",
)
with self.assertRaises(Exception):
validate_contact_attachments([uploaded])
@override_settings(
CONTACT_UPLOAD_ROOT=__import__("pathlib").Path(__file__).resolve().parents[3]
/ "test_private_uploads"
)
class ContactViewUploadTest(TestCase):
def setUp(self):
self.client = Client(enforce_csrf_checks=True)
self.url = reverse("pages:contact")
def _start_session(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.csrf_token = response.cookies["csrftoken"].value
captcha_question = response.context["captcha_question"]
left, right = captcha_question.split(" + ")
return int(left) + int(right)
def _post_contact(self, captcha_answer, attachments=None, extra=None):
payload = {
"name": "Test User",
"title": "Upload test",
"description": "Testing attachments",
"email": "test@example.com",
"captcha_answer": captcha_answer,
}
if attachments is not None:
payload["attachments"] = attachments
if extra:
payload.update(extra)
return self.client.post(
self.url,
data=payload,
HTTP_X_CSRFTOKEN=self.csrf_token,
)
def test_contact_submission_with_png_attachment(self):
captcha_answer = self._start_session()
response = self._post_contact(captcha_answer, attachments=_png_file())
self.assertEqual(response.status_code, 200)
self.assertTrue(response.json()["success"])
submission = ContactSubmission.objects.get(title="Upload test")
self.assertEqual(submission.attachments.count(), 1)
attachment = submission.attachments.first()
self.assertEqual(attachment.original_filename, "screenshot.png")
self.assertTrue(attachment.file.storage.exists(attachment.file.name))
def test_contact_submission_rejects_invalid_attachment(self):
captcha_answer = self._start_session()
response = self._post_contact(
captcha_answer,
attachments=SimpleUploadedFile(
"bad.exe",
b"MZ",
content_type="application/octet-stream",
),
)
self.assertEqual(response.status_code, 400)
self.assertFalse(response.json()["success"])
self.assertIn("attachments", response.json()["errors"])
self.assertEqual(ContactSubmission.objects.count(), 0)
self.assertEqual(ContactSubmissionAttachment.objects.count(), 0)
+94
View File
@@ -0,0 +1,94 @@
from django.test import TestCase
from django.urls import reverse
from apps.pages.models import CustomPage, CustomPageSection, CustomPageSectionItem
class CustomPageViewTest(TestCase):
def setUp(self):
self.page = CustomPage.objects.create(
title="Resources",
slug="resources",
show_in_nav=True,
menu_order=5,
is_published=True,
)
CustomPageSection.objects.create(
page=self.page,
section_type=CustomPageSection.TYPE_HERO,
title="Resources",
badge="Docs",
is_active=True,
)
CustomPage.objects.create(
title="Draft Page",
slug="draft",
is_published=False,
)
def test_published_page_returns_200(self):
response = self.client.get(reverse("pages:custom_page", kwargs={"slug": "resources"}))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "pages/custom_page.html")
self.assertEqual(response.context["custom_page"], self.page)
def test_unpublished_page_returns_404(self):
response = self.client.get(reverse("pages:custom_page", kwargs={"slug": "draft"}))
self.assertEqual(response.status_code, 404)
def test_unknown_slug_returns_404(self):
response = self.client.get(reverse("pages:custom_page", kwargs={"slug": "missing"}))
self.assertEqual(response.status_code, 404)
def test_section_item_with_url_renders_as_link(self):
section = CustomPageSection.objects.create(
page=self.page,
section_type=CustomPageSection.TYPE_FEATURES,
title="Highlights",
is_active=True,
)
CustomPageSectionItem.objects.create(
page=self.page,
section=section,
title="Documentation",
content="Read the docs.",
url="/about/",
order=1,
)
response = self.client.get(reverse("pages:custom_page", kwargs={"slug": "resources"}))
self.assertContains(response, 'href="/about/"')
self.assertContains(response, "section-item-link")
self.assertContains(response, "Documentation")
class CustomPageNavTest(TestCase):
def test_nav_custom_pages_in_context(self):
CustomPage.objects.create(
title="Visible",
slug="visible",
show_in_nav=True,
menu_order=1,
is_published=True,
)
CustomPage.objects.create(
title="Hidden Nav",
slug="hidden-nav",
show_in_nav=False,
is_published=True,
)
response = self.client.get(reverse("pages:home"))
pages = list(response.context["nav_custom_pages"])
self.assertEqual(len(pages), 1)
self.assertEqual(pages[0].slug, "visible")
def test_nav_link_rendered(self):
CustomPage.objects.create(
title="Team",
slug="team",
menu_label="Our Team",
show_in_nav=True,
is_published=True,
)
response = self.client.get(reverse("pages:home"))
self.assertContains(response, "Our Team")
self.assertContains(response, reverse("pages:custom_page", kwargs={"slug": "team"}))
+187
View File
@@ -0,0 +1,187 @@
from django.test import TestCase
from django.urls import reverse
from apps.core.video import parse_youtube_video_id, youtube_embed_url
from apps.pages.models import (
AboutSection,
CustomPage,
CustomPageSection,
HomepageSection,
PageVideo,
)
from apps.products.models import MainProduct, ProductVideo
class YouTubeParsingTest(TestCase):
def test_watch_url(self):
self.assertEqual(
parse_youtube_video_id("https://www.youtube.com/watch?v=dQw4w9WgXcQ"),
"dQw4w9WgXcQ",
)
def test_short_url(self):
self.assertEqual(
parse_youtube_video_id("https://youtu.be/dQw4w9WgXcQ"),
"dQw4w9WgXcQ",
)
def test_embed_url(self):
url = youtube_embed_url("https://youtu.be/dQw4w9WgXcQ")
self.assertEqual(url, "https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ")
class HomepageVideoSectionTest(TestCase):
def test_video_section_renders_youtube_embed(self):
HomepageSection.objects.create(
section_type=HomepageSection.TYPE_VIDEO,
title="Demo",
video_source="youtube",
video_url="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
is_active=True,
)
response = self.client.get(reverse("pages:home"))
self.assertContains(response, "youtube-nocookie.com/embed/dQw4w9WgXcQ")
self.assertContains(response, "video-block--md")
class AboutVideoSectionTest(TestCase):
def test_video_section_renders_on_about_page(self):
AboutSection.objects.create(
section_type=AboutSection.TYPE_VIDEO,
title="Overview",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
video_size="lg",
is_active=True,
)
response = self.client.get(reverse("pages:about"))
self.assertContains(response, "video-block--lg")
self.assertContains(response, "Overview")
class CustomPageVideoSectionTest(TestCase):
def test_video_section_renders_on_custom_page(self):
page = CustomPage.objects.create(
title="Media",
slug="media-page",
is_published=True,
)
CustomPageSection.objects.create(
page=page,
section_type=CustomPageSection.TYPE_VIDEO,
title="Walkthrough",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
is_active=True,
)
response = self.client.get(reverse("pages:custom_page", kwargs={"slug": "media-page"}))
self.assertContains(response, "Walkthrough")
self.assertContains(response, "iframe")
class PageVideoTest(TestCase):
def test_contact_page_video(self):
PageVideo.objects.create(
page=PageVideo.PAGE_CONTACT,
title="Intro",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
is_active=True,
)
response = self.client.get(reverse("pages:contact"))
self.assertContains(response, "Intro")
self.assertContains(response, "youtube-nocookie.com/embed/dQw4w9WgXcQ")
def test_faq_page_video(self):
PageVideo.objects.create(
page=PageVideo.PAGE_FAQ,
title="Tutorial",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
is_active=True,
)
response = self.client.get(reverse("pages:faq"))
self.assertContains(response, "Tutorial")
class ProductVideoTest(TestCase):
def setUp(self):
self.main_product = MainProduct.objects.create(
name="Tecvico",
slug="tecvico",
short_description="Short",
description="Long",
is_active=True,
)
def test_product_video_renders_on_detail_page(self):
ProductVideo.objects.create(
main_product=self.main_product,
title="Product Demo",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
video_size="full",
is_active=True,
)
response = self.client.get(
reverse("products:main_product_detail", kwargs={"main_slug": "tecvico"})
)
self.assertContains(response, "Product Demo")
self.assertContains(response, "video-block--full")
class VideoStyledBackgroundTest(TestCase):
def test_styled_background_renders_panel(self):
HomepageSection.objects.create(
section_type=HomepageSection.TYPE_VIDEO,
title="Styled Demo",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
video_styled_background=True,
is_active=True,
)
response = self.client.get(reverse("pages:home"))
self.assertContains(response, "video-panel--styled")
self.assertContains(response, "video-panel-blob")
def test_plain_background_without_panel(self):
HomepageSection.objects.create(
section_type=HomepageSection.TYPE_VIDEO,
title="Plain Demo",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
video_styled_background=False,
is_active=True,
)
response = self.client.get(reverse("pages:home"))
self.assertNotContains(response, "video-panel--styled")
self.assertContains(response, "Plain Demo")
class VideoDescriptionFormatTest(TestCase):
def test_plain_description_preserves_line_breaks(self):
HomepageSection.objects.create(
section_type=HomepageSection.TYPE_VIDEO,
title="Demo",
description="First line\nSecond line",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
is_active=True,
)
response = self.client.get(reverse("pages:home"))
self.assertContains(response, "First line")
self.assertContains(response, "Second line")
self.assertContains(response, "<br>")
def test_markdown_description_renders(self):
PageVideo.objects.create(
page=PageVideo.PAGE_FAQ,
title="Guide",
description="**Bold** intro",
description_format="markdown",
video_source="youtube",
video_url="https://youtu.be/dQw4w9WgXcQ",
is_active=True,
)
response = self.client.get(reverse("pages:faq"))
self.assertContains(response, "<strong>Bold</strong>")
+125
View File
@@ -0,0 +1,125 @@
from django.test import TestCase
from django.urls import reverse
from apps.pages.models import FAQEntry
class HomeViewTest(TestCase):
def test_home_returns_200(self):
response = self.client.get(reverse("pages:home"))
self.assertEqual(response.status_code, 200)
def test_home_uses_correct_template(self):
response = self.client.get(reverse("pages:home"))
self.assertTemplateUsed(response, "pages/home.html")
def test_home_renders_dynamic_showcase_sections(self):
from apps.pages.models import HomepageSection
projects = HomepageSection.objects.create(
section_type=HomepageSection.TYPE_PROJECTS,
title="Our Journey in the Realm of",
title_highlight="Outstanding Projects",
description="Explore our standout projects.",
order=50,
is_active=True,
)
HomepageSection.objects.create(
section_type=HomepageSection.TYPE_EXPERIENCE,
title="Experience Leading",
title_highlight="the Way in Development",
description="Embark on a journey of accelerated product development.",
order=51,
is_active=True,
)
response = self.client.get(reverse("pages:home"))
content = response.content.decode()
self.assertIn("Our Journey in the Realm of", content)
self.assertIn("Outstanding Projects", content)
self.assertIn("Experience Leading", content)
self.assertIn("the Way in Development", content)
self.assertIn('data-project-filter="all"', content)
class AboutViewTest(TestCase):
def test_about_returns_200(self):
response = self.client.get(reverse("pages:about"))
self.assertEqual(response.status_code, 200)
def test_about_uses_correct_template(self):
response = self.client.get(reverse("pages:about"))
self.assertTemplateUsed(response, "pages/about.html")
class FAQViewTest(TestCase):
def setUp(self):
FAQEntry.objects.create(
question="What is the license?",
answer="It is CC BY-NC-SA.",
order=1,
is_active=True,
)
FAQEntry.objects.create(
question="Hidden question",
answer="Hidden answer",
order=2,
is_active=False,
)
def test_faq_returns_200(self):
response = self.client.get(reverse("pages:faq"))
self.assertEqual(response.status_code, 200)
def test_faq_uses_correct_template(self):
response = self.client.get(reverse("pages:faq"))
self.assertTemplateUsed(response, "pages/faq.html")
def test_faq_only_shows_active_entries(self):
response = self.client.get(reverse("pages:faq"))
entries = response.context["faq_entries"]
self.assertEqual(entries.count(), 1)
self.assertEqual(entries.first().question, "What is the license?")
class ContactViewTest(TestCase):
def test_contact_returns_200(self):
response = self.client.get(reverse("pages:contact"))
self.assertEqual(response.status_code, 200)
def test_contact_uses_correct_template(self):
response = self.client.get(reverse("pages:contact"))
self.assertTemplateUsed(response, "pages/contact.html")
class NavigationContextTest(TestCase):
def test_nav_main_products_in_context_on_all_pages(self):
urls = [
reverse("pages:home"),
reverse("pages:about"),
reverse("pages:faq"),
reverse("pages:contact"),
reverse("products:overview"),
]
for url in urls:
response = self.client.get(url)
self.assertIn(
"nav_main_products",
response.context,
f"Missing nav_main_products at {url}",
)
def test_nav_custom_pages_in_context_on_all_pages(self):
urls = [
reverse("pages:home"),
reverse("pages:about"),
reverse("pages:faq"),
reverse("pages:contact"),
]
for url in urls:
response = self.client.get(url)
self.assertIn(
"nav_custom_pages",
response.context,
f"Missing nav_custom_pages at {url}",
)