Coverage for website/tests/test_login_and_search_views.py: 100%

63 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2025-09-13 15:29 -0300

1from types import SimpleNamespace 

2from unittest.mock import patch 

3 

4from django.contrib.auth import get_user_model 

5from django.contrib.messages.storage.fallback import FallbackStorage 

6from django.contrib.sessions.backends.db import SessionStore 

7from django.test import RequestFactory, TestCase 

8 

9from website.models.AuthorModel import Author 

10from website.models.PostModel import Post 

11from website.views.LoginView import login_user 

12from website.views.SearchView import search_posts 

13 

14User = get_user_model() 

15 

16 

17class LoginViewTests(TestCase): 

18 def setUp(self): 

19 self.factory = RequestFactory() 

20 

21 def _attach_session_and_messages(self, req): 

22 req.session = SessionStore() 

23 req._messages = FallbackStorage(req) 

24 

25 def test_login_success_redirects(self): 

26 # create user 

27 user = User.objects.create_user( 

28 email="u1@example.com", username="u1", password="pw" 

29 ) 

30 data = {"email": "u1@example.com", "password": "pw"} 

31 req = self.factory.post("/login", data) 

32 self._attach_session_and_messages(req) 

33 

34 # patch authenticate and check_password to ensure branch 

35 with ( 

36 patch("website.views.LoginView.authenticate", return_value=user), 

37 patch("website.views.LoginView.check_password", return_value=True), 

38 ): 

39 resp = login_user(req) 

40 

41 # successful login redirects to '/' 

42 assert resp.status_code in (301, 302) 

43 

44 def test_login_email_not_found_renders_with_flag(self): 

45 data = {"email": "noone@example.com", "password": "pw"} 

46 req = self.factory.post("/login", data) 

47 self._attach_session_and_messages(req) 

48 

49 # patch render to capture context 

50 def fake_render(req_in, template, context=None, status=200): 

51 return SimpleNamespace(status_code=status, context=context) 

52 

53 with patch("website.views.LoginView.render", fake_render): 

54 resp = login_user(req) 

55 

56 assert resp.status_code == 200 

57 assert getattr(resp, "context", None) is not None 

58 assert resp.context.get("email_not_found", False) is True 

59 

60 

61class SearchViewTests(TestCase): 

62 def setUp(self): 

63 self.factory = RequestFactory() 

64 

65 def test_search_returns_results_and_counts(self): 

66 user = User.objects.create_user( 

67 email="a@example.com", username="a", password="pw" 

68 ) 

69 author = Author.objects.create( 

70 user=user, author_name="AuthorX", author_url_slug="ax" 

71 ) 

72 # create matching posts 

73 Post.objects.create(author=author, title="FindMe", text="abc", url_slug="p1") 

74 Post.objects.create( 

75 author=author, title="FindMe two", text="def", url_slug="p2" 

76 ) 

77 

78 req = self.factory.get("/search", {"query": "FindMe"}) 

79 

80 def fake_render(req_in, template, context=None): 

81 return SimpleNamespace(status_code=200, context=context) 

82 

83 with patch("website.views.SearchView.render", fake_render): 

84 resp = search_posts(req) 

85 

86 assert resp.status_code == 200 

87 assert resp.context["results_count"] == 2 

88 

89 def test_search_page_not_integer_returns_first_page(self): 

90 user = User.objects.create_user( 

91 email="b@example.com", username="b", password="pw" 

92 ) 

93 author = Author.objects.create( 

94 user=user, author_name="AuthorY", author_url_slug="ay" 

95 ) 

96 # one matching post 

97 Post.objects.create(author=author, title="OnlyOne", text="x", url_slug="o1") 

98 

99 req = self.factory.get("/search", {"query": "OnlyOne", "page": "notint"}) 

100 

101 def fake_render(req_in, template, context=None): 

102 return SimpleNamespace(status_code=200, context=context) 

103 

104 resp = None 

105 with patch("website.views.SearchView.render", fake_render): 

106 resp = search_posts(req) 

107 

108 assert resp.status_code == 200 

109 # posts is a Page object; ensure it corresponds to page 1 

110 # by checking object_list length 

111 assert len(list(resp.context["posts"])) == 1