| 
									
										
										
										
											2024-07-12 00:17:15 -05:00
										 |  |  | # -*- coding: utf-8; -*- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  | from unittest.mock import patch | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import colander | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  | from wuttaweb.views import common as mod | 
					
						
							| 
									
										
										
										
											2025-01-06 16:47:48 -06:00
										 |  |  | from wuttaweb.testing import WebTestCase | 
					
						
							| 
									
										
										
										
											2025-06-29 09:16:44 -05:00
										 |  |  | from wuttaweb.app import establish_theme | 
					
						
							| 
									
										
										
										
											2024-07-12 00:17:15 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  | class TestCommonView(WebTestCase): | 
					
						
							| 
									
										
										
										
											2024-07-12 00:17:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |     def make_view(self): | 
					
						
							|  |  |  |         return mod.CommonView(self.request) | 
					
						
							| 
									
										
										
										
											2024-07-12 00:17:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |     def test_includeme(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.include("wuttaweb.views.common") | 
					
						
							| 
									
										
										
										
											2024-07-12 00:17:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 22:13:55 -05:00
										 |  |  |     def test_forbidden_view(self): | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  |         context = view.forbidden_view() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(context["index_title"], self.app.get_title()) | 
					
						
							| 
									
										
										
										
											2024-08-14 22:13:55 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_notfound_view(self): | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  |         context = view.notfound_view() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(context["index_title"], self.app.get_title()) | 
					
						
							| 
									
										
										
										
											2024-08-14 22:13:55 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-12 00:17:15 -05:00
										 |  |  |     def test_home(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.add_route("setup", "/setup") | 
					
						
							|  |  |  |         self.pyramid_config.add_route("login", "/login") | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # if no users then home page will redirect | 
					
						
							|  |  |  |         response = view.home(session=self.session) | 
					
						
							|  |  |  |         self.assertEqual(response.status_code, 302) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # so add a user | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="foo") | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |         self.session.add(user) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # now we see the home page | 
					
						
							|  |  |  |         context = view.home(session=self.session) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(context["index_title"], self.app.get_title()) | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 20:16:19 -05:00
										 |  |  |         # but if configured, anons will be redirected to login | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config.setdefault("wuttaweb.home_redirect_to_login", "true") | 
					
						
							| 
									
										
										
										
											2024-08-20 20:16:19 -05:00
										 |  |  |         response = view.home(session=self.session) | 
					
						
							|  |  |  |         self.assertEqual(response.status_code, 302) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # now only an auth'ed user can see home page | 
					
						
							|  |  |  |         self.request.user = user | 
					
						
							|  |  |  |         context = view.home(session=self.session) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(context["index_title"], self.app.get_title()) | 
					
						
							| 
									
										
										
										
											2024-08-20 20:16:19 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |     def test_feedback_make_schema(self): | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  |         schema = view.feedback_make_schema() | 
					
						
							|  |  |  |         self.assertIsInstance(schema, colander.Schema) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertIn("message", schema) | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_feedback(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.add_route("users.view", "/users/{uuid}") | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |         model = self.app.model | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |         self.session.add(user) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(view, "feedback_send") as feedback_send: | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # basic send, no user | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.request.client_addr = "127.0.0.1" | 
					
						
							|  |  |  |             self.request.method = "POST" | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |             self.request.POST = { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "referrer": "/foo", | 
					
						
							|  |  |  |                 "user_name": "Barney Rubble", | 
					
						
							|  |  |  |                 "message": "hello world", | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |             } | 
					
						
							|  |  |  |             context = view.feedback() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(context, {"ok": True}) | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |             feedback_send.assert_called_once() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # reset | 
					
						
							|  |  |  |             feedback_send.reset_mock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # basic send, with user | 
					
						
							|  |  |  |             self.request.user = user | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.request.POST["user_uuid"] = str(user.uuid) | 
					
						
							|  |  |  |             with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |                 context = view.feedback() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(context, {"ok": True}) | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |             feedback_send.assert_called_once() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # reset | 
					
						
							|  |  |  |             self.request.user = None | 
					
						
							|  |  |  |             feedback_send.reset_mock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # invalid form data | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.request.POST = {"message": "hello world"} | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |             context = view.feedback() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(list(context), ["error"]) | 
					
						
							|  |  |  |             self.assertIn("Required", context["error"]) | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |             feedback_send.assert_not_called() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # error on send | 
					
						
							|  |  |  |             self.request.POST = { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |                 "referrer": "/foo", | 
					
						
							|  |  |  |                 "user_name": "Barney Rubble", | 
					
						
							|  |  |  |                 "message": "hello world", | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  |             } | 
					
						
							|  |  |  |             feedback_send.side_effect = RuntimeError | 
					
						
							|  |  |  |             context = view.feedback() | 
					
						
							|  |  |  |             feedback_send.assert_called_once() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             self.assertEqual(list(context), ["error"]) | 
					
						
							|  |  |  |             self.assertIn("RuntimeError", context["error"]) | 
					
						
							| 
									
										
										
										
											2024-08-25 20:25:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:21:05 -05:00
										 |  |  |     def test_feedback_send(self): | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.app, "send_email") as send_email: | 
					
						
							|  |  |  |             view.feedback_send({"user_name": "Barney", "message": "hello world"}) | 
					
						
							|  |  |  |             send_email.assert_called_once_with( | 
					
						
							|  |  |  |                 "feedback", {"user_name": "Barney", "message": "hello world"} | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:21:05 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |     def test_setup(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.add_route("home", "/") | 
					
						
							|  |  |  |         self.pyramid_config.add_route("login", "/login") | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |         model = self.app.model | 
					
						
							|  |  |  |         auth = self.app.get_auth_handler() | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # at first, can see the setup page | 
					
						
							|  |  |  |         self.assertEqual(self.session.query(model.User).count(), 0) | 
					
						
							|  |  |  |         context = view.setup(session=self.session) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(context["index_title"], self.app.get_title()) | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # so add a user | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="foo") | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |         self.session.add(user) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # once user exists it will always redirect | 
					
						
							|  |  |  |         response = view.setup(session=self.session) | 
					
						
							|  |  |  |         self.assertEqual(response.status_code, 302) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # delete that user | 
					
						
							|  |  |  |         self.session.delete(user) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # so we can see the setup page again | 
					
						
							|  |  |  |         context = view.setup(session=self.session) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(context["index_title"], self.app.get_title()) | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # and finally, post data to create admin user | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.request.method = "POST" | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |         self.request.POST = { | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |             "username": "barney", | 
					
						
							|  |  |  |             "__start__": "password:mapping", | 
					
						
							|  |  |  |             "password": "testpass", | 
					
						
							|  |  |  |             "password-confirm": "testpass", | 
					
						
							|  |  |  |             "__end__": "password:mapping", | 
					
						
							|  |  |  |             "first_name": "Barney", | 
					
						
							|  |  |  |             "last_name": "Rubble", | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |         response = view.setup(session=self.session) | 
					
						
							|  |  |  |         # nb. redirects on success | 
					
						
							|  |  |  |         self.assertEqual(response.status_code, 302) | 
					
						
							|  |  |  |         barney = self.session.query(model.User).one() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(barney.username, "barney") | 
					
						
							|  |  |  |         self.assertTrue(auth.check_user_password(barney, "testpass")) | 
					
						
							| 
									
										
										
										
											2024-08-14 18:29:08 -05:00
										 |  |  |         admin = auth.get_role_administrator(self.session) | 
					
						
							|  |  |  |         self.assertIn(admin, barney.roles) | 
					
						
							|  |  |  |         self.assertIsNotNone(barney.person) | 
					
						
							|  |  |  |         person = barney.person | 
					
						
							|  |  |  |         self.assertEqual(person.first_name, "Barney") | 
					
						
							|  |  |  |         self.assertEqual(person.last_name, "Rubble") | 
					
						
							|  |  |  |         self.assertEqual(person.full_name, "Barney Rubble") | 
					
						
							| 
									
										
										
										
											2025-06-29 09:16:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_change_theme(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config.add_route("home", "/") | 
					
						
							| 
									
										
										
										
											2025-06-29 09:16:44 -05:00
										 |  |  |         settings = self.request.registry.settings | 
					
						
							|  |  |  |         establish_theme(settings) | 
					
						
							|  |  |  |         view = self.make_view() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # theme is not changed if not provided by caller | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(settings["wuttaweb.theme"], "default") | 
					
						
							|  |  |  |         with patch.object(mod, "set_app_theme") as set_app_theme: | 
					
						
							| 
									
										
										
										
											2025-06-29 09:16:44 -05:00
										 |  |  |             view.change_theme() | 
					
						
							|  |  |  |             set_app_theme.assert_not_called() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(settings["wuttaweb.theme"], "default") | 
					
						
							| 
									
										
										
										
											2025-06-29 09:16:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # but theme will change if provided | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         with patch.object(self.request, "params", new={"theme": "butterfly"}): | 
					
						
							|  |  |  |             with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-06-29 09:16:44 -05:00
										 |  |  |                 view.change_theme() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(settings["wuttaweb.theme"], "butterfly") | 
					
						
							| 
									
										
										
										
											2025-06-29 09:16:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # flash error if invalid theme is provided | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(self.request.session.peek_flash("error")) | 
					
						
							|  |  |  |         with patch.object(self.request, "params", new={"theme": "anotherone"}): | 
					
						
							|  |  |  |             with patch.object(mod, "Session", return_value=self.session): | 
					
						
							| 
									
										
										
										
											2025-06-29 09:16:44 -05:00
										 |  |  |                 view.change_theme() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual(settings["wuttaweb.theme"], "butterfly") | 
					
						
							|  |  |  |         self.assertTrue(self.request.session.peek_flash("error")) | 
					
						
							|  |  |  |         messages = self.request.session.pop_flash("error") | 
					
						
							|  |  |  |         self.assertIn("Failed to set theme", messages[0]) |