summaryrefslogtreecommitdiff
path: root/tests/test_debianbts.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_debianbts.py')
-rw-r--r--tests/test_debianbts.py444
1 files changed, 444 insertions, 0 deletions
diff --git a/tests/test_debianbts.py b/tests/test_debianbts.py
new file mode 100644
index 0000000..86d75ea
--- /dev/null
+++ b/tests/test_debianbts.py
@@ -0,0 +1,444 @@
+import datetime
+import email.message
+import math
+import logging
+import unittest.mock as mock
+
+import pytest
+
+from pysimplesoap.simplexml import SimpleXMLElement
+
+import debianbts as bts
+
+logger = logging.getLogger(__name__)
+
+
+@pytest.fixture
+def create_bugreport():
+ def factory(**kwargs):
+ bugreport = bts.Bugreport()
+ bugreport.severity = 'normal'
+ for k, v in kwargs.items():
+ setattr(bugreport, k, v)
+ return bugreport
+ return factory
+
+
+def test_get_usertag_empty():
+ """get_usertag should return empty dict if no bugs are found."""
+ d = bts.get_usertag("thisisatest@debian.org")
+ assert d == dict()
+
+
+def test_get_usertag():
+ """get_usertag should return dict with tag(s) and buglist(s)."""
+ d = bts.get_usertag("debian-python@lists.debian.org")
+ assert isinstance(d, dict)
+ for k, v in d.items():
+ assert isinstance(k, str)
+ assert isinstance(v, list)
+ for bug in v:
+ assert isinstance(bug, int)
+
+
+def test_get_usertag_filters():
+ """get_usertag should return only requested tags"""
+ tags = bts.get_usertag("debian-python@lists.debian.org")
+ assert isinstance(tags, dict)
+ randomKey0 = list(tags.keys())[0]
+ randomKey1 = list(tags.keys())[1]
+
+ filtered_tags = bts.get_usertag(
+ "debian-python@lists.debian.org", randomKey0, randomKey1)
+
+ assert len(filtered_tags) == 2
+ assert set(filtered_tags[randomKey0]) == set(tags[randomKey0])
+ assert set(filtered_tags[randomKey1]) == set(tags[randomKey1])
+
+
+def test_get_usertag_args(caplog):
+ # no tags
+ tags = bts.get_usertag("debian-python@lists.debian.org")
+ assert len(tags) > 2
+
+ randomKey0 = list(tags.keys())[0]
+ randomKey1 = list(tags.keys())[1]
+
+ # one tags
+ tags = bts.get_usertag("debian-python@lists.debian.org",
+ [randomKey0])
+ assert len(tags) == 1
+
+ # two tags
+ tags = bts.get_usertag("debian-python@lists.debian.org",
+ [randomKey0, randomKey1])
+ assert len(tags) == 2
+
+ # deprecated positional arguments
+ tags = bts.get_usertag("debian-python@lists.debian.org",
+ randomKey0, randomKey1)
+ assert len(tags) == 2
+ assert "deprecated" in caplog.text
+
+
+def test_get_bugs_empty(caplog):
+ """get_bugs should return empty list if no matching bugs where found."""
+ bugs = bts.get_bugs(package="thisisatest")
+ assert bugs == []
+
+ bugs = bts.get_bugs("package", "thisisatest")
+ assert bugs == []
+ assert "deprecated" in caplog.text
+
+
+def test_get_bugs(caplog):
+ """get_bugs should return list of bugnumbers."""
+ bugs = bts.get_bugs(submitter="venthur@debian.org")
+ assert len(bugs) != 0
+ assert isinstance(bugs, list)
+ for i in bugs:
+ assert isinstance(i, int)
+
+ bugs = bts.get_bugs("submitter", "venthur@debian.org")
+ assert len(bugs) != 0
+ assert isinstance(bugs, list)
+ for i in bugs:
+ assert isinstance(i, int)
+ assert "deprecated" in caplog.text
+
+
+def test_get_bugs_list(caplog):
+ """older versions of python-debianbts accepted malformed key-val-lists."""
+ bugs = bts.get_bugs(submitter='venthur@debian.org',
+ severity='normal')
+ assert len(bugs) != 0
+
+ bugs = bts.get_bugs(
+ 'submitter',
+ 'venthur@debian.org',
+ 'severity',
+ 'normal')
+ bugs2 = bts.get_bugs(
+ ['submitter', 'venthur@debian.org', 'severity', 'normal'])
+ assert len(bugs) != 0
+ bugs.sort()
+ bugs2.sort()
+ assert bugs == bugs2
+ assert "deprecated" in caplog.text
+
+
+def test_newest_bugs():
+ """newest_bugs should return list of bugnumbers."""
+ bugs = bts.newest_bugs(10)
+ assert isinstance(bugs, list)
+ for i in bugs:
+ assert isinstance(i, int)
+
+
+def test_newest_bugs_amount():
+ """newest_bugs(amount) should return a list of len 'amount'. """
+ for i in 0, 1, 10:
+ bugs = bts.newest_bugs(i)
+ assert len(bugs) == i
+
+
+def test_get_bug_log():
+ """get_bug_log should return the correct data types."""
+ bl = bts.get_bug_log(223344)
+ assert isinstance(bl, list)
+ for i in bl:
+ assert isinstance(i, dict)
+ assert "attachments" in i
+ assert isinstance(i["attachments"], list)
+ assert "body" in i
+ assert isinstance(i["body"], str)
+ assert "header" in i
+ assert isinstance(i["header"], str)
+ assert "msg_num" in i
+ assert isinstance(i["msg_num"], int)
+
+
+def test_get_bug_log_with_attachments():
+ """get_bug_log should include attachments"""
+ buglogs = bts.get_bug_log(400000)
+ for bl in buglogs:
+ assert "attachments" in bl
+
+
+def test_bug_log_message():
+ """dict returned by get_bug_log has a email.Message field"""
+ buglogs = bts.get_bug_log(400012)
+ for buglog in buglogs:
+ assert 'message' in buglog
+ msg = buglog['message']
+ assert isinstance(msg, email.message.Message)
+ assert 'Subject' in msg
+ if not msg.is_multipart():
+ assert isinstance(msg.get_payload(), str)
+
+
+def test_bug_log_message_unicode():
+ """test parsing of bug_log mail with non ascii characters"""
+ buglogs = bts.get_bug_log(773321)
+ buglog = buglogs[2]
+ msg_payload = buglog['message'].get_payload()
+ assert isinstance(msg_payload, str)
+ assert 'é' in msg_payload
+
+
+def test_empty_get_status():
+ """get_status should return empty list if bug doesn't exits"""
+ bugs = bts.get_status(0)
+ assert isinstance(bugs, list)
+ assert len(bugs) == 0
+
+
+def test_get_status_params(caplog):
+ BUG = 223344
+ BUG2 = 334455
+
+ bugs = bts.get_status(BUG)
+ assert isinstance(bugs, list)
+ assert len(bugs) == 1
+
+ bugs = bts.get_status([BUG, BUG2])
+ assert isinstance(bugs, list)
+ assert len(bugs) == 2
+
+ bugs = bts.get_status((BUG, BUG2))
+ assert isinstance(bugs, list)
+ assert len(bugs) == 2
+
+ bugs = bts.get_status(BUG, BUG2)
+ assert isinstance(bugs, list)
+ assert len(bugs) == 2
+ assert "deprecated" in caplog.text
+
+
+def test_sample_get_status():
+ """test retrieving of a "known" bug status"""
+ bugs = bts.get_status(486212)
+ assert len(bugs) == 1
+ bug = bugs[0]
+ assert bug.bug_num == 486212
+ assert bug.date == datetime.datetime(2008, 6, 14, 10, 30, 2)
+ assert bug.subject.startswith('[reportbug-ng] segm')
+ assert bug.package == 'reportbug-ng'
+ assert bug.severity == 'normal'
+ assert bug.tags == ['help']
+ assert bug.blockedby == []
+ assert bug.blocks == []
+ assert bug.summary == ''
+ assert bug.location == 'archive'
+ assert bug.source == 'reportbug-ng'
+ assert bug.log_modified == datetime.datetime(2008, 8, 17, 7, 26, 22)
+ assert bug.pending == 'done'
+ assert bug.done
+ assert bug.done_by == 'Bastian Venthur <venthur@debian.org>'
+ assert bug.archived
+ assert bug.found_versions == ['reportbug-ng/0.2008.06.04']
+ assert bug.fixed_versions == ['reportbug-ng/1.0']
+ assert bug.affects == []
+
+
+def test_done_by_decoding():
+ """Done by is properly base64 decoded when needed."""
+ # no base64 encoding
+ bug = bts.get_status(486212)[0]
+ assert bug.done_by == 'Bastian Venthur <venthur@debian.org>'
+
+ # base64 encoding
+ bug = bts.get_status(938128)[0]
+ assert bug.done_by == 'Ondřej Nový <onovy@debian.org>'
+
+
+def test_bug_str(create_bugreport):
+ """test string conversion of a Bugreport"""
+ b1 = create_bugreport(package='foo-pkg', bug_num=12222)
+ s = str(b1)
+ assert isinstance(s, str) # byte string in py2, unicode in py3
+ assert 'bug_num: 12222\n' in s
+ assert 'package: foo-pkg\n' in s
+
+
+def test_get_status_affects():
+ """test a bug with "affects" field"""
+ bugs = bts.get_status(290501, 770490)
+ assert len(bugs) == 2
+ assert bugs[0].affects == []
+ assert bugs[1].affects == ['conkeror']
+
+
+@mock.patch.object(bts.debianbts, '_build_soap_client')
+def test_status_batches_large_bug_counts(mock_build_client):
+ """get_status should perform requests in batches to reduce server load."""
+ mock_build_client.return_value = mock_client = mock.Mock()
+ mock_client.call.return_value = SimpleXMLElement(
+ '<a><s-gensym3/></a>')
+ nr = bts.BATCH_SIZE + 10.0
+ calls = int(math.ceil(nr / bts.BATCH_SIZE))
+ bts.get_status([722226] * int(nr))
+ assert mock_client.call.call_count == calls
+
+
+@mock.patch.object(bts.debianbts, '_build_soap_client')
+def test_status_batches_multiple_arguments(mock_build_client):
+ """get_status should batch multiple arguments into one request."""
+ mock_build_client.return_value = mock_client = mock.Mock()
+ mock_client.call.return_value = SimpleXMLElement(
+ '<a><s-gensym3/></a>')
+ batch_size = bts.BATCH_SIZE
+
+ calls = 1
+ bts.get_status(*list(range(batch_size)))
+ assert mock_client.call.call_count == calls
+
+ calls += 2
+ bts.get_status(*list(range(batch_size + 1)))
+ assert mock_client.call.call_count == calls
+
+
+def test_comparison(create_bugreport):
+ """comparison of two bugs"""
+ b1 = create_bugreport(archived=True)
+ b2 = create_bugreport(done=True)
+ assert b2 > b1
+ assert b2 >= b1
+ assert b2 != b1
+ assert not(b2 == b1)
+ assert not(b2 <= b1)
+ assert not(b2 < b1)
+
+
+def test_comparison_equal(create_bugreport):
+ """comparison of two bug which are equal regarding their
+ relative order"""
+ b1 = create_bugreport(done=True)
+ b2 = create_bugreport(done=True)
+ assert not(b2 > b1)
+ assert b2 >= b1
+ assert b2 == b1
+ assert not(b2 < b1)
+ assert b2 <= b1
+
+
+def test_get_bugs_int_bugs():
+ """It is possible to pass a list of bug number to get_bugs"""
+ bugs = bts.get_bugs('bugs', [400010, 400012], 'archive', '1')
+ assert set(bugs) == set((400010, 400012))
+
+
+def test_get_bugs_single_int_bug():
+ """bugs parameter in get_bugs can be a list of int or a int"""
+ bugs1 = bts.get_bugs('bugs', 400040, 'archive', '1')
+ bugs2 = bts.get_bugs('bugs', [400040], 'archive', '1')
+ assert bugs1 == bugs2
+
+
+def test_get_bugs_archived():
+ """archive tristate."""
+ # the parameter is rather undocumented. with trial and error i found
+ # out that it takes a string with those three values. everything
+ # else will be interpreted as "1"
+ bugs_unarchived = bts.get_bugs(src='python-debianbgs', archive='0')
+ bugs_archived = bts.get_bugs(src='python-debianbgs', archive='1')
+ bugs_both = bts.get_bugs(src='python-debianbgs', archive='both')
+ assert len(bugs_both) == len(bugs_unarchived) + len(bugs_archived)
+
+
+def test_get_bugs_archived_default():
+ """Return un-archived bugs by default."""
+ bugs_unarchived = bts.get_bugs(src='python-debianbgs', archive='0')
+ bugs_default = bts.get_bugs(src='python-debianbgs')
+ assert len(bugs_default) == len(bugs_unarchived)
+
+
+def test_mergedwith():
+ """Mergedwith is always a list of int."""
+ # this one is merged with two other bugs
+ m = bts.get_status(486212)[0].mergedwith
+ assert len(m) == 2
+ for i in m:
+ assert isinstance(i, int)
+ # this one was merged with one bug
+ m = bts.get_status(433550)[0].mergedwith
+ assert len(m) == 1
+ assert isinstance(m[0], int)
+ # this one was not merged
+ m = bts.get_status(474955)[0].mergedwith
+ assert m == list()
+
+
+def test_base64_status_fields():
+ """fields in bug status are sometimes base64-encoded"""
+ bug = bts.get_status(711111)[0]
+ assert isinstance(bug.originator, str)
+ assert bug.originator.endswith('gmail.com>')
+ assert 'ł' in bug.originator
+
+
+def test_base64_buglog_body():
+ """buglog body is sometimes base64 encoded"""
+ buglog = bts.get_bug_log(773321)
+ body = buglog[2]['body']
+ assert isinstance(buglog[1]['body'], str)
+ assert 'é' in body
+
+
+def test_string_status_originator():
+ """test reading of bug status originator that is not base64-encoded"""
+ bug = bts.get_status(711112)[0]
+ assert isinstance(bug.originator, str)
+ assert bug.originator.endswith('debian.org>')
+
+
+def test_unicode_conversion_in_str():
+ """string representation must deal with unicode correctly."""
+ [bug] = bts.get_status(773321)
+ bug.__str__()
+
+
+def test_regression_588954():
+ """Get_bug_log must convert the body correctly to unicode."""
+ bts.get_bug_log(582010)
+
+
+def test_version():
+ assert isinstance(bts.__version__, str)
+
+
+def test_regression_590073():
+ """bug.blocks is sometimes a str sometimes an int."""
+ # test the int case
+ # TODO: test the string case
+ bts.get_status(568657)
+
+
+def test_regression_590725():
+ """bug.body utf sometimes contains invalid continuation bytes."""
+ bts.get_bug_log(578363)
+ bts.get_bug_log(570825)
+
+
+def test_regression_670446():
+ """affects should be split by ','"""
+ bug = bts.get_status(657408)[0]
+ assert bug.affects == ['epiphany-browser-dev', 'libwebkit-dev']
+
+
+def test_regression_799528():
+ """fields of buglog are sometimes base64 encoded."""
+ # bug with base64 encoding originator
+ [bug] = bts.get_status(711111)
+ assert 'ł' in bug.originator
+ # bug with base64 encoding subject
+ [bug] = bts.get_status(779005)
+ assert '‘' in bug.subject
+
+
+def test_regression_917165():
+ bts.get_bug_log(887978)
+
+
+def test_regression_917258():
+ bts.get_bug_log(541147)