From 8a5ece0fb101fac3b643f18fc999b723caf959dc Mon Sep 17 00:00:00 2001 From: Sandeep <7006205280dk@gmail.com> Date: Mon, 26 Oct 2026 22:11:25 +0530 Subject: [PATCH] [FIX] Handle missing test in restart_test and stop_test When restart_test or stop_test is invoked with a nonexistent test_id, the controller queried Test.query.filter(Test.id == test_id).first() without verifying if test is None. For admin users, execution continued to test.id, causing an unhandled AttributeError ('NoneType' object has no attribute 'id') and returning HTTP 500. For non-admin users, the endpoint erroneously returned HTTP 403 Forbidden instead of HTTP 404 Not Found. Explicitly verify if test is None and raise TestNotFoundException, logging the error and rendering the standard 404 test_not_found page, matching by_id and REST API runs endpoints. Fixes #1248 --- mod_test/controllers.py | 8 ++++++ tests/test_test/test_controllers.py | 44 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/mod_test/controllers.py b/mod_test/controllers.py index 62844bbe..691ab698 100644 --- a/mod_test/controllers.py +++ b/mod_test/controllers.py @@ -416,6 +416,10 @@ def restart_test(test_id): :type test_id: int """ test = Test.query.filter(Test.id == test_id).first() + if test is None: + g.log.error(f"test with id: {test_id} not found!") + raise TestNotFoundException(f"Test with id {test_id} does not exist") + test_fork = TestFork.query.filter(TestFork.user_id == g.user.id, TestFork.test_id == test_id).first() if not g.user.is_admin and test_fork is None: g.log.warning(f"user with id: {g.user.id} tried to access restricted endpoint") @@ -441,6 +445,10 @@ def stop_test(test_id): :type test_id: int """ test = Test.query.filter(Test.id == test_id).first() + if test is None: + g.log.error(f"test with id: {test_id} not found!") + raise TestNotFoundException(f"Test with id {test_id} does not exist") + test_fork = TestFork.query.filter(TestFork.user_id == g.user.id, TestFork.test_id == test_id).first() if not g.user.is_admin and test_fork is None: g.log.warning(f"user with id: {g.user.id} tried to access restricted endpoint") diff --git a/tests/test_test/test_controllers.py b/tests/test_test/test_controllers.py index 1fa043fb..eeec69b2 100644 --- a/tests/test_test/test_controllers.py +++ b/tests/test_test/test_controllers.py @@ -109,6 +109,50 @@ def test_stop_fails_on_no_permission(self): response = c.get('/test/stop_test/1') self.assert403(response) + def test_restart_nonexistent_test_as_admin(self): + """Test restart of a nonexistent test as admin returns 404.""" + self.create_user_with_role( + self.user.name, self.user.email, self.user.password, Role.admin) + with self.app.test_client() as c: + c.post( + '/account/login', data=self.create_login_form_data(self.user.email, self.user.password)) + response = c.get('/test/restart_test/99999') + self.assertEqual(response.status_code, 404) + self.assert_template_used('test/test_not_found.html') + + def test_restart_nonexistent_test_as_tester(self): + """Test restart of a nonexistent test as tester returns 404.""" + self.create_user_with_role( + self.user.name, self.user.email, self.user.password, Role.tester) + with self.app.test_client() as c: + c.post( + '/account/login', data=self.create_login_form_data(self.user.email, self.user.password)) + response = c.get('/test/restart_test/99999') + self.assertEqual(response.status_code, 404) + self.assert_template_used('test/test_not_found.html') + + def test_stop_nonexistent_test_as_admin(self): + """Test stop of a nonexistent test as admin returns 404.""" + self.create_user_with_role( + self.user.name, self.user.email, self.user.password, Role.admin) + with self.app.test_client() as c: + c.post( + '/account/login', data=self.create_login_form_data(self.user.email, self.user.password)) + response = c.get('/test/stop_test/99999') + self.assertEqual(response.status_code, 404) + self.assert_template_used('test/test_not_found.html') + + def test_stop_nonexistent_test_as_tester(self): + """Test stop of a nonexistent test as tester returns 404.""" + self.create_user_with_role( + self.user.name, self.user.email, self.user.password, Role.tester) + with self.app.test_client() as c: + c.post( + '/account/login', data=self.create_login_form_data(self.user.email, self.user.password)) + response = c.get('/test/stop_test/99999') + self.assertEqual(response.status_code, 404) + self.assert_template_used('test/test_not_found.html') + def test_get_json_data_throw_not_found_error(self): """Test if get_json_data throws Error 404.""" response = self.app.test_client().get('/test/get_json_data/99999')