diff options
author | 2020-10-04 18:55:33 +0300 | |
---|---|---|
committer | 2020-10-04 18:55:33 +0300 | |
commit | aff3a89c3cec04eda096e8f27115e36108ee6286 (patch) | |
tree | 299fb51b60916e6b552fa1ac7e0e05dbef512343 | |
parent | Add more information to how to write a guide guide (diff) |
Change guides system to content system
As this system will be used for more than just guides,
I had to do some refactoring to match this system with plans.
Basically now there isn't guides, but articles instead.
Diffstat (limited to '')
31 files changed, 328 insertions, 324 deletions
diff --git a/pydis_site/apps/guides/__init__.py b/pydis_site/apps/content/__init__.py index e69de29b..e69de29b 100644 --- a/pydis_site/apps/guides/__init__.py +++ b/pydis_site/apps/content/__init__.py diff --git a/pydis_site/apps/content/apps.py b/pydis_site/apps/content/apps.py new file mode 100644 index 00000000..1e300a48 --- /dev/null +++ b/pydis_site/apps/content/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + + +class ContentConfig(AppConfig): + """Django AppConfig for content app.""" + + name = 'content' diff --git a/pydis_site/apps/guides/migrations/__init__.py b/pydis_site/apps/content/migrations/__init__.py index e69de29b..e69de29b 100644 --- a/pydis_site/apps/guides/migrations/__init__.py +++ b/pydis_site/apps/content/migrations/__init__.py diff --git a/pydis_site/apps/content/resources/content/guides/_info.yml b/pydis_site/apps/content/resources/content/guides/_info.yml new file mode 100644 index 00000000..8a38271d --- /dev/null +++ b/pydis_site/apps/content/resources/content/guides/_info.yml @@ -0,0 +1,2 @@ +name: Guides +description: Python and PyDis guides.
\ No newline at end of file diff --git a/pydis_site/apps/guides/resources/guides/how-to-write-a-guide.md b/pydis_site/apps/content/resources/content/guides/how-to-write-a-guide.md index 072c2538..072c2538 100644 --- a/pydis_site/apps/guides/resources/guides/how-to-write-a-guide.md +++ b/pydis_site/apps/content/resources/content/guides/how-to-write-a-guide.md diff --git a/pydis_site/apps/guides/tests/__init__.py b/pydis_site/apps/content/tests/__init__.py index e69de29b..e69de29b 100644 --- a/pydis_site/apps/guides/tests/__init__.py +++ b/pydis_site/apps/content/tests/__init__.py diff --git a/pydis_site/apps/guides/tests/test_guides/category/_info.yml b/pydis_site/apps/content/tests/test_content/category/_info.yml index 8311509d..8311509d 100644 --- a/pydis_site/apps/guides/tests/test_guides/category/_info.yml +++ b/pydis_site/apps/content/tests/test_content/category/_info.yml diff --git a/pydis_site/apps/guides/tests/test_guides/category/test3.md b/pydis_site/apps/content/tests/test_content/category/test3.md index bdde6188..bdde6188 100644 --- a/pydis_site/apps/guides/tests/test_guides/category/test3.md +++ b/pydis_site/apps/content/tests/test_content/category/test3.md diff --git a/pydis_site/apps/guides/tests/test_guides/test.md b/pydis_site/apps/content/tests/test_content/test.md index 7a917899..7a917899 100644 --- a/pydis_site/apps/guides/tests/test_guides/test.md +++ b/pydis_site/apps/content/tests/test_content/test.md diff --git a/pydis_site/apps/guides/tests/test_guides/test2.md b/pydis_site/apps/content/tests/test_content/test2.md index f0852356..f0852356 100644 --- a/pydis_site/apps/guides/tests/test_guides/test2.md +++ b/pydis_site/apps/content/tests/test_content/test2.md diff --git a/pydis_site/apps/content/tests/test_utils.py b/pydis_site/apps/content/tests/test_utils.py new file mode 100644 index 00000000..82e1ac5f --- /dev/null +++ b/pydis_site/apps/content/tests/test_utils.py @@ -0,0 +1,122 @@ +import os +from unittest.mock import patch + +from django.conf import settings +from django.http import Http404 +from django.test import TestCase +from markdown import Markdown + +from pydis_site.apps.content import utils + +BASE_PATH = os.path.join(settings.BASE_DIR, "pydis_site", "apps", "content", "tests", "test_content") + + +class TestGetBasePath(TestCase): + def test_get_base_path(self): + """Test does function return content base path.""" + self.assertEqual( + utils._get_base_path(), + os.path.join(settings.BASE_DIR, "pydis_site", "apps", "content", "resources", "content") + ) + + +class TestGetCategory(TestCase): + def test_get_category_successfully(self): + """Check does this get right data from category data file.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + result = utils.get_category("category") + + self.assertEqual(result, {"name": "My Category", "description": "My Description"}) + + def test_get_category_not_exists(self): + """Check does this raise 404 error when category don't exists.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + with self.assertRaises(Http404): + utils.get_category("invalid") + + def test_get_category_not_directory(self): + """Check does this raise 404 error when category isn't directory.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + with self.assertRaises(Http404): + utils.get_category("test.md") + + +class TestGetCategories(TestCase): + def test_get_categories(self): + """Check does this return test content categories.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + result = utils.get_categories() + + self.assertEqual(result, {"category": {"name": "My Category", "description": "My Description"}}) + + +class TestGetArticles(TestCase): + def test_get_all_root_articles(self): + """Check does this return all root level testing content.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + result = utils.get_articles() + + for case in ["test", "test2"]: + with self.subTest(guide=case): + md = Markdown(extensions=['meta']) + with open(os.path.join(BASE_PATH, f"{case}.md")) as f: + md.convert(f.read()) + + self.assertIn(case, result) + self.assertEqual(md.Meta, result[case]) + + def test_get_all_category_articles(self): + """Check does this return all category testing content.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + result = utils.get_articles("category") + + md = Markdown(extensions=['meta']) + with open(os.path.join(BASE_PATH, "category", "test3.md")) as f: + md.convert(f.read()) + + self.assertIn("test3", result) + self.assertEqual(md.Meta, result["test3"]) + + +class TestGetArticle(TestCase): + def test_get_root_article_success(self): + """Check does this return article HTML and metadata when root article exist.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + result = utils.get_article("test", None) + + md = Markdown(extensions=['meta', 'attr_list', 'fenced_code']) + + with open(os.path.join(BASE_PATH, "test.md")) as f: + html = md.convert(f.read()) + + self.assertEqual(result, {"article": html, "metadata": md.Meta}) + + def test_get_root_article_dont_exist(self): + """Check does this raise Http404 when root article don't exist.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + with self.assertRaises(Http404): + utils.get_article("invalid", None) + + def test_get_category_article_success(self): + """Check does this return article HTML and metadata when category guide exist.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + result = utils.get_article("test3", "category") + + md = Markdown(extensions=['meta', 'attr_list', 'fenced_code']) + + with open(os.path.join(BASE_PATH, "category", "test3.md")) as f: + html = md.convert(f.read()) + + self.assertEqual(result, {"article": html, "metadata": md.Meta}) + + def test_get_category_article_dont_exist(self): + """Check does this raise Http404 when category article don't exist.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + with self.assertRaises(Http404): + utils.get_article("invalid", "category") + + def test_get_category_article_category_dont_exist(self): + """Check does this raise Http404 when category don't exist.""" + with patch("pydis_site.apps.content.utils._get_base_path", return_value=BASE_PATH): + with self.assertRaises(Http404): + utils.get_article("some-guide", "invalid") diff --git a/pydis_site/apps/content/tests/test_views.py b/pydis_site/apps/content/tests/test_views.py new file mode 100644 index 00000000..98054534 --- /dev/null +++ b/pydis_site/apps/content/tests/test_views.py @@ -0,0 +1,104 @@ +from unittest.mock import patch + +from django.http import Http404 +from django.test import TestCase +from django_hosts.resolvers import reverse + + +class TestGuidesIndexView(TestCase): + @patch("pydis_site.apps.content.views.articles.get_articles") + @patch("pydis_site.apps.content.views.articles.get_categories") + def test_articles_index_return_200(self, get_categories_mock, get_articles_mock): + """Check that content index return HTTP code 200.""" + get_categories_mock.return_value = {} + get_articles_mock.return_value = {} + + url = reverse('content:content') + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + get_articles_mock.assert_called_once() + get_categories_mock.assert_called_once() + + +class TestGuideView(TestCase): + @patch("pydis_site.apps.content.views.article.os.path.getmtime") + @patch("pydis_site.apps.content.views.article.get_article") + @patch("pydis_site.apps.content.views.article.get_category") + def test_guide_return_code_200(self, get_category_mock, get_article_mock, get_time_mock): + get_article_mock.return_value = {"guide": "test", "metadata": {}} + + url = reverse("content:article", args=["test-guide"]) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + get_category_mock.assert_not_called() + get_article_mock.assert_called_once_with("test-guide", None) + + @patch("pydis_site.apps.content.views.article.os.path.getmtime") + @patch("pydis_site.apps.content.views.article.get_article") + @patch("pydis_site.apps.content.views.article.get_category") + def test_guide_return_404(self, get_category_mock, get_article_mock, get_time_mock): + """Check that return code is 404 when invalid article provided.""" + get_article_mock.side_effect = Http404("Article not found.") + + url = reverse("content:article", args=["invalid-guide"]) + response = self.client.get(url) + self.assertEqual(response.status_code, 404) + get_article_mock.assert_called_once_with("invalid-guide", None) + get_category_mock.assert_not_called() + + +class TestCategoryView(TestCase): + @patch("pydis_site.apps.content.views.category.get_category") + @patch("pydis_site.apps.content.views.category.get_articles") + def test_valid_category_code_200(self, get_articles_mock, get_category_mock): + """Check that return code is 200 when visiting valid category.""" + get_category_mock.return_value = {"name": "test", "description": "test"} + get_articles_mock.return_value = {} + + url = reverse("content:category", args=["category"]) + response = self.client.get(url) + + self.assertEqual(response.status_code, 200) + get_articles_mock.assert_called_once_with("category") + get_category_mock.assert_called_once_with("category") + + @patch("pydis_site.apps.content.views.category.get_category") + @patch("pydis_site.apps.content.views.category.get_articles") + def test_invalid_category_code_404(self, get_articles_mock, get_category_mock): + """Check that return code is 404 when trying to visit invalid category.""" + get_category_mock.side_effect = Http404("Category not found.") + + url = reverse("content:category", args=["invalid-category"]) + response = self.client.get(url) + + self.assertEqual(response.status_code, 404) + get_category_mock.assert_called_once_with("invalid-category") + get_articles_mock.assert_not_called() + + +class TestCategoryGuidesView(TestCase): + @patch("pydis_site.apps.content.views.article.os.path.getmtime") + @patch("pydis_site.apps.content.views.article.get_article") + @patch("pydis_site.apps.content.views.article.get_category") + def test_valid_category_article_code_200(self, get_category_mock, get_article_mock, get_time_mock): + """Check that return code is 200 when visiting valid category article.""" + get_article_mock.return_value = {"guide": "test", "metadata": {}} + + url = reverse("content:category_article", args=["category", "test3"]) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + get_article_mock.assert_called_once_with("test3", "category") + get_category_mock.assert_called_once_with("category") + + @patch("pydis_site.apps.content.views.article.os.path.getmtime") + @patch("pydis_site.apps.content.views.article.get_article") + @patch("pydis_site.apps.content.views.article.get_category") + def test_invalid_category_article_code_404(self, get_category_mock, get_article_mock, get_time_mock): + """Check that return code is 200 when trying to visit invalid category article.""" + get_article_mock.side_effect = Http404("Article not found.") + + url = reverse("content:category_article", args=["category", "invalid"]) + response = self.client.get(url) + self.assertEqual(response.status_code, 404) + get_article_mock.assert_called_once_with("invalid", "category") + get_category_mock.assert_not_called() diff --git a/pydis_site/apps/content/urls.py b/pydis_site/apps/content/urls.py new file mode 100644 index 00000000..ae9b1e57 --- /dev/null +++ b/pydis_site/apps/content/urls.py @@ -0,0 +1,11 @@ +from django.urls import path + +from . import views + +app_name = "content" +urlpatterns = [ + path("", views.ArticlesView.as_view(), name='content'), + path("category/<str:category>/", views.CategoryView.as_view(), name='category'), + path("category/<str:category>/<str:article>/", views.ArticleView.as_view(), name='category_article'), + path("<str:article>/", views.ArticleView.as_view(), name='article') +] diff --git a/pydis_site/apps/guides/utils.py b/pydis_site/apps/content/utils.py index c6f668f7..57905a69 100644 --- a/pydis_site/apps/guides/utils.py +++ b/pydis_site/apps/content/utils.py @@ -9,7 +9,7 @@ from markdown import Markdown def _get_base_path() -> str: """Have extra function for base path getting for testability.""" - return os.path.join(settings.BASE_DIR, "pydis_site", "apps", "guides", "resources", "guides") + return os.path.join(settings.BASE_DIR, "pydis_site", "apps", "content", "resources", "content") def get_category(category: str) -> Dict[str, str]: @@ -34,14 +34,14 @@ def get_categories() -> Dict[str, Dict]: return categories -def get_guides(category: Optional[str] = None) -> Dict[str, Dict]: - """Get all root guides when category is not specified. Otherwise get all this category guides.""" +def get_articles(category: Optional[str] = None) -> Dict[str, Dict]: + """Get all root content when category is not specified. Otherwise get all this category content.""" if category is None: base_dir = _get_base_path() else: base_dir = os.path.join(_get_base_path(), category) - guides = {} + articles = {} for filename in os.listdir(base_dir): full_path = os.path.join(base_dir, filename) @@ -50,13 +50,13 @@ def get_guides(category: Optional[str] = None) -> Dict[str, Dict]: with open(full_path) as f: md.convert(f.read()) - guides[os.path.splitext(filename)[0]] = md.Meta + articles[os.path.splitext(filename)[0]] = md.Meta - return guides + return articles -def get_guide(guide: str, category: Optional[str]) -> Dict[str, Union[str, Dict]]: - """Get one specific guide. When category is specified, get it from there.""" +def get_article(article: str, category: Optional[str]) -> Dict[str, Union[str, Dict]]: + """Get one specific article. When category is specified, get it from there.""" if category is None: base_path = _get_base_path() else: @@ -65,13 +65,13 @@ def get_guide(guide: str, category: Optional[str]) -> Dict[str, Union[str, Dict] if not os.path.exists(base_path) or not os.path.isdir(base_path): raise Http404("Category not found.") - guide_path = os.path.join(base_path, f"{guide}.md") - if not os.path.exists(guide_path) or not os.path.isfile(guide_path): - raise Http404("Guide not found.") + article_path = os.path.join(base_path, f"{article}.md") + if not os.path.exists(article_path) or not os.path.isfile(article_path): + raise Http404("Article not found.") md = Markdown(extensions=['meta', 'attr_list', 'fenced_code']) - with open(guide_path) as f: + with open(article_path) as f: html = md.convert(f.read()) - return {"guide": html, "metadata": md.Meta} + return {"article": html, "metadata": md.Meta} diff --git a/pydis_site/apps/content/views/__init__.py b/pydis_site/apps/content/views/__init__.py new file mode 100644 index 00000000..b50d487b --- /dev/null +++ b/pydis_site/apps/content/views/__init__.py @@ -0,0 +1,5 @@ +from .category import CategoryView +from .article import ArticleView +from .articles import ArticlesView + +__all__ = ["ArticleView", "ArticlesView", "CategoryView"] diff --git a/pydis_site/apps/guides/views/guide.py b/pydis_site/apps/content/views/article.py index bcd68bc4..b34ca3ee 100644 --- a/pydis_site/apps/guides/views/guide.py +++ b/pydis_site/apps/content/views/article.py @@ -8,22 +8,24 @@ from django.http import HttpResponse from django.shortcuts import render from django.views import View -from pydis_site.apps.guides.utils import get_category, get_guide +from pydis_site.apps.content.utils import get_category, get_article -class GuideView(View): +class ArticleView(View): """Shows specific guide page.""" - def get(self, request: WSGIRequest, guide: str, category: Optional[str] = None) -> HttpResponse: + def get(self, request: WSGIRequest, article: str, category: Optional[str] = None) -> HttpResponse: """Collect guide content and display it. When guide don't exist, return 404.""" - guide_result = get_guide(guide, category) + article_result = get_article(article, category) if category is not None: path = os.path.join( - settings.BASE_DIR, "pydis_site", "apps", "guides", "resources", "guides", category, f"{guide}.md" + settings.BASE_DIR, "pydis_site", "apps", "content", "resources", "content", category, f"{article}.md" ) else: - path = os.path.join(settings.BASE_DIR, "pydis_site", "apps", "guides", "resources", "guides", f"{guide}.md") + path = os.path.join( + settings.BASE_DIR, "pydis_site", "apps", "content", "resources", "content", f"{article}.md" + ) if category is not None: category_data = get_category(category) @@ -33,15 +35,15 @@ class GuideView(View): return render( request, - "guides/guide.html", + "content/article.html", { - "guide": guide_result, + "article": article_result, "last_modified": datetime.fromtimestamp(os.path.getmtime(path)).strftime("%dth %B %Y"), "category_data": category_data, "relevant_links": { link: value for link, value in zip( - guide_result["metadata"].get("relevantlinks", []), - guide_result["metadata"].get("relevantlinkvalues", []) + article_result["metadata"].get("relevantlinks", []), + article_result["metadata"].get("relevantlinkvalues", []) ) } } diff --git a/pydis_site/apps/content/views/articles.py b/pydis_site/apps/content/views/articles.py new file mode 100644 index 00000000..ff945a19 --- /dev/null +++ b/pydis_site/apps/content/views/articles.py @@ -0,0 +1,14 @@ +from django.core.handlers.wsgi import WSGIRequest +from django.http import HttpResponse +from django.shortcuts import render +from django.views import View + +from pydis_site.apps.content.utils import get_categories, get_articles + + +class ArticlesView(View): + """Shows all content and categories.""" + + def get(self, request: WSGIRequest) -> HttpResponse: + """Shows all content and categories.""" + return render(request, "content/articles.html", {"content": get_articles(), "categories": get_categories()}) diff --git a/pydis_site/apps/content/views/category.py b/pydis_site/apps/content/views/category.py new file mode 100644 index 00000000..62e80a47 --- /dev/null +++ b/pydis_site/apps/content/views/category.py @@ -0,0 +1,18 @@ +from django.core.handlers.wsgi import WSGIRequest +from django.http import HttpResponse +from django.shortcuts import render +from django.views import View + +from pydis_site.apps.content.utils import get_category, get_articles + + +class CategoryView(View): + """Handles content category page.""" + + def get(self, request: WSGIRequest, category: str) -> HttpResponse: + """Handles page that displays category content.""" + return render( + request, + "content/category.html", + {"category_info": get_category(category), "content": get_articles(category), "category_name": category} + ) diff --git a/pydis_site/apps/guides/apps.py b/pydis_site/apps/guides/apps.py deleted file mode 100644 index 8dfa4f65..00000000 --- a/pydis_site/apps/guides/apps.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.apps import AppConfig - - -class GuidesConfig(AppConfig): - """Django AppConfig for guides app.""" - - name = 'guides' diff --git a/pydis_site/apps/guides/tests/test_utils.py b/pydis_site/apps/guides/tests/test_utils.py deleted file mode 100644 index e7448be6..00000000 --- a/pydis_site/apps/guides/tests/test_utils.py +++ /dev/null @@ -1,122 +0,0 @@ -import os -from unittest.mock import patch - -from django.conf import settings -from django.http import Http404 -from django.test import TestCase -from markdown import Markdown - -from pydis_site.apps.guides import utils - -BASE_PATH = os.path.join(settings.BASE_DIR, "pydis_site", "apps", "guides", "tests", "test_guides") - - -class TestGetBasePath(TestCase): - def test_get_base_path(self): - """Test does function return guides base path.""" - self.assertEqual( - utils._get_base_path(), - os.path.join(settings.BASE_DIR, "pydis_site", "apps", "guides", "resources", "guides") - ) - - -class TestGetCategory(TestCase): - def test_get_category_successfully(self): - """Check does this get right data from category data file.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - result = utils.get_category("category") - - self.assertEqual(result, {"name": "My Category", "description": "My Description"}) - - def test_get_category_not_exists(self): - """Check does this raise 404 error when category don't exists.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - with self.assertRaises(Http404): - utils.get_category("invalid") - - def test_get_category_not_directory(self): - """Check does this raise 404 error when category isn't directory.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - with self.assertRaises(Http404): - utils.get_category("test.md") - - -class TestGetCategories(TestCase): - def test_get_categories(self): - """Check does this return test guides categories.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - result = utils.get_categories() - - self.assertEqual(result, {"category": {"name": "My Category", "description": "My Description"}}) - - -class TestGetGuides(TestCase): - def test_get_all_root_guides(self): - """Check does this return all root level testing guides.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - result = utils.get_guides() - - for case in ["test", "test2"]: - with self.subTest(guide=case): - md = Markdown(extensions=['meta']) - with open(os.path.join(BASE_PATH, f"{case}.md")) as f: - md.convert(f.read()) - - self.assertIn(case, result) - self.assertEqual(md.Meta, result[case]) - - def test_get_all_category_guides(self): - """Check does this return all category testing guides.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - result = utils.get_guides("category") - - md = Markdown(extensions=['meta']) - with open(os.path.join(BASE_PATH, "category", "test3.md")) as f: - md.convert(f.read()) - - self.assertIn("test3", result) - self.assertEqual(md.Meta, result["test3"]) - - -class TestGetGuide(TestCase): - def test_get_root_guide_success(self): - """Check does this return guide HTML and metadata when root guide exist.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - result = utils.get_guide("test", None) - - md = Markdown(extensions=['meta', 'attr_list', 'fenced_code']) - - with open(os.path.join(BASE_PATH, "test.md")) as f: - html = md.convert(f.read()) - - self.assertEqual(result, {"guide": html, "metadata": md.Meta}) - - def test_get_root_guide_dont_exist(self): - """Check does this raise Http404 when root guide don't exist.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - with self.assertRaises(Http404): - result = utils.get_guide("invalid", None) - - def test_get_category_guide_success(self): - """Check does this return guide HTML and metadata when category guide exist.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - result = utils.get_guide("test3", "category") - - md = Markdown(extensions=['meta', 'attr_list', 'fenced_code']) - - with open(os.path.join(BASE_PATH, "category", "test3.md")) as f: - html = md.convert(f.read()) - - self.assertEqual(result, {"guide": html, "metadata": md.Meta}) - - def test_get_category_guide_dont_exist(self): - """Check does this raise Http404 when category guide don't exist.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - with self.assertRaises(Http404): - result = utils.get_guide("invalid", "category") - - def test_get_category_guide_category_dont_exist(self): - """Check does this raise Http404 when category don't exist.""" - with patch("pydis_site.apps.guides.utils._get_base_path", return_value=BASE_PATH): - with self.assertRaises(Http404): - result = utils.get_guide("some-guide", "invalid") diff --git a/pydis_site/apps/guides/tests/test_views.py b/pydis_site/apps/guides/tests/test_views.py deleted file mode 100644 index e3945136..00000000 --- a/pydis_site/apps/guides/tests/test_views.py +++ /dev/null @@ -1,104 +0,0 @@ -from unittest.mock import patch - -from django.http import Http404 -from django.test import TestCase -from django_hosts.resolvers import reverse - - -class TestGuidesIndexView(TestCase): - @patch("pydis_site.apps.guides.views.guides.get_guides") - @patch("pydis_site.apps.guides.views.guides.get_categories") - def test_guides_index_return_200(self, get_categories_mock, get_guides_mock): - """Check that guides index return HTTP code 200.""" - get_categories_mock.return_value = {} - get_guides_mock.return_value = {} - - url = reverse('guide:guides') - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - get_guides_mock.assert_called_once() - get_categories_mock.assert_called_once() - - -class TestGuideView(TestCase): - @patch("pydis_site.apps.guides.views.guide.os.path.getmtime") - @patch("pydis_site.apps.guides.views.guide.get_guide") - @patch("pydis_site.apps.guides.views.guide.get_category") - def test_guide_return_code_200(self, get_category_mock, get_guide_mock, get_time_mock): - get_guide_mock.return_value = {"guide": "test", "metadata": {}} - - url = reverse("guide:guide", args=["test-guide"]) - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - get_category_mock.assert_not_called() - get_guide_mock.assert_called_once_with("test-guide", None) - - @patch("pydis_site.apps.guides.views.guide.os.path.getmtime") - @patch("pydis_site.apps.guides.views.guide.get_guide") - @patch("pydis_site.apps.guides.views.guide.get_category") - def test_guide_return_404(self, get_category_mock, get_guide_mock, get_time_mock): - """Check that return code is 404 when invalid guide provided.""" - get_guide_mock.side_effect = Http404("Guide not found.") - - url = reverse("guide:guide", args=["invalid-guide"]) - response = self.client.get(url) - self.assertEqual(response.status_code, 404) - get_guide_mock.assert_called_once_with("invalid-guide", None) - get_category_mock.assert_not_called() - - -class TestCategoryView(TestCase): - @patch("pydis_site.apps.guides.views.category.get_category") - @patch("pydis_site.apps.guides.views.category.get_guides") - def test_valid_category_code_200(self, get_guides_mock, get_category_mock): - """Check that return code is 200 when visiting valid category.""" - get_category_mock.return_value = {"name": "test", "description": "test"} - get_guides_mock.return_value = {} - - url = reverse("guide:category", args=["category"]) - response = self.client.get(url) - - self.assertEqual(response.status_code, 200) - get_guides_mock.assert_called_once_with("category") - get_category_mock.assert_called_once_with("category") - - @patch("pydis_site.apps.guides.views.category.get_category") - @patch("pydis_site.apps.guides.views.category.get_guides") - def test_invalid_category_code_404(self, get_guides_mock, get_category_mock): - """Check that return code is 404 when trying to visit invalid category.""" - get_category_mock.side_effect = Http404("Category not found.") - - url = reverse("guide:category", args=["invalid-category"]) - response = self.client.get(url) - - self.assertEqual(response.status_code, 404) - get_category_mock.assert_called_once_with("invalid-category") - get_guides_mock.assert_not_called() - - -class TestCategoryGuidesView(TestCase): - @patch("pydis_site.apps.guides.views.guide.os.path.getmtime") - @patch("pydis_site.apps.guides.views.guide.get_guide") - @patch("pydis_site.apps.guides.views.guide.get_category") - def test_valid_category_guide_code_200(self, get_category_mock, get_guide_mock, get_time_mock): - """Check that return code is 200 when visiting valid category article.""" - get_guide_mock.return_value = {"guide": "test", "metadata": {}} - - url = reverse("guide:category_guide", args=["category", "test3"]) - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - get_guide_mock.assert_called_once_with("test3", "category") - get_category_mock.assert_called_once_with("category") - - @patch("pydis_site.apps.guides.views.guide.os.path.getmtime") - @patch("pydis_site.apps.guides.views.guide.get_guide") - @patch("pydis_site.apps.guides.views.guide.get_category") - def test_invalid_category_guide_code_404(self, get_category_mock, get_guide_mock, get_time_mock): - """Check that return code is 200 when trying to visit invalid category article.""" - get_guide_mock.side_effect = Http404("Guide not found.") - - url = reverse("guide:category_guide", args=["category", "invalid"]) - response = self.client.get(url) - self.assertEqual(response.status_code, 404) - get_guide_mock.assert_called_once_with("invalid", "category") - get_category_mock.assert_not_called() diff --git a/pydis_site/apps/guides/urls.py b/pydis_site/apps/guides/urls.py deleted file mode 100644 index 69641638..00000000 --- a/pydis_site/apps/guides/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.urls import path - -from . import views - -app_name = "guides" -urlpatterns = [ - path("", views.GuidesView.as_view(), name='guides'), - path("category/<str:category>/", views.CategoryView.as_view(), name='category'), - path("category/<str:category>/<str:guide>/", views.GuideView.as_view(), name='category_guide'), - path("<str:guide>/", views.GuideView.as_view(), name='guide') -] diff --git a/pydis_site/apps/guides/views/__init__.py b/pydis_site/apps/guides/views/__init__.py deleted file mode 100644 index 17a244c1..00000000 --- a/pydis_site/apps/guides/views/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .category import CategoryView -from .guide import GuideView -from .guides import GuidesView - -__all__ = ["GuideView", "GuidesView", "CategoryView"] diff --git a/pydis_site/apps/guides/views/category.py b/pydis_site/apps/guides/views/category.py deleted file mode 100644 index 33e8c97b..00000000 --- a/pydis_site/apps/guides/views/category.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.core.handlers.wsgi import WSGIRequest -from django.http import HttpResponse -from django.shortcuts import render -from django.views import View - -from pydis_site.apps.guides.utils import get_category, get_guides - - -class CategoryView(View): - """Handles guides category page.""" - - def get(self, request: WSGIRequest, category: str) -> HttpResponse: - """Handles page that displays category guides.""" - return render( - request, - "guides/category.html", - {"category_info": get_category(category), "guides": get_guides(category), "category_name": category} - ) diff --git a/pydis_site/apps/guides/views/guides.py b/pydis_site/apps/guides/views/guides.py deleted file mode 100644 index bb8b565e..00000000 --- a/pydis_site/apps/guides/views/guides.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.core.handlers.wsgi import WSGIRequest -from django.http import HttpResponse -from django.shortcuts import render -from django.views import View - -from pydis_site.apps.guides.utils import get_categories, get_guides - - -class GuidesView(View): - """Shows all guides and categories.""" - - def get(self, request: WSGIRequest) -> HttpResponse: - """Shows all guides and categories.""" - return render(request, "guides/guides.html", {"guides": get_guides(), "categories": get_categories()}) diff --git a/pydis_site/apps/home/urls.py b/pydis_site/apps/home/urls.py index 06d62352..e49fd4e0 100644 --- a/pydis_site/apps/home/urls.py +++ b/pydis_site/apps/home/urls.py @@ -39,5 +39,5 @@ urlpatterns = [ path('admin/', admin.site.urls), path('notifications/', include('django_nyt.urls')), - path('guides/', include('pydis_site.apps.guides.urls', namespace='guide')), + path('content/', include('pydis_site.apps.content.urls', namespace='content')), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/pydis_site/settings.py b/pydis_site/settings.py index 6aff0fc1..aaac3bfe 100644 --- a/pydis_site/settings.py +++ b/pydis_site/settings.py @@ -91,7 +91,7 @@ INSTALLED_APPS = [ 'pydis_site.apps.api', 'pydis_site.apps.home', 'pydis_site.apps.staff', - 'pydis_site.apps.guides', + 'pydis_site.apps.content', 'django.contrib.admin', 'django.contrib.auth', diff --git a/pydis_site/static/css/guides/guide.css b/pydis_site/static/css/content/articles.css index fa7a0ba5..fa7a0ba5 100644 --- a/pydis_site/static/css/guides/guide.css +++ b/pydis_site/static/css/content/articles.css diff --git a/pydis_site/templates/guides/guide.html b/pydis_site/templates/content/article.html index 97fc8262..de6cd28d 100644 --- a/pydis_site/templates/guides/guide.html +++ b/pydis_site/templates/content/article.html @@ -3,10 +3,10 @@ {% block title %}{{ metadata.title|first }}{% endblock %} {% block head %} - <meta property="og:title" content="Python Discord - {{ guide.metadata.title|first }}" /> + <meta property="og:title" content="Python Discord - {{ article.metadata.title|first }}" /> <meta property="og:type" content="website" /> - <meta property="og:description" content="{{ guide.metadata.shortdescription|first }}" /> - <link rel="stylesheet" href="{% static "css/guides/guide.css" %}"> + <meta property="og:description" content="{{ article.metadata.shortdescription|first }}" /> + <link rel="stylesheet" href="{% static "css/content/articles.css" %}"> <link rel="stylesheet" href="//cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/default.min.css"> <script src="//cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js"></script> <script>hljs.initHighlightingOnLoad();</script> @@ -19,11 +19,11 @@ <div class="container"> <nav class="breadcrumb is-pulled-left" aria-label="breadcrumbs"> <ul> - <li><a href="/guides">Guides</a></li> + <li><a href="/content">Pages</a></li> {% if category_data.raw_name is not None %} - <li><a href="/guides/category/{{ category_data.raw_name }}">{{ category_data.name }}</a></li> + <li><a href="/content/category/{{ category_data.raw_name }}">{{ category_data.name }}</a></li> {% endif %} - <li class="is-active"><a href="#">{{ guide.metadata.title|first }}</a></li> + <li class="is-active"><a href="#">{{ article.metadata.title|first }}</a></li> </ul> </nav> </div> @@ -32,13 +32,13 @@ <section class="section"> <div class="content"> <div class="container"> - <h1 class="title">{{ guide.metadata.title|first }}</h1> + <h1 class="title">{{ article.metadata.title|first }}</h1> <div class="columns is-variable is-8"> <div class="column is-two-thirds"> - {{ guide.guide|safe }} + {{ article.article|safe }} <p class="has-text-weight-light is-size-7"> <strong>Last modified:</strong> {{ last_modified }}<br/> - <strong>Contributors:</strong> {{ guide.metadata.contributors|join:", " }} + <strong>Contributors:</strong> {{ article.metadata.contributors|join:", " }} </p> </div> <div class="column"> diff --git a/pydis_site/templates/guides/guides.html b/pydis_site/templates/content/articles.html index 0e6f2073..6fea66e5 100644 --- a/pydis_site/templates/guides/guides.html +++ b/pydis_site/templates/content/articles.html @@ -3,7 +3,7 @@ {% block title %}Guides{% endblock %} {% block head %} - <link rel="stylesheet" href="{% static "css/guides/guide.css" %}"> + <link rel="stylesheet" href="{% static "css/content/articles.css" %}"> {% endblock %} {% block content %} @@ -13,7 +13,7 @@ <div class="container"> <nav class="breadcrumb is-pulled-left" aria-label="breadcrumbs"> <ul> - <li class="is-active"><a href="/guides">Guides</a></li> + <li class="is-active"><a href="/content">Pages</a></li> </ul> </nav> </div> @@ -22,13 +22,13 @@ <section class="section"> <div class="container"> <div class="content"> - <h1>Guides</h1> - {% for guide, data in guides.items %} + <h1>Articles</h1> + {% for article, data in content.items %} <div class="box" style="max-width: 800px;"> <span class="icon is-size-4 is-medium"> <i class="fab fa-python is-size-3 is-black has-icon-padding" aria-hidden="true"></i> </span> - <a href="{{ guide }}/"> + <a href="{{ article }}/"> <span class="is-size-4 has-text-weight-bold">{{ data.title.0 }}</span> </a> <p class="is-italic">{{ data.shortdescription.0 }}</p> diff --git a/pydis_site/templates/guides/category.html b/pydis_site/templates/content/category.html index f3a8c2ce..61e20c43 100644 --- a/pydis_site/templates/guides/category.html +++ b/pydis_site/templates/content/category.html @@ -6,7 +6,7 @@ <meta property="og:title" content="Python Discord - {{ category_info.name }}" /> <meta property="og:type" content="website" /> <meta property="og:description" content="{{ category_info.description }}" /> - <link rel="stylesheet" href="{% static "css/guides/guide.css" %}"> + <link rel="stylesheet" href="{% static "css/content/articles.css" %}"> {% endblock %} {% block content %} @@ -16,7 +16,7 @@ <div class="container"> <nav class="breadcrumb is-pulled-left" aria-label="breadcrumbs"> <ul> - <li><a href="/guides">Guides</a></li> + <li><a href="/content">Pages</a></li> <li class="is-active"><a href="#">{{ category_info.name }}</a></li> </ul> </nav> @@ -27,12 +27,12 @@ <div class="container"> <div class="content"> <h1>{{ category_info.name }}</h1> - {% for guide, data in guides.items %} + {% for article, data in content.items %} <div class="box" style="max-width: 800px;"> <span class="icon is-size-4 is-medium"> <i class="fab fa-python is-size-3 is-black has-icon-padding" aria-hidden="true"></i> </span> - <a href="/guides/category/{{ category_name }}/{{ guide }}/"> + <a href="/content/category/{{ category_name }}/{{ article }}/"> <span class="is-size-4 has-text-weight-bold">{{ data.title.0 }}</span> </a> <p class="is-italic">{{ data.shortdescription.0 }}</p> |