diff --git a/app/templates/app/includes/navbar_katalog_materi.html b/app/templates/app/includes/navbar_katalog_materi.html index 67474f5a48493a5d61b0bcf8384e0e099d87590d..9b4fb44c47332de1df4600621b1e7a670f6a5999 100644 --- a/app/templates/app/includes/navbar_katalog_materi.html +++ b/app/templates/app/includes/navbar_katalog_materi.html @@ -13,6 +13,9 @@ <li class="nav-item"> <a class="nav-link" href="/forum">Forum</a> </li> + <li class="nav-item"> + <a class="nav-link" href="/news/all">Berita</a> + </li> {% if not request.user.is_authenticated %} <li class="nav-item"> <a class="nav-link" href="/registrasi">Registrasi</a> diff --git a/news/services.py b/news/services.py index 813b4a5bdac282152aaa74674239135f1754879e..61c1433bae39217959f3cf8d8f13c40808870805 100644 --- a/news/services.py +++ b/news/services.py @@ -29,3 +29,13 @@ class NewsService: def delete_news(news_data): news_data.cover.delete() news_data.delete() + + @staticmethod + def read_news(news_id): + news = News.objects.get(pk=news_id) + return news + + @staticmethod + def read_all_news(): + news = News.objects.order_by('timestamp').reverse() + return news diff --git a/news/static/css/all_news_page.css b/news/static/css/all_news_page.css new file mode 100644 index 0000000000000000000000000000000000000000..97d0591ae37ddef3abe8eaaa65694a8744258385 --- /dev/null +++ b/news/static/css/all_news_page.css @@ -0,0 +1,7 @@ +#card_image { + max-height: 300px; + max-width: 1000px; +} +.image_container{ + text-align: center; +} \ No newline at end of file diff --git a/news/templates/all_news_page.html b/news/templates/all_news_page.html new file mode 100644 index 0000000000000000000000000000000000000000..a38fc2afa4abcee433cbc7c2756dd94ff8911b12 --- /dev/null +++ b/news/templates/all_news_page.html @@ -0,0 +1,22 @@ +{% extends "base_news.html" %} +{% block content %} + <div class="container"> + {% include 'app/includes/navbar_katalog_materi.html' %} + <br> + <h1>Berita Terkini</h1> + {% for news in news_list %} + <br> + <div class="card" style="min-width: 641px;"> + <div class="card-body"> + <div class="image_container"> + <img class="img-responsive center-block" id="card_image" src="{{news.cover.url}}" alt="{{news.id}}"> + </div> + <br><br> + <h5 class="card-title">{{news.title}}</h5> + <p class="card-text">Last Post : {{news.timestamp}}</p> + <a href="/news/{{news.id}}" id="button-{{news.id}}" class="btn btn-primary">Baca</a> + </div> + </div> + {% endfor %} + </div><br><br><br> +{% endblock %} \ No newline at end of file diff --git a/news/templates/base_news.html b/news/templates/base_news.html new file mode 100644 index 0000000000000000000000000000000000000000..a72778e3cf9d5e2f3c8ff9d00be30c6416c5cd7a --- /dev/null +++ b/news/templates/base_news.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load static %} +{% block title %}Digipus News{% endblock %} +{% block header %} + <link rel="stylesheet" type="text/css" href="{% static 'app/css/katalog_materi.css' %}"> + <link href="../../static/app/css/heroic-features.css" rel="stylesheet"> + <link rel="icon" type="image/png" href="{% static 'images/icons/logo.ico' %}" /> + <link rel="stylesheet" type="text/css" href="{% static 'css/styles.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'css/util.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'css/navbar_katalog_materi.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'css/all_news_page.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'fonts/font-awesome-4.7.0/css/font-awesome.min.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'vendor/animate/animate.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'vendor/daterangepicker/daterangepicker.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'vendor/css-hamburgers/hamburgers.min.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'vendor/animsition/css/animsition.min.css' %}"> + <link rel="stylesheet" type="text/css" href="{% static 'vendor/select2/select2.min.css' %}"> +{% endblock header %} +{% block content %} +{% endblock %} \ No newline at end of file diff --git a/news/templates/news_page.html b/news/templates/news_page.html new file mode 100644 index 0000000000000000000000000000000000000000..ff463ca880ea7bab0c5249c7b11d41b8c2316381 --- /dev/null +++ b/news/templates/news_page.html @@ -0,0 +1,16 @@ +{% extends "base_news.html" %} + +{% block content %} + <div class="container"> + {% include 'app/includes/navbar_katalog_materi.html' %} + <div class="text-center"> + <br><br> + <h1>{{news.title}}</h1><br> + <p>{{news.timestamp}}</p><br> + <img class="img-responsive center-block" id="card_image" src= "{{news.cover.url}}" alt="image-{{news.id}}"/> <br><br> + <article> + {{news.content | safe}} + </article><br><br><br><br> + </div> + </div> +{% endblock %} \ No newline at end of file diff --git a/news/tests.py b/news/tests.py index 595532f63a1943dbf19cdf2dd6d626c5fe94f8f1..a8809df495fc33d59b0625bd8f63e9f4c8b61f8f 100644 --- a/news/tests.py +++ b/news/tests.py @@ -79,6 +79,7 @@ class NewsFormTest(TestCase): self.update_form_url = self.form_url+"edit/" self.list_news_url = self.base_url+"list" self.admin_jpg_name = "news_admin.jpg" + self.html_news_form = "news_form.html" self.admin_credential = { "email": "admin@gov.id", "password": str(uuid.uuid4()) @@ -207,14 +208,14 @@ class NewsFormTest(TestCase): def test_form_news_using_news_form_html(self): self.client.login(**self.admin_credential) response = self.client.get(self.form_url) - self.assertTemplateUsed(response, 'news_form.html') + self.assertTemplateUsed(response, self.html_news_form) self.client.logout() def test_update_form_news_using_news_form_html(self): self.client.login(**self.admin_credential) id_news4 = str(self.news4.id) response = self.client.get(self.update_form_url+id_news4) - self.assertTemplateUsed(response, 'news_form.html') + self.assertTemplateUsed(response, self.html_news_form) self.client.logout() def test_update_form_news_but_news_not_exist(self): @@ -281,4 +282,98 @@ class NewsFormTest(TestCase): response = self.client.get(self.list_news_url) self.assertTemplateUsed(response, 'news_list.html') self.client.logout() - \ No newline at end of file + +@override_settings(MEDIA_ROOT = MOCK_MEDIA_ROOT) +class NewsPageTest(TestCase): + def setUp(self): + self.client = Client() + self.root_url = "/" + self.news_url = self.root_url+"news/" + self.all_news_url = self.news_url+"all" + self.html_news_form = "news_form.html" + self.admin_credential = { + "email": "admin@gov.id", + "password": str(uuid.uuid4()) + } + self.contributor_credential = { + "email": "kontributor@gov.id", + "password": str(uuid.uuid4()) + } + self.admin = get_user_model().objects.create_user( + **self.admin_credential, name="Admin", is_admin=True) + self.contributor = get_user_model().objects.create_user( + **self.contributor_credential, name="Kontributor", is_contributor=True + ) + self.test_file_jpg6 = SimpleUploadedFile("foto6.jpg", b"file_content") + self.test_file_jpg7 = SimpleUploadedFile("foto7.jpg", b"file_content") + self.news6 = News.objects.create( + title = 'title6', + content = 'content news6', + cover = self.test_file_jpg6 + ) + self.news7 = News.objects.create( + title = 'title7', + content = 'content news7', + cover = self.test_file_jpg7 + ) + self.news6.save() + self.news7.save() + + @classmethod + def tearDownClass(cls): + shutil.rmtree(MOCK_MEDIA_ROOT, ignore_errors=True) + super().tearDownClass() + + def test_news_page_can_be_accessed_by_admin(self): + self.client.login(**self.admin_credential) + response = self.client.get(self.news_url+str(self.news6.id)) + self.assertEqual(response.status_code, 200) + self.client.logout() + + def test_news_page_can_be_accessed_by_contributor(self): + self.client.login(**self.contributor_credential) + response = self.client.get(self.news_url+str(self.news6.id)) + self.assertEqual(response.status_code, 200) + self.client.logout() + + def test_news_page_can_be_accessed_by_anonymous(self): + response = self.client.get(self.news_url+str(self.news6.id)) + self.assertEqual(response.status_code, 200) + + def test_news_page_used_news_page_html(self): + response = self.client.get(self.news_url+str(self.news6.id)) + self.assertTemplateUsed(response,'news_page.html') + self.assertTemplateNotUsed(response, self.html_news_form) + + def test_all_news_page_can_be_accessed_by_admin(self): + self.client.login(**self.admin_credential) + response = self.client.get(self.all_news_url) + self.assertEqual(response.status_code, 200) + self.client.logout() + + def test_all_news_page_can_be_accessed_by_contributor(self): + self.client.login(**self.contributor_credential) + response = self.client.get(self.all_news_url) + self.assertEqual(response.status_code, 200) + self.client.logout() + + def test_all_news_page_can_be_accessed_by_anonymous(self): + response = self.client.get(self.all_news_url) + self.assertEqual(response.status_code, 200) + + def test_all_news_page_used_all_news_page_html(self): + response = self.client.get(self.all_news_url) + self.assertTemplateUsed(response,'all_news_page.html') + self.assertTemplateNotUsed(response,'news_page.html') + + def test_all_news_page_contain_string_data_in_object_news(self): + response = self.client.get(self.all_news_url) + self.assertContains(response, self.news6.title+"</h5>") + self.assertContains(response, str(self.news7.title)+"</h5>") + + def test_news_page_contain_string_data_in_object_news(self): + response = self.client.get(self.news_url+str(self.news6.id)) + self.assertContains(response, self.news6.title+"</h1>") + self.assertNotContains(response, self.news7.title+"</h1>") + self.assertContains(response, self.news6.content) + self.assertNotContains(response, self.news7.content) diff --git a/news/urls.py b/news/urls.py index 568d2060336a7583d0fa8ad63ae48e5256d5e4ca..cf803fc50010b1d4b4164fa976363162b4c33536 100644 --- a/news/urls.py +++ b/news/urls.py @@ -28,4 +28,14 @@ urlpatterns = [ views.show_news_list, name = "show_news_list" ), + path( + 'news/<int:id_news>', + views.show_news_page, + name = 'show_news_page' + ), + path( + 'news/all', + views.show_all_news, + name = 'show_all_news' + ), ] \ No newline at end of file diff --git a/news/views.py b/news/views.py index f16a1dec553cd9608d3ff7b2cd9a21f39218a7d5..1950992e4724bd6fedf7955719d67f1f666caadc 100644 --- a/news/views.py +++ b/news/views.py @@ -10,6 +10,8 @@ from .services import NewsService html_news_form = "news_form.html" html_news_list = "news_list.html" +html_news_page = "news_page.html" +html_all_news_page = "all_news_page.html" login_url = "/login/" root_url = "/" news_list_url = "/administration/news/list" @@ -81,6 +83,20 @@ def show_news_list(request): return redirect(root_url) response = { - "news_list" : News.objects.all() + "news_list" : NewsService.read_all_news() } return render(request, html_news_list, response) + +def show_news_page(request, id_news): + news = NewsService.read_news(id_news) + response = { + "news": news + } + return render(request, html_news_page, response) + +def show_all_news(request): + news = NewsService.read_all_news() + response = { + "news_list": news + } + return render(request, html_all_news_page, response) \ No newline at end of file