From 9a455841d15f6bf9b2e0f51ee5ed3a33daf9bc7e Mon Sep 17 00:00:00 2001 From: Jana Cupova Date: Mar 22 2021 12:06:25 +0000 Subject: unify error messages for web Fixes: https://pagure.io/koji/issue/2720 --- diff --git a/tests/test_www/test_buildinfo.py b/tests/test_www/test_buildinfo.py new file mode 100644 index 0000000..981dcfa --- /dev/null +++ b/tests/test_www/test_buildinfo.py @@ -0,0 +1,31 @@ +import unittest +import koji + +import mock +from .loadwebindex import webidx + + +class TestBuildInfo(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None + } + self.build_id = '1' + + def tearDown(self): + mock.patch.stopall() + + def test_buildinfo_exception(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getBuild.side_effect = koji.GenericError + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.buildinfo(self.environ, self.build_id) + self.assertEqual(str(cm.exception), 'No such build ID: %s' % self.build_id) diff --git a/tests/test_www/test_buildtargetdelete.py b/tests/test_www/test_buildtargetdelete.py new file mode 100644 index 0000000..0c9e636 --- /dev/null +++ b/tests/test_www/test_buildtargetdelete.py @@ -0,0 +1,53 @@ +from __future__ import absolute_import +import unittest +import mock + +import koji +from koji.server import ServerRedirect +from .loadwebindex import webidx + + +class TestBuildTargetDelete(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + self.assert_login = mock.patch.object(webidx, "_assertLogin").start() + self.session = mock.MagicMock() + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None, + + } + + def __get_server(env): + env['koji.session'] = self.session + return self.session + + self.get_server.side_effect = __get_server + self.buildtarget_id = 1 + + def tearDown(self): + mock.patch.stopall() + + def test_buildtargetdelete_exception_from_api_call(self): + """Test taskinfo function raises exception""" + self.get_server.return_value = self.session + self.session.getBuildTarget.return_value = None + + with self.assertRaises(koji.GenericError) as cm: + webidx.buildtargetdelete(self.environ, self.buildtarget_id) + self.session.deleteBuildTarget.assert_not_called() + self.assertEqual(str(cm.exception), 'No such build target: %s' % self.buildtarget_id) + + def test_buildtargetdelete_normal_case(self): + """Test taskinfo function""" + self.get_server.return_value = self.session + self.session.getBuildTarget.return_value = {'id': self.buildtarget_id} + webidx._assertLogin.return_value = True + + with self.assertRaises(ServerRedirect): + webidx.buildtargetdelete(self.environ, self.buildtarget_id) + self.session.deleteBuildTarget.assert_called_with(self.buildtarget_id) + self.assertEqual(self.environ['koji.redirect'], 'buildtargets') diff --git a/tests/test_www/test_buildtargetedit.py b/tests/test_www/test_buildtargetedit.py new file mode 100644 index 0000000..5d6d315 --- /dev/null +++ b/tests/test_www/test_buildtargetedit.py @@ -0,0 +1,74 @@ +import mock +import unittest +import cgi + +import koji +from io import BytesIO +from .loadwebindex import webidx + + +class TestBuildTargetEdit(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + self.assert_login = mock.patch.object(webidx, "_assertLogin").start() + self.server = mock.MagicMock() + self.buildtarget_id = '1' + self.buildtag_id = '11' + self.desttag_id = '99' + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None, + } + + urlencode_data = b"save=True&name=testname&buildTag=11&destTag=99" + urlencode_environ = { + 'CONTENT_LENGTH': str(len(urlencode_data)), + 'CONTENT_TYPE': 'application/x-www-form-urlencoded', + 'QUERY_STRING': '', + 'REQUEST_METHOD': 'POST', + } + data = BytesIO(urlencode_data) + data.seek(0) + self.fs = cgi.FieldStorage(fp=data, environ=urlencode_environ) + + def __get_server(env): + env['koji.session'] = self.server + env['koji.form'] = self.fs + return self.server + + self.get_server.side_effect = __get_server + + def tearDown(self): + mock.patch.stopall() + + def test_buildtargetedit_exception(self): + """Test taskinfo function raises exception""" + self.server.getBuildTarget.return_value = None + self.get_server.return_value = self.server + + with self.assertRaises(koji.GenericError) as cm: + webidx.buildtargetedit(self.environ, self.buildtarget_id) + self.assertEqual(str(cm.exception), 'No such build target: %s' % self.buildtarget_id) + + def test_buildtargetedit_exception_build_tag(self): + """Test taskinfo function raises exception""" + self.server.getBuildTarget.return_value = {'id': 1} + self.server.getTag.return_value = None + self.get_server.return_value = self.server + + with self.assertRaises(koji.GenericError) as cm: + webidx.buildtargetedit(self.environ, self.buildtarget_id) + self.assertEqual(str(cm.exception), 'No such tag ID: %s' % self.buildtag_id) + + def test_buildtargetedit_exception_dest_tag(self): + """Test taskinfo function raises exception""" + self.server.getBuildTarget.return_value = {'id': 1} + self.server.getTag.side_effect = [{'id': 11}, None] + self.get_server.return_value = self.server + + with self.assertRaises(koji.GenericError) as cm: + webidx.buildtargetedit(self.environ, self.buildtarget_id) + self.assertEqual(str(cm.exception), 'No such tag ID: %s' % self.desttag_id) diff --git a/tests/test_www/test_buildtargetinfo.py b/tests/test_www/test_buildtargetinfo.py new file mode 100644 index 0000000..0fb6908 --- /dev/null +++ b/tests/test_www/test_buildtargetinfo.py @@ -0,0 +1,42 @@ +import mock +import unittest + +import koji +from .loadwebindex import webidx + + +class TestBuildTargetInfo(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None + } + self.buildtarget_id = '1' + self.buildtarget_name = 'test-name' + + def tearDown(self): + mock.patch.stopall() + + def test_buildtargetinfo_exception_id(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getBuildTarget.return_value = None + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.buildtargetinfo(self.environ, targetID=self.buildtarget_id) + self.assertEqual(str(cm.exception), 'No such build target: %s' % self.buildtarget_id) + + def test_buildtargetinfo_exception_name(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getBuildTarget.return_value = None + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.buildtargetinfo(self.environ, name=self.buildtarget_name) + self.assertEqual(str(cm.exception), 'No such build target: %s' % self.buildtarget_name) diff --git a/tests/test_www/test_channelinfo.py b/tests/test_www/test_channelinfo.py new file mode 100644 index 0000000..742418f --- /dev/null +++ b/tests/test_www/test_channelinfo.py @@ -0,0 +1,31 @@ +import mock +import unittest + +import koji +from .loadwebindex import webidx + + +class TestChannelInfo(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None + } + self.channel_id = '1' + + def tearDown(self): + mock.patch.stopall() + + def test_channelinfo_exception(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + self.get_server.return_value = server + server.getChannel.return_value = None + + with self.assertRaises(koji.GenericError) as cm: + webidx.channelinfo(self.environ, self.channel_id) + self.assertEqual(str(cm.exception), 'No such channel ID: %s' % self.channel_id) diff --git a/tests/test_www/test_fileinfo.py b/tests/test_www/test_fileinfo.py new file mode 100644 index 0000000..c950cda --- /dev/null +++ b/tests/test_www/test_fileinfo.py @@ -0,0 +1,84 @@ +import mock +import unittest + +import koji +from .loadwebindex import webidx + + +class TestFileInfo(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None + } + self.filename = 'testfilename' + self.rpm_id = '11' + self.archive_id = '111' + + def tearDown(self): + mock.patch.stopall() + + def test_fileinfo_exception_rpm(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getRPM.return_value = None + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.fileinfo(self.environ, self.filename, rpmID=self.rpm_id) + self.assertEqual( + str(cm.exception), 'No such RPM ID: %s' % self.rpm_id) + + def test_fileinfo_exception_archive(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getArchive.return_value = None + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.fileinfo(self.environ, self.filename, archiveID=self.archive_id) + self.assertEqual( + str(cm.exception), 'No such archive ID: %s' % self.archive_id) + + def test_fileinfo_exception_rpm_file(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getRPMFile.return_value = None + server.getRPM.return_value = {'id': 123} + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.fileinfo(self.environ, self.filename, rpmID=self.rpm_id) + self.assertEqual( + str(cm.exception), 'no file %s in RPM %i' % (self.filename, int(self.rpm_id))) + + def test_fileinfo_exception_archive_file(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getArchiveFile.return_value = None + server.getArchive.return_value = {'id': 123} + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.fileinfo(self.environ, self.filename, archiveID=self.archive_id) + self.assertEqual( + str(cm.exception), 'no file %s in archive %i' % (self.filename, int(self.archive_id))) + + def test_fileinfo_exception(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.fileinfo(self.environ, self.filename) + self.assertEqual(str(cm.exception), 'either rpmID or archiveID must be specified') diff --git a/tests/test_www/test_hostinfo.py b/tests/test_www/test_hostinfo.py new file mode 100644 index 0000000..ff1bde5 --- /dev/null +++ b/tests/test_www/test_hostinfo.py @@ -0,0 +1,57 @@ +import mock +import unittest + +import koji +from .loadwebindex import webidx + + +class TestHostInfo(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None + } + self.host_id = '11' + self.user_id = '111' + + def tearDown(self): + mock.patch.stopall() + + def test_hostinfo_exception_host_option(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getHost.return_value = None + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.hostinfo(self.environ, hostID=self.host_id) + self.assertEqual( + str(cm.exception), 'No such host ID: %s' % self.host_id) + + def test_hostinfo_exception_user_option(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.listHosts.return_value = [] + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.hostinfo(self.environ, userID=self.user_id) + self.assertEqual( + str(cm.exception), 'No such host for user ID: %s' % self.user_id) + + def test_hostinfo_exception(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.hostinfo(self.environ) + self.assertEqual(str(cm.exception), 'hostID or userID must be provided') diff --git a/tests/test_www/test_packageinfo.py b/tests/test_www/test_packageinfo.py new file mode 100644 index 0000000..d59e13b --- /dev/null +++ b/tests/test_www/test_packageinfo.py @@ -0,0 +1,34 @@ +import mock +import unittest + +import koji +from .loadwebindex import webidx + + +class TestPackageInfo(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None + } + self.package_id = '1' + + def tearDown(self): + mock.patch.stopall() + + def test_packageinfo_exception(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getPackage.return_value = None + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.packageinfo(self.environ, self.package_id) + self.assertEqual( + str(cm.exception), 'No such package ID: %s' % self.package_id) diff --git a/tests/test_www/test_rpminfo.py b/tests/test_www/test_rpminfo.py new file mode 100644 index 0000000..dc4495e --- /dev/null +++ b/tests/test_www/test_rpminfo.py @@ -0,0 +1,34 @@ +import mock +import unittest + +import koji +from .loadwebindex import webidx + + +class TestRpmInfo(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None + } + self.build_id = '1' + + def tearDown(self): + mock.patch.stopall() + + def test_rpminfo_exception(self): + """Test taskinfo function raises exception""" + server = mock.MagicMock() + server.getRPM.side_effect = koji.GenericError + + self.get_server.return_value = server + + with self.assertRaises(koji.GenericError) as cm: + webidx.rpminfo(self.environ, self.build_id) + self.assertEqual( + str(cm.exception), 'No such RPM ID: %s' % self.build_id) diff --git a/tests/test_www/test_search.py b/tests/test_www/test_search.py new file mode 100644 index 0000000..4618923 --- /dev/null +++ b/tests/test_www/test_search.py @@ -0,0 +1,48 @@ +import mock +import unittest +import cgi + +import koji +from io import BytesIO +from .loadwebindex import webidx + + +class TestSearch(unittest.TestCase): + def setUp(self): + self.get_server = mock.patch.object(webidx, "_getServer").start() + self.server = mock.MagicMock() + self.environ = { + 'koji.options': { + 'SiteName': 'test', + 'KojiFilesURL': 'https://server.local/files', + }, + 'koji.currentUser': None, + } + urlencode_data = b"terms=test&type=package&match=testmatch" + urlencode_environ = { + 'CONTENT_LENGTH': str(len(urlencode_data)), + 'CONTENT_TYPE': 'application/x-www-form-urlencoded', + 'QUERY_STRING': '', + 'REQUEST_METHOD': 'POST', + } + data = BytesIO(urlencode_data) + data.seek(0) + self.fs = cgi.FieldStorage(fp=data, environ=urlencode_environ) + + def __get_server(env): + env['koji.form'] = self.fs + return self.server + + self.get_server.side_effect = __get_server + + def tearDown(self): + mock.patch.stopall() + + def test_search_exception_match(self): + """Test taskinfo function raises exception""" + self.server.getBuildTarget.return_info = None + self.get_server.return_value = self.server + + with self.assertRaises(koji.GenericError) as cm: + webidx.search(self.environ) + self.assertEqual(str(cm.exception), "No such match type: 'testmatch'") diff --git a/tests/test_www/test_taskinfo.py b/tests/test_www/test_taskinfo.py index 286d93f..4648bcb 100644 --- a/tests/test_www/test_taskinfo.py +++ b/tests/test_www/test_taskinfo.py @@ -155,7 +155,7 @@ class TestTaskInfo(unittest.TestCase): with self.assertRaises(koji.GenericError) as cm: webidx.taskinfo(self.environ, self.task_id) self.assertEqual( - str(cm.exception), 'invalid task ID: %s' % self.task_id) + str(cm.exception), 'No such task ID: %s' % self.task_id) def test_taskinfo_getTaskResult_exception(self): """Test taskinfo function with exception raised from getTaskResult""" diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py index 75f6651..5825d15 100644 --- a/www/kojiweb/index.py +++ b/www/kojiweb/index.py @@ -57,7 +57,7 @@ def _validate_arch(arch): elif _VALID_ARCH_RE.match(arch): return arch else: - raise koji.GenericError("Invalid arch: %r" % arch) + raise koji.GenericError("No such arch: %r" % arch) def _validate_name_or_id(value): @@ -632,7 +632,7 @@ def taskinfo(environ, taskID): taskID = int(taskID) task = server.getTaskInfo(taskID, request=True) if not task: - raise koji.GenericError('invalid task ID: %s' % taskID) + raise koji.GenericError('No such task ID: %s' % taskID) values['title'] = koji.taskLabel(task) + ' | Task Info' @@ -940,7 +940,7 @@ def packageinfo(environ, packageID, tagOrder='name', tagStart=None, buildOrder=' packageID = _validate_name_or_id(packageID) package = server.getPackage(packageID) if package is None: - raise koji.GenericError('invalid package ID: %s' % packageID) + raise koji.GenericError('No such package ID: %s' % packageID) values['title'] = package['name'] + ' | Package Info' @@ -1197,7 +1197,7 @@ def buildinfo(environ, buildID): try: build = server.getBuild(buildID, strict=True) except koji.GenericError: - raise koji.GenericError("Invalid build ID: %i" % buildID) + raise koji.GenericError("No such build ID: %i" % buildID) values['title'] = koji.buildLabel(build) + ' | Build Info' @@ -1471,7 +1471,7 @@ def rpminfo(environ, rpmID, fileOrder='name', fileStart=None, buildrootOrder='-i try: rpm = server.getRPM(rpmID, strict=True) except koji.GenericError: - raise koji.GenericError('invalid RPM ID: %i' % rpmID) + raise koji.GenericError('No such RPM ID: %i' % rpmID) values['title'] = '%(name)s-%%s%(version)s-%(release)s.%(arch)s.rpm' % rpm + ' | RPM Info' epochStr = '' @@ -1577,7 +1577,7 @@ def fileinfo(environ, filename, rpmID=None, archiveID=None): rpmID = int(rpmID) rpm = server.getRPM(rpmID) if not rpm: - raise koji.GenericError('invalid RPM ID: %i' % rpmID) + raise koji.GenericError('No such RPM ID: %i' % rpmID) file = server.getRPMFile(rpm['id'], filename) if not file: raise koji.GenericError('no file %s in RPM %i' % (filename, rpmID)) @@ -1586,7 +1586,7 @@ def fileinfo(environ, filename, rpmID=None, archiveID=None): archiveID = int(archiveID) archive = server.getArchive(archiveID) if not archive: - raise koji.GenericError('invalid archive ID: %i' % archiveID) + raise koji.GenericError('No such archive ID: %i' % archiveID) file = server.getArchiveFile(archive['id'], filename) if not file: raise koji.GenericError('no file %s in archive %i' % (filename, archiveID)) @@ -1656,7 +1656,7 @@ def hostinfo(environ, hostID=None, userID=None): hostID = _validate_name_or_id(hostID) host = server.getHost(hostID) if host is None: - raise koji.GenericError('invalid host ID: %s' % hostID) + raise koji.GenericError('No such host ID: %s' % hostID) elif userID: userID = int(userID) hosts = server.listHosts(userID=userID) @@ -1664,7 +1664,7 @@ def hostinfo(environ, hostID=None, userID=None): if hosts: host = hosts[0] if host is None: - raise koji.GenericError('invalid host ID: %s' % userID) + raise koji.GenericError('No such host for user ID: %s' % userID) else: raise koji.GenericError('hostID or userID must be provided') @@ -1767,8 +1767,9 @@ def channelinfo(environ, channelID): channelID = int(channelID) channel = server.getChannel(channelID) + print(channel) if channel is None: - raise koji.GenericError('invalid channel ID: %i' % channelID) + raise koji.GenericError('No such channel ID: %i' % channelID) values['title'] = channel['name'] + ' | Channel Info' @@ -1936,7 +1937,7 @@ def buildtargetinfo(environ, targetID=None, name=None): target = server.getBuildTarget(name) if target is None: - raise koji.GenericError('invalid build target: %s' % (targetID or name)) + raise koji.GenericError('No such build target: %s' % (targetID or name)) values['title'] = target['name'] + ' | Build Target Info' @@ -1962,7 +1963,7 @@ def buildtargetedit(environ, targetID): target = server.getBuildTarget(targetID) if target is None: - raise koji.GenericError('invalid build target: %s' % targetID) + raise koji.GenericError('No such build target: %s' % targetID) form = environ['koji.form'] @@ -1971,12 +1972,12 @@ def buildtargetedit(environ, targetID): buildTagID = int(form.getfirst('buildTag')) buildTag = server.getTag(buildTagID) if buildTag is None: - raise koji.GenericError('invalid tag ID: %i' % buildTagID) + raise koji.GenericError('No such tag ID: %i' % buildTagID) destTagID = int(form.getfirst('destTag')) destTag = server.getTag(destTagID) if destTag is None: - raise koji.GenericError('invalid tag ID: %i' % destTagID) + raise koji.GenericError('No such tag ID: %i' % destTagID) server.editBuildTarget(target['id'], name, buildTag['id'], destTag['id']) @@ -2037,7 +2038,7 @@ def buildtargetdelete(environ, targetID): target = server.getBuildTarget(targetID) if target is None: - raise koji.GenericError('invalid build target: %i' % targetID) + raise koji.GenericError('No such build target: %i' % targetID) server.deleteBuildTarget(target['id']) @@ -2468,7 +2469,7 @@ def search(environ, start=None, order=None): values['match'] = match if match not in ('glob', 'regexp', 'exact'): - raise koji.GenericError("Invalid match type: %r" % match) + raise koji.GenericError("No such match type: %r" % match) if not _VALID_SEARCH_RE.match(terms): values['error'] = 'Invalid search terms
' + \