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