Skip to content

Commit

Permalink
Merge pull request #111 from paOmer/like
Browse files Browse the repository at this point in the history
🚀  Like Button
  • Loading branch information
Yarboa authored May 12, 2022
2 parents 453913c + c7375d2 commit abe6286
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 4 deletions.
9 changes: 6 additions & 3 deletions feed/templates/feed/post.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@ <h5><a class="text-decoration-none text-dark" href="{% url 'post-detail' post.id

<!-- Buttons -->
<div class="d-flex justify-content-around text-center border-top border-bottom mb-4">
<button type="button" class="btn btn-link btn-lg">
<img src="{% static 'jobseeker/icons/like.svg' %}" class="me-2" /> Like
</button>
<form action="{% url 'like-post' post.id %}" method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-link btn-lg">
<img src="{% static 'jobseeker/icons/like.svg' %}" class="me-2" /> Like
</button>
</form>
<form action="{% url 'comment-create' post.id %}" method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-link btn-lg">
Expand Down
86 changes: 86 additions & 0 deletions feed/tests/test_feed_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from feed.models import Post
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from django.contrib.messages import get_messages


USERNAME1 = 'username1'
Expand All @@ -13,6 +14,8 @@
POST_DETAIL_URL = '/post/'
FEED_URL = '/'
NEW_POST_URL = '/post/new/'
LOGIN_URL = '/login/'
LIKE_WARNING_MESSAGE = 'You must login in order to like a post'
REDIRECT_URL_STATUS = 302
PAGE_NOT_FOUND = 404

Expand All @@ -21,20 +24,46 @@ def post_delete_url(post_id):
return f"/post/{post_id}/delete/"


def post_like_url(post_id):
return f"/post/{post_id}/like/"


@pytest.fixture
def users(db):
user1 = User.objects.create_user(USERNAME1, password=USER_PASS)
user2 = User.objects.create_user(USERNAME2, password=USER_PASS)
return [user1, user2]


@pytest.fixture
def logged_in_client(client, users):
client.force_login(users[0])
return client


@pytest.fixture
def post(db, users):
post = Post.posts.create(title=POST_TITLE, content=POST_CONTENT, author=users[0])
post.save()
return post


@pytest.fixture
def liked_post(post, users):
post.likes.add(users[0])
return post


@pytest.fixture
def post_init_like_count(post):
return post.likes.count()


@pytest.fixture
def liked_post_init_like_count(liked_post):
return liked_post.likes.count()


@pytest.mark.django_db
class TestPostDetailView:
def test_detail_view_page_entrypoint(self, post, client):
Expand Down Expand Up @@ -131,3 +160,60 @@ def test_redirect_after_successful_post_creation(self, users, client):
# The new post ID should be as the amount of posts exists
new_post_id = Post.posts.count()
assert response.url == POST_DETAIL_URL + str(new_post_id) + '/'


class TestLikeForNonLoggedUser:
def test_like_view_return_warning_when_logged_out(self, post, client):
# Testing that when logged out, if trying to access the like url
# a warning message returns
post_to_like = post
response = client.get(post_like_url(post_to_like.id))
messages = [m.message for m in get_messages(response.wsgi_request)]
assert len(messages) == 1
assert messages[0] == LIKE_WARNING_MESSAGE

def test_like_view_redirects_to_login_when_logged_out(self, post, client):
# Testing that when logged out, if trying to access the like url
# the user gets redirected to the login url
post_to_like = post
response = client.get(post_like_url(post_to_like.id))
assert response.status_code == REDIRECT_URL_STATUS
assert response.url == LOGIN_URL

def test_like_url_doesnt_adds_like_to_post(self, post, client, post_init_like_count):
# Testing that when logged out, if trying to access the like url
# it doesnt adds a like to a post
post_to_check_likes = post
client.get(post_like_url(post_to_check_likes.id))
assert post_to_check_likes.likes.count() == post_init_like_count


class TestLikeForLoggedUser:
def test_like_url_adds_like_to_post(self, post, logged_in_client, post_init_like_count):
# Testing that the like url, adds a like to a specific post
post_to_like = post
response = logged_in_client.get(post_like_url(post_to_like.id))
response = logged_in_client.get(response.url)
assert response.context['post'].id == post_to_like.id
assert response.context['post'].likes.count() == post_init_like_count + 1

def test_like_url_unlikes(self, liked_post, logged_in_client, liked_post_init_like_count):
# Testing that the like url, unlike a post where the logged in
# user have already liked the post
post_to_unlike = liked_post
response = logged_in_client.get(post_like_url(post_to_unlike.id))
response = logged_in_client.get(response.url)
assert response.status_code == 200
assert response.context['post'].id == post_to_unlike.id
assert response.context['post'].likes.count() == liked_post_init_like_count - 1

def test_after_like_redirect_to_detail_view(self, post, logged_in_client):
# Testing that after successful like, if the user got to the like URL
# by typing it, he would get redirected to the post detail view page.
# Also, if a user turned off the HTTP_REFERER option in his browser he would
# get returned to the post detail view
response = logged_in_client.get(post_like_url(post.id))
assert response.status_code == REDIRECT_URL_STATUS
assert response.url == POST_DETAIL_URL + f'{post.id}/'
response = logged_in_client.get(response.url)
assert response.status_code == 200
1 change: 1 addition & 0 deletions feed/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
path('post/<int:pk>/delete/', views.PostDeleteView.as_view(), name='post-delete'),
path('post/new/', views.PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/comment/new/', views.CommentCreateView.as_view(), name='comment-create'),
path('post/<int:pk>/like/', views.LikeView, name='like-post'),
]
22 changes: 21 additions & 1 deletion feed/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.shortcuts import render, get_object_or_404
from django.shortcuts import render, redirect, get_object_or_404
from .models import Post, Comment
from django.views.generic import DetailView, DeleteView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib import messages
from django.urls import reverse
from django.http import HttpResponseRedirect


def feed(request):
Expand Down Expand Up @@ -59,3 +60,22 @@ def form_valid(self, form):
comment.save()

return super().form_valid(form)


def LikeView(request, pk):
post = get_object_or_404(Post, id=pk)
user = request.user
if user.is_authenticated:
if post.likes.filter(id=user.id).exists():
post.likes.remove(user)
else:
post.likes.add(user)

origin_url = request.META.get('HTTP_REFERER')
if origin_url is not None:
return HttpResponseRedirect(origin_url)
return HttpResponseRedirect(reverse('post-detail', args=(str(pk),)))

else:
messages.warning(request, "You must login in order to like a post")
return redirect('login')

0 comments on commit abe6286

Please sign in to comment.