from django.test import TestCase from django.urls import reverse from django.contrib.auth.models import User, Permission from django.contrib.auth.hashers import make_password from watchlist.models import Movie, MovieVote def create_user(name="user", is_staff=False): user = User.objects.create(username=name, password=make_password("dummy")) user.user_permissions.add(Permission.objects.get(codename="add_movie")) user.save() return user def create_movie(name="Test movie", added_by="user"): return Movie.objects.create(name=name, suggested_by=User.objects.filter(username=added_by).first(), watched=False) class IndexViewTests(TestCase): def setUp(self): self.user = create_user("user") def test_no_movies(self): """Tests the index page with no movies""" response = self.client.get(reverse('watchlist:index')) self.assertQuerysetEqual(response.context["object_list"], []) self.assertContains(response, "No movies yet.") self.assertNotContains(response, "Submit new movie") def test_no_movies_logged_in(self): """Tests the index page with no movies, while the user is logged in.""" self.client.login(username="user", password="dummy") response = self.client.get(reverse('watchlist:index')) self.assertQuerysetEqual(response.context["object_list"], []) self.assertContains(response, "No movies yet.") self.assertContains(response, "Submit new movie") def test_with_movie(self): """Tests that the index page shows a movie, hides it if it watched, but shows it with proper filter""" create_movie() with self.subTest(watched=False): response = self.client.get(reverse('watchlist:index')) self.assertQuerysetEqual(response.context["object_list"], Movie.objects.all()) self.assertContains(response, "Test movie") movie = Movie.objects.first() movie.watched = True movie.save() with self.subTest(watched=True, filter=False): response = self.client.get(reverse('watchlist:index')) self.assertQuerysetEqual(response.context["object_list"], []) self.assertNotContains(response, "Test movie") with self.subTest(watched=True, filter=True): response = self.client.get(reverse('watchlist:index',) + "?watched") self.assertQuerysetEqual(response.context["object_list"], Movie.objects.all()) self.assertContains(response, "Test movie") def test_unvoted(self): """Test that the index shows an asterisk with movies that the user hasn't voted on yet""" create_movie() self.client.login(username="user",password="dummy") response = self.client.get(reverse('watchlist:index')) self.assertContains(response, "Test movie*") def test_voted(self): """Test that the index doesn't show an asterisk with movies the has voted on.""" movie = create_movie() MovieVote.objects.create(movie=movie, user=self.user, vote=1) self.client.login(username="user",password="dummy") response = self.client.get(reverse('watchlist:index')) self.assertContains(response, "Test movie") self.assertNotContains(response, "Test movie*") def test_movie_sorting(self): """Test various methods of movie sorting""" m1 = create_movie(name="ZZZ: A movie test") m2 = create_movie(name="Test movie 2") tests = [ ('?sort=id', [m1,m2]), ('?sort=-id', [m2,m1]), ('?sort=name', [m2,m1]), ('?sort=-name', [m1,m2]), ] for param, qs in tests: with self.subTest(param=param, qs=qs): response = self.client.get(reverse('watchlist:index') + param) self.assertQuerysetEqual(response.context["object_list"], qs) self.assertContains(response, m1.name) self.assertContains(response, m2.name) class MovieDetailViewTests(TestCase): def setUp(self): self.user = create_user("user") def test_detail_logged_out(self): m = create_movie() response = self.client.get(reverse('watchlist:detail', args=(m.id,))) self.assertContains(response, m.name) self.assertEqual(response.context["movie"], m) self.assertNotContains(response, "Edit") def test_detail_logged_in(self): m = create_movie() self.client.login(username="user", password="dummy") response = self.client.get(reverse('watchlist:detail', args=(m.id,))) self.assertContains(response, m.name) self.assertEqual(response.context["movie"], m) self.assertContains(response, "Edit") def test_no_movie(self): response = self.client.get(reverse('watchlist:detail', args=(1,))) self.assertEqual(response.status_code, 404) class VoteTests(TestCase): def setUp(self): self.user = create_user("user") def test_no_user_voting(self): m = create_movie() response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data={"vote": 1, "seen": True}) self.assertRedirects(response, "/accounts/login/?next=" + response.request["PATH_INFO"], fetch_redirect_response=False) def test_user_voting(self): m = create_movie() score = m.score self.client.login(username="user", password="dummy") for vote in [1, 0, -1]: for seen in True, False: with self.subTest(vote=vote, seen=seen): response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data={"vote": str(vote), "seen": True}) self.assertRedirects(response, reverse('watchlist:index')) self.assertEqual(m.score, score + vote) def test_invalid_votes(self): m = create_movie() score = m.score self.client.login(username="user", password="dummy") for vote in [2,3,4,-5,0.5,'abc','']: with self.subTest(vote=vote): response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data={"vote": str(vote), "seen": True}) self.assertEqual(response.status_code, 400) self.assertEqual(m.score, score) with self.subTest(vote="empty"): response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data={"seen": True}) self.assertEqual(response.status_code, 400) self.assertEqual(m.score, score) def test_seen(self): m = create_movie() self.client.login(username="user", password="dummy") for seen in (True, False) * 2: with self.subTest(seen=seen): data = {"vote": "0", "seen": "on"} if seen else {"vote": "0"} response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data=data) self.assertRedirects(response, reverse('watchlist:index')) mv = m.movievote_set.get(user=self.user) self.assertEqual(mv.seen, seen) def test_comment(self): m = create_movie() self.client.login(username="user", password="dummy") for comment in ["aaa", "", "TEST"]: with self.subTest(comment=comment): response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data={"vote": "0", "comment": comment}) mv = m.movievote_set.get(user=self.user) self.assertEqual(mv.comment, None if comment == "" else comment) with self.subTest(comment=None): response = self.client.post(reverse('watchlist:vote', args=(m.id,)), data={"vote": "0"}) mv = m.movievote_set.get(user=self.user) self.assertEqual(mv.comment, None)