Fakultas Ilmu Komputer UI
Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
PMPL
Class Project
DIGIPUS
Commits
9edc8814
Commit
9edc8814
authored
Oct 08, 2020
by
Kevin Raikhan Zain
Browse files
Merge branch '1706075041-43' into 'master'
[
#43
] Add rating in detail materi See merge request
!10
parents
34c193ee
8477d1cf
Pipeline
#57816
passed with stages
in 8 minutes and 30 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
app/templates/app/detail_materi.html
View file @
9edc8814
...
...
@@ -57,7 +57,7 @@
</div>
</div>
</div>
</li>
</li>
{% endif %}
{% endif %}
...
...
@@ -170,11 +170,39 @@
{% else %}
<button
id=
"thumb"
class=
"btn btn-link btn-book shadow-sm p-2 mr-2 bg-white rounded"
><i
id=
"thumbIcon"
aria-hidden=
"true"
class=
"far fa-thumbs-up"
></i>
Sukai
</button>
{% endif %}
{% if user.is_authenticated %}
<div
class=
"dropdown"
>
<button
class=
"btn dropdown-toggle btn-book shadow-sm p-2 mr-2 bg-white rounded align-self-center"
type=
"button"
data-toggle=
"dropdown"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<em
id=
"button-rating-star-icon"
class=
"align-self-center far fa-star"
></em>
<span
id=
"button-rating-text"
>
Beri Rating
</span>
</button>
<div
id=
"star-dropdown"
class=
"dropdown-menu"
aria-labelledby=
"dropdownMenuButton"
>
<div
class=
"text-center btn-book"
>
<em
onclick=
"postAddRating(1)"
id=
"star-1"
class=
"far fa-star fa-lg"
></em>
<em
onclick=
"postAddRating(2)"
id=
"star-2"
class=
"far fa-star fa-lg"
></em>
<em
onclick=
"postAddRating(3)"
id=
"star-3"
class=
"far fa-star fa-lg"
></em>
<em
onclick=
"postAddRating(4)"
id=
"star-4"
class=
"far fa-star fa-lg"
></em>
<em
onclick=
"postAddRating(5)"
id=
"star-5"
class=
"far fa-star fa-lg"
></em>
</div>
</div>
</div>
{% else %}
<button
class=
"btn dropdown-toggle btn-book shadow-sm p-2 mr-2 bg-white rounded align-self-center"
type=
"button"
id=
"dropdownMenuButton"
aria-haspopup=
"true"
aria-expanded=
"false"
data-toggle=
"modal"
data-target=
"#notLoggedInModal"
>
<em
class=
"align-self-center far fa-star"
></em>
Beri Rating
</button>
{% endif %}
</div>
</div>
</div>
<div
class=
"row menu-wrapper mr-4 ml-4 p-3"
>
<nav
class=
"navbar navbar-expand-sm border-top border-bottom p-0 mt-3 mb-3"
>
<nav
class=
"navbar navbar-expand-sm border-top border-bottom p-0 mt-3 mb-3"
>
<ul
class=
"navbar-nav"
>
<li
class=
"nav-item"
>
<a
class=
"nav-link"
href=
"#deskripsi"
>
Deskripsi
</a>
...
...
@@ -199,8 +227,8 @@
{% csrf_token %}
<h1>
Komentar
</h1>
<div
class=
"form-group"
>
<textarea
placeholder=
"Beri komentar..."
class=
"form-control"
id=
"exampleFormControlTextarea1"
<textarea
placeholder=
"Beri komentar..."
class=
"form-control"
id=
"exampleFormControlTextarea1"
rows=
"3"
name=
"comment"
required
></textarea>
<button
type=
"submit"
class=
"btn btn-link btn-book shadow-sm p-2 mt-2 bg-white rounded"
>
Kirim
</button>
...
...
@@ -246,12 +274,89 @@
</div>
</div>
</footer>
<!-- Modal -->
<div
class=
"modal fade"
id=
"notLoggedInModal"
tabindex=
"-1"
role=
"dialog"
aria-labelledby=
"notLoggedInModalLabel"
aria-hidden=
"true"
>
<div
class=
"modal-dialog"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<h5
class=
"modal-title"
id=
"notLoggedInModalLabel"
>
Belum Login
</h5>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"Close"
>
<span
aria-hidden=
"true"
>
×
</span>
</button>
</div>
<div
class=
"modal-body"
>
Login untuk memberikan rating
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
class=
"btn btn-secondary"
data-dismiss=
"modal"
>
Batal
</button>
<button
type=
"button"
class=
"btn btn-primary"
onclick=
"window.location.href = '/login';"
>
Login
</button>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block extra_scripts %}
<script
src=
"https://kit.fontawesome.com/bc2cedd6b2.js"
crossorigin=
"anonymous"
></script>
<script
type=
"text/javascript"
>
// using jQuery
var
csrftoken
=
jQuery
(
"
[name=csrfmiddlewaretoken]
"
).
val
();
let
currentRating
=
{{
materi_rating_score
}};
fillRatingStar
(
currentRating
)
function
changeButtonIntoRated
()
{
$
(
'
#button-rating-star-icon
'
).
addClass
(
'
fas
'
);
$
(
'
#button-rating-star-icon
'
).
removeClass
(
'
far
'
);
$
(
'
#button-rating-text
'
).
text
(
"
Rating Anda
"
)
}
if
(
currentRating
>
0
)
{
changeButtonIntoRated
()
}
$
(
"
#star-dropdown
"
).
click
(
function
(
e
)
{
e
.
stopPropagation
();
});
function
clearRatingStar
()
{
for
(
let
i
=
1
;
i
<=
5
;
i
++
)
{
$
(
'
#star-
'
+
i
).
addClass
(
'
far
'
);
$
(
'
#star-
'
+
i
).
removeClass
(
'
fas
'
);
}
}
function
fillRatingStar
(
ratingScore
)
{
for
(
let
i
=
1
;
i
<=
ratingScore
;
i
++
)
{
$
(
'
#star-
'
+
i
).
addClass
(
'
fas
'
);
$
(
'
#star-
'
+
i
).
removeClass
(
'
far
'
);
}
}
function
makeHoverStar
(
starAmount
)
{
function
hoverStar
()
{
clearRatingStar
()
fillRatingStar
(
starAmount
)
}
return
hoverStar
}
function
makeUnHoverStar
(
starAmount
)
{
function
unHoverStar
()
{
clearRatingStar
()
fillRatingStar
(
currentRating
)
}
return
unHoverStar
}
$
(
'
#star-1
'
).
hover
(
makeHoverStar
(
1
),
makeUnHoverStar
(
1
));
$
(
'
#star-2
'
).
hover
(
makeHoverStar
(
2
),
makeUnHoverStar
(
2
));
$
(
'
#star-3
'
).
hover
(
makeHoverStar
(
3
),
makeUnHoverStar
(
3
));
$
(
'
#star-4
'
).
hover
(
makeHoverStar
(
4
),
makeUnHoverStar
(
4
));
$
(
'
#star-5
'
).
hover
(
makeHoverStar
(
5
),
makeUnHoverStar
(
5
));
</script>
<script>
function
csrfSafeMethod
(
method
)
{
...
...
@@ -281,6 +386,32 @@
});
});
function
postAddRating
(
rating_score
)
{
$
.
ajaxSetup
({
beforeSend
:
function
(
xhr
,
settings
)
{
if
(
!
csrfSafeMethod
(
settings
.
type
)
&&
!
this
.
crossDomain
)
{
xhr
.
setRequestHeader
(
"
X-CSRFToken
"
,
csrftoken
);
}
}
});
$
.
ajax
({
type
:
'
POST
'
,
url
:
"
{% url 'rate-materi' %}
"
,
data
:
{
'
materi_id
'
:
"
{{ materi_data.id }}
"
,
'
rating_score
'
:
rating_score
},
success
:
function
(
data
)
{
const
response
=
JSON
.
parse
(
data
)
currentRating
=
response
.
rating_score
makeUnHoverStar
(
currentRating
)()
changeButtonIntoRated
()
},
dataType
:
'
html
'
});
}
function
LikePost
(
data
,
jqXHR
)
{
var
data
=
$
.
parseJSON
(
data
)
...
...
app/tests.py
View file @
9edc8814
...
...
@@ -6,13 +6,14 @@ from django.contrib.auth import get_user_model
from
django.core.exceptions
import
PermissionDenied
,
ValidationError
from
django.core.files.uploadedfile
import
SimpleUploadedFile
from
django.core.management
import
call_command
from
django.test
import
Client
,
RequestFactory
,
TestCase
from
django.db
import
IntegrityError
from
django.test
import
Client
,
TestCase
from
django.urls
import
resolve
from
administration.models
import
VerificationSetting
,
VerificationReport
from
administration.utils
import
id_generator
from
app.views
import
UploadMateriView
from
app.forms
import
SuntingProfilForm
from
app.views
import
UploadMateriView
,
add_rating_materi
from
authentication.models
import
User
from
.models
import
Category
,
Comment
,
Materi
,
Like
,
Rating
from
.views
import
(
DaftarKatalog
,
DashboardKontributorView
,
DetailMateri
,
...
...
@@ -218,7 +219,7 @@ class PostsViewTest(TestCase):
def
test_url_resolves_to_posts_view
(
self
):
found
=
resolve
(
self
.
url
)
self
.
assertEqual
(
found
.
func
.
__name__
,
PostsView
.
as_view
().
__name__
)
def
test_returns_200_on_authenticated_access
(
self
):
response
=
self
.
_request_as_user
()
self
.
assertEqual
(
response
.
status_code
,
200
)
...
...
@@ -254,14 +255,14 @@ class PostsViewTest(TestCase):
}
self
.
assertRegex
(
str
(
response
.
content
),
str
(
response
.
content
),
rf
'.*(<div id="post-
{
posts
[
2
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
2
]
}
-comment-
{
comments
[
2
][
0
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
2
]
}
-comment-
{
comments
[
2
][
1
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
2
]
}
-comment-
{
comments
[
2
][
2
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
2
]
}
-comment-
{
comments
[
2
][
0
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
2
]
}
-comment-
{
comments
[
2
][
1
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
2
]
}
-comment-
{
comments
[
2
][
2
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
1
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
0
]
}
">)'
+
\
rf
'.*(<div id="post-
{
posts
[
0
]
}
-comment-
{
comments
[
0
][
0
]
}
">)'
rf
'.*(<div id="post-
{
posts
[
0
]
}
-comment-
{
comments
[
0
][
0
]
}
">)'
)
...
...
@@ -345,6 +346,7 @@ class UploadPageTest(TestCase):
# Negative tests
self
.
assertNotContains
(
response
,
"anything"
)
class
DashboardKontributorViewTest
(
TestCase
):
def
setUp
(
self
):
self
.
client
=
Client
()
...
...
@@ -406,6 +408,7 @@ class DashboardKontributorViewTest(TestCase):
response
=
self
.
client
.
get
(
self
.
url
)
self
.
assertEqual
(
response
.
status_code
,
403
)
class
ProfilAdminTest
(
TestCase
):
def
setUp
(
self
):
self
.
client
=
Client
()
...
...
@@ -444,6 +447,7 @@ class ProfilAdminTest(TestCase):
# Logout
self
.
client
.
logout
()
class
ProfilKontributorTest
(
TestCase
):
def
setUp
(
self
):
self
.
client
=
Client
()
...
...
@@ -749,7 +753,7 @@ class LikeMateriTest(TestCase):
def
test_like_materi
(
self
):
# Verify that materi doesn't have any like to start with
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
0
)
# Like a materi
...
...
@@ -761,12 +765,12 @@ class LikeMateriTest(TestCase):
'session_id'
:
session_id
}
ajax_response
=
Client
().
post
(
self
.
url_like
,
payload
)
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
1
)
def
test_unlike_materi
(
self
):
# Verify that materi doesn't have any like to start with
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
0
)
# Like a materi
...
...
@@ -778,7 +782,7 @@ class LikeMateriTest(TestCase):
'session_id'
:
session_id
}
ajax_response
=
Client
().
post
(
self
.
url_like
,
payload
)
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
1
)
# Unlike a materi
...
...
@@ -790,12 +794,12 @@ class LikeMateriTest(TestCase):
'session_id'
:
session_id
}
ajax_response
=
Client
().
post
(
self
.
url_like
,
payload
)
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
0
)
def
test_2_client_like_materi
(
self
):
# Verify that materi doesn't have any like to start with
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
0
)
# Client 1 like a materi
...
...
@@ -807,7 +811,7 @@ class LikeMateriTest(TestCase):
'session_id'
:
session_id
}
ajax_response
=
Client
().
post
(
self
.
url_like
,
payload
)
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
1
)
# Client 2 like a materi
...
...
@@ -819,12 +823,12 @@ class LikeMateriTest(TestCase):
'session_id'
:
session_id
}
ajax_response
=
Client
().
post
(
self
.
url_like
,
payload
)
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
2
)
def
test_incomplete_like_parameter
(
self
):
# Verify that materi doesn't have any like to start with
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
0
)
# missing session id
...
...
@@ -835,7 +839,7 @@ class LikeMateriTest(TestCase):
}
ajax_response
=
Client
().
post
(
self
.
url_like
,
payload
)
ajax_response
=
json
.
loads
(
ajax_response
.
content
)
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
0
)
self
.
assertEqual
(
ajax_response
.
get
(
"success"
,
None
),
False
)
...
...
@@ -847,7 +851,7 @@ class LikeMateriTest(TestCase):
}
ajax_response
=
Client
().
post
(
self
.
url_like
,
payload
)
ajax_response
=
json
.
loads
(
ajax_response
.
content
)
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
num_of_likes
=
Like
.
objects
.
filter
(
materi
=
self
.
materi1
).
count
()
self
.
assertEqual
(
num_of_likes
,
0
)
self
.
assertEqual
(
ajax_response
.
get
(
"success"
,
None
),
False
)
...
...
@@ -893,6 +897,7 @@ class ViewMateriStatissticsTest(TestCase):
num_of_views
=
self
.
materi1
.
baca
.
all
().
count
()
self
.
assertEqual
(
num_of_views
,
2
)
class
DownloadMateriStatissticsTest
(
TestCase
):
def
setUp
(
self
):
self
.
contributor_credential
=
{
...
...
@@ -934,6 +939,7 @@ class DownloadMateriStatissticsTest(TestCase):
num_of_downloads
=
self
.
materi1
.
unduh
.
all
().
count
()
self
.
assertEqual
(
num_of_downloads
,
2
)
class
RevisiMateriTest
(
TestCase
):
def
setUp
(
self
):
self
.
client
=
Client
()
...
...
@@ -1040,7 +1046,6 @@ class RemoveDummyCommandTest(TestCase):
class
RatingMateriTest
(
TestCase
):
def
setUp
(
self
):
self
.
url
=
'/administration/'
self
.
contributor_credential
=
{
"email"
:
"kontributor@gov.id"
,
"password"
:
id_generator
()
...
...
@@ -1074,6 +1079,8 @@ class RatingMateriTest(TestCase):
status
=
"APPROVE"
,
cover
=
self
.
cover
,
content
=
self
.
content
).
save
()
self
.
materi1
=
Materi
.
objects
.
all
()[
0
]
self
.
materi2
=
Materi
.
objects
.
all
()[
1
]
self
.
url_rate
=
'/materi/rate/'
self
.
url_materi
=
'/materi/{}/'
.
format
(
self
.
materi1
.
id
)
def
test_rating_model_can_be_created_with_proper_parameter
(
self
):
Rating
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
,
score
=
5
).
save
()
...
...
@@ -1131,6 +1138,105 @@ class RatingMateriTest(TestCase):
with
self
.
assertRaises
(
TypeError
):
Rating
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
).
save
()
def
test_rating_materi_url_use_add_rating_materi_function
(
self
):
found
=
resolve
(
self
.
url_rate
)
self
.
assertEqual
(
found
.
func
,
add_rating_materi
)
def
test_rating_materi_get_method_should_return_403_forbidden
(
self
):
response
=
self
.
client
.
get
(
self
.
url_rate
)
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
response_json
.
get
(
"success"
,
None
),
False
)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"Forbidden"
)
self
.
assertEqual
(
response
.
status_code
,
403
)
def
test_rating_materi_post_not_authenticated_should_return_403_forbidden
(
self
):
response
=
self
.
client
.
post
(
self
.
url_rate
,
{
'materi_id'
:
1
,
'rating_score'
:
5
})
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
response_json
.
get
(
"success"
,
None
),
False
)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"Forbidden"
)
self
.
assertEqual
(
response
.
status_code
,
403
)
def
test_rating_materi_not_authenticated_post_wrong_param_should_return_403_forbidden
(
self
):
for
data
in
[{},
{
'materi_id'
:
1
},
{
'rating_score'
:
1
},
{
'rating_score'
:
'STRING'
,
'materi_id'
:
'STRING'
}]:
response
=
self
.
client
.
post
(
self
.
url_rate
,
data
)
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
response_json
.
get
(
"success"
,
None
),
False
)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"Forbidden"
)
self
.
assertEqual
(
response
.
status_code
,
403
)
def
test_rating_materi_authenticated_post_missing_param
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
for
data
in
[{
'rating_score'
:
1
},
{
'materi_id'
:
1
},
{}]:
response
=
self
.
client
.
post
(
self
.
url_rate
,
data
)
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
response_json
.
get
(
"success"
,
None
),
False
)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"Missing param"
)
self
.
assertEqual
(
response
.
status_code
,
422
)
def
test_rating_materi_authenticated_materi_id_doesnt_exist_should_return_422
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
post
(
self
.
url_rate
,
{
'materi_id'
:
123456
,
'rating_score'
:
5
})
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
response_json
.
get
(
"success"
,
None
),
False
)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"Materi does not exist"
)
self
.
assertEqual
(
response
.
status_code
,
422
)
def
test_rating_materi_authenticated_param_wrong_data_type_should_return_422
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
post
(
self
.
url_rate
,
{
'materi_id'
:
"STRING"
,
'rating_score'
:
5
})
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
response_json
.
get
(
"success"
,
None
),
False
)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"materi_id must be an integer"
)
self
.
assertEqual
(
response
.
status_code
,
422
)
response
=
self
.
client
.
post
(
self
.
url_rate
,
{
'materi_id'
:
1
,
'rating_score'
:
"STRING"
})
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
response_json
.
get
(
"success"
,
None
),
False
)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"rating_score must be an integer"
)
self
.
assertEqual
(
response
.
status_code
,
422
)
def
test_rating_score_should_be_between_1_and_5
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
for
i
in
range
(
1
,
6
):
Rating
.
objects
.
all
().
delete
()
response
=
self
.
client
.
post
(
self
.
url_rate
,
{
'materi_id'
:
self
.
materi1
.
id
,
'rating_score'
:
i
})
response_json
=
json
.
loads
(
response
.
content
)
# self.assertEqual(response_json.get("success", None), True)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"Rating successfully created"
)
self
.
assertEqual
(
response
.
status_code
,
201
)
for
i
in
[
-
100
,
-
7
,
-
6
,
-
1
,
0
,
6
,
7
,
100
]:
Rating
.
objects
.
all
().
delete
()
response
=
self
.
client
.
post
(
self
.
url_rate
,
{
'materi_id'
:
self
.
materi1
.
id
,
'rating_score'
:
i
})
response_json
=
json
.
loads
(
response
.
content
)
# self.assertEqual(response_json.get("success", None), False)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"Rating must be an integer from 1 to 5"
)
self
.
assertEqual
(
response
.
status_code
,
422
)
def
test_user_should_not_able_to_rate_materi_twice
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
Rating
.
objects
.
all
().
delete
()
self
.
client
.
post
(
self
.
url_rate
,
{
'materi_id'
:
self
.
materi1
.
id
,
'rating_score'
:
1
})
response
=
self
.
client
.
post
(
self
.
url_rate
,
{
'materi_id'
:
self
.
materi1
.
id
,
'rating_score'
:
2
})
response_json
=
json
.
loads
(
response
.
content
)
# self.assertEqual(response_json.get("success", None), False)
self
.
assertEqual
(
response_json
.
get
(
"msg"
,
None
),
"Rating already exist"
)
self
.
assertEqual
(
response
.
status_code
,
409
)
def
test_user_authenticated_visit_unrated_should_get_0_materi_rating_score_context
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
get
(
self
.
url_materi
)
self
.
assertEqual
(
0
,
response
.
context
.
get
(
'materi_rating_score'
))
def
test_user_not_authenticated_visit_unrated_should_get_0_materi_rating_score_context
(
self
):
response
=
self
.
client
.
get
(
self
.
url_materi
)
self
.
assertEqual
(
0
,
response
.
context
.
get
(
'materi_rating_score'
))
def
test_user_authenticated_visit_rated_should_get_correct_materi_rating_score_context
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
Rating
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
,
score
=
1
).
save
()
response
=
self
.
client
.
get
(
self
.
url_materi
)
self
.
assertEqual
(
1
,
response
.
context
.
get
(
'materi_rating_score'
))
class
fileManagementUtilTest
(
TestCase
):
def
setUp
(
self
):
...
...
app/urls.py
View file @
9edc8814
...
...
@@ -28,4 +28,5 @@ urlpatterns = [
path
(
"sunting-admin/"
,
SuntingProfilAdminView
.
as_view
(),
name
=
"sunting-admin"
),
path
(
"req-materi/"
,
ReqMateriView
.
as_view
(),
name
=
"req-materi"
),
path
(
"post-req-materi/"
,
views
.
post_req_materi
,
name
=
"post-req-materi"
),
path
(
"materi/rate/"
,
views
.
add_rating_materi
,
name
=
"rate-materi"
),
]
app/views.py
View file @
9edc8814
...
...
@@ -2,23 +2,20 @@ import mimetypes
import
os
from
django.conf
import
settings
from
django.contrib.auth.models
import
AnonymousUser
from
django.contrib
import
messages
from
django.co
re
import
serializ
er
s
from
django.co
ntrib.auth.models
import
AnonymousUs
er
from
django.core.exceptions
import
PermissionDenied
,
ValidationError
from
django.core.paginator
import
Paginator
,
EmptyPage
,
PageNotAnInteger
from
django.core.paginator
import
Paginator
from
django.db.models
import
Q
,
Count
from
django.http
import
(
Http404
,
HttpResponse
,
HttpResponseRedirect
,
JsonResponse
)
from
django.shortcuts
import
get_object_or_404
,
redirect
,
render
from
django.shortcuts
import
get_object_or_404
from
django.template
import
loader
from
django.urls
import
reverse
from
django.views.generic
import
TemplateView
,
ListView
from
.models
import
Category
,
Comment
,
Materi
from
django.core.paginator
import
Paginator
,
EmptyPage
,
PageNotAnInteger
from
django.views.generic
import
TemplateView
from
administration.models
import
VerificationReport
from
app.forms
import
SuntingProfilForm
,
UploadMateriForm
from
app.models
import
Category
,
Comment
,
Materi
,
Like
,
ViewStatistics
,
DownloadStatistics
,
ReqMaterial
from
app.models
import
Category
,
Comment
,
Materi
,
Like
,
ViewStatistics
,
DownloadStatistics
,
ReqMaterial
,
Rating
from
app.utils.fileManagementUtil
import
get_random_filename
,
remove_image_exifdata
from
authentication.models
import
User
import
django
...
...
@@ -67,10 +64,10 @@ class DaftarKatalog(TemplateView):
elif
(
getSort
==
"terbaru"
):
lstMateri
=
lstMateri
.
order_by
(
'-date_created'
)
elif
(
getSort
==
"terlama"
):
lstMateri
=
lstMateri
.
order_by
(
'date_created'
)
lstMateri
=
lstMateri
.
order_by
(
'date_created'
)
elif
(
getSort
==
"terpopuler"
):
lstMateri
=
lstMateri
.
annotate
(
count
=
Count
(
'like__id'
)).
order_by
(
'-count'
)
context
[
"materi_list"
]
=
lstMateri
paginator
=
Paginator
(
context
[
"materi_list"
],
15
)
page_number
=
request
.
GET
.
get
(
'page'
)
...
...
@@ -94,6 +91,13 @@ class DetailMateri(TemplateView):
context
[
"report"
]
=
VerificationReport
.
objects
.
filter
(
materi
=
materi
)
context
[
"has_liked"
]
=
Like
.
objects
.
filter
(
materi
=
materi
,
session_id
=
self
.
request
.
session
.
session_key
).
exists
()
context
[
'materi_rating_score'
]
=
0
if
self
.
request
.
user
.
is_authenticated
:
materi_rating
=
Rating
.
objects
.
filter
(
materi
=
materi
,
user
=
self
.
request
.
user
).
first
()
if
materi_rating
is
not
None
:
context
[
'materi_rating_score'
]
=
materi_rating
.
score
return
context
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
...
...
@@ -160,6 +164,41 @@ def delete_comment(request, pk_materi, pk_comment):
return
HttpResponseRedirect
(
url
)
def
add_rating_materi
(
request
):
if
request
.
method
==
'POST'
and
request
.
user
.
is_authenticated
:
materi_id
=
request
.
POST
.
get
(
'materi_id'
,
None
)
rating_score
=
request
.
POST
.
get
(
'rating_score'
,
None
)
if
materi_id
is
None
or
rating_score
is
None
:
return
JsonResponse
({
"success"
:
False
,
"msg"
:
"Missing param"
},
status
=
422
)
try
:
rating_score
=
int
(
rating_score
)
except
ValueError
:
return
JsonResponse
({
"success"
:
False
,
"msg"
:
"rating_score must be an integer"
},
status
=
422
)
try
:
materi_id
=
int
(
materi_id
)
except
ValueError
:
return
JsonResponse
({
"success"
:
False
,
"msg"
:
"materi_id must be an integer"
},
status
=
422
)
if
rating_score
not
in
range
(
1
,
6
):
return
JsonResponse
({
"success"
:
False
,
"msg"
:
"Rating must be an integer from 1 to 5"
},
status
=
422
)
materi
=
Materi
.
objects
.
filter
(
pk
=
materi_id
).
first
()
if
materi
is
None
:
return
JsonResponse
({
"success"
:
False
,
"msg"
:
"Materi does not exist"
},
status
=
422
)
if
Rating
.
objects
.
filter
(
materi
=
materi
,
user
=
request
.
user
).
first
()
is
not
None
:
return
JsonResponse
({
"success"
:
False
,
"msg"
:
"Rating already exist"
},
status
=
409
)
Rating
(
materi
=
materi
,
user
=
request
.
user
,
score
=
rating_score
).
save
()
return
JsonResponse
({
"success"
:
True
,
"msg"
:
"Rating successfully created"
,
"rating_score"
:
rating_score
},
status
=
201
)
return
JsonResponse
({
"success"
:
False
,
"msg"
:
"Forbidden"
},
status
=
403
)
def
download_materi
(
request
,
pk
):
materi
=
get_object_or_404
(
Materi
,
pk
=
pk
)
path
=
materi
.
content
.
path
...
...
@@ -238,7 +277,7 @@ class UploadMateriView(TemplateView):
context
=
self
.
get_context_data
(
**
kwargs
)
context
[
"form"
]
=
UploadMateriForm
return
self
.
render_to_response
(
context
)
def
validate_file_extension
(
self
,
value
):
ext
=
os
.
path
.
splitext
(
value
.
name
)[
1
]
# [0] returns path+filename
valid_extensions
=
[
'.pdf'
,
'.doc'
,
'.docx'
,
'.jpg'
,
'.png'
,
'.xlsx'
,
'.xls'
,
'.mp4'
,
'.mp3'
]
...
...
@@ -549,7 +588,7 @@ class PostsView(TemplateView):
class
RevisiMateriView
(
TemplateView
):
template_name
=
"revisi.html"
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_contributor
:
raise
PermissionDenied
(
request
)