def test_we_can_know_when_bugsy_is_authenticated_using_apikey(): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/valid_login?login=foo', body='true', status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy(username='******', api_key='goodkey') assert bugzilla.authenticated
def test_we_can_handle_errors_coming_back_from_search(): error_return = { "code": 108, "documentation": "http://www.bugzilla.org/docs/tip/en/html/api/", "error": True, "message": "Can't use [Bug Creation] as a field name." } url_params = dict( chfield=['[Bug Creation]', 'Alias'], chfieldvalue='foo', chfieldfrom='2014-12-01', chfieldto='2014-12-05', ) responses.add(responses.GET, rest_url('bug', **url_params), body=json.dumps(error_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy() try: bugzilla.search_for\ .change_history_fields(['[Bug Creation]', 'Alias'], 'foo')\ .timeframe('2014-12-01', '2014-12-05')\ .search() except SearchException as e: assert str( e ) == "Message: Can't use [Bug Creation] as a field name. Code: 108"
def test_add_attachment(attachment_return, bug_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, rest_url('bug', 1017315), json=bug_return, status=200, content_type='application/json', match_querystring=True) responses.add(responses.POST, 'https://bugzilla.mozilla.org/rest/bug/1017315/attachment', json=attachment_return, status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = bugzilla.get(1017315) attachment = Attachment(bugzilla, **attachment_return['bugs']['1017315'][0]) bug.add_attachment(attachment) assert len(responses.calls) == 3
def test_add_attachment_with_missing_required_fields(attachment_return, bug_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, rest_url('bug', 1017315), json=bug_return, status=200, content_type='application/json', match_querystring=True) responses.add(responses.POST, 'https://bugzilla.mozilla.org/rest/bug/1017315/attachment', json=attachment_return, status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = bugzilla.get(1017315) clone = copy.deepcopy(attachment_return['bugs']['1017315'][0]) del clone['data'] attachment = Attachment(bugzilla, **clone) try: bug.add_attachment(attachment) assert False, "Should have raised a BugException due to add without data" except BugException as e: assert str( e ) == "Message: Cannot add attachment without all required fields Code: None"
def test_we_can_search_for_a_list_of_bug_numbers_with_start_finish_dates(): return_1 = { "bugs": [{ "component": "CSS Parsing and Computation", "product": "Core", "summary": "Map \"rebeccapurple\" to #663399 in named color list." }] } url_params = dict( chfieldfrom='2014-12-01', chfieldto='2014-12-05', ) responses.add(responses.GET, rest_url('bug', **url_params), body=json.dumps(return_1), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy() bugs = bugzilla.search_for\ .timeframe('2014-12-01', '2014-12-05')\ .search() assert len(responses.calls) == 1 assert len(bugs) == 1 assert bugs[0].product == return_1['bugs'][0]['product'] assert bugs[0].summary == return_1['bugs'][0]['summary']
def test_we_can_search_summary_fields(): summary_return = { "bugs": [{ "component": "CSS Parsing and Computation", "product": "Core", "summary": "Map \"rebeccapurple\" to #663399 in named color list." }] } url_params = dict( assigned_to='*****@*****.**', short_desc='rebecca', short_desc_type='allwordssubstr', ) responses.add(responses.GET, rest_url('bug', **url_params), body=json.dumps(summary_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy() bugs = bugzilla.search_for\ .assigned_to('*****@*****.**')\ .summary("rebecca")\ .search() assert len(responses.calls) == 1 assert len(bugs) == 1 assert bugs[0].product == summary_return['bugs'][0]['product'] assert bugs[0].summary == summary_return['bugs'][0]['summary']
def test_comment_retrieval(bug_return, comments_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, rest_url('bug', 1017315), body=json.dumps(bug_return), status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/bug/1017315/comment', body=json.dumps(comments_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = bugzilla.get(1017315) comments = bug.get_comments() assert len(comments) == 2 c1 = comments[0] assert c1.attachment_id is None assert c1.author == u'*****@*****.**' assert c1.bug_id == 1017315 assert c1.creation_time == datetime.datetime(2014, 3, 27, 23, 47, 45) assert c1.creator == u'*****@*****.**' assert c1.id == 8589785 assert c1.is_private is False assert c1.text == u'text 1' assert c1.tags == set([u'tag1', u'tag2']) assert c1.time == datetime.datetime(2014, 3, 27, 23, 47, 45)
def test_we_cant_post_without_a_username_or_password(): bugzilla = Bugsy() try: bugzilla.put("foo") assert 1 == 0, "Should have thrown when calling put" except BugsyException as e: assert str(e) == "Message: Unfortunately you can't put bugs in Bugzilla without credentials Code: None"
def test_that_we_can_add_a_comment_to_a_bug_before_it_is_put(bug_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add( responses.GET, 'https://bugzilla.mozilla.org/rest/bug/1017315?include_fields=version&include_fields=id&include_fields=summary&include_fields=status&include_fields=op_sys&include_fields=resolution&include_fields=product&include_fields=component&include_fields=platform', body=json.dumps(bug_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = Bug() bug.summary = "I like cheese" bug.add_comment("I like sausages") bug_dict = bug.to_dict().copy() bug_dict['id'] = 123123 responses.add(responses.POST, 'https://bugzilla.mozilla.org/rest/bug', body=json.dumps(bug_dict), status=200, content_type='application/json', match_querystring=True) bugzilla.put(bug)
def test_that_we_can_add_a_comment_to_an_existing_bug(bug_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, rest_url('bug', 1017315), body=json.dumps(bug_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = bugzilla.get(1017315) responses.add(responses.POST, 'https://bugzilla.mozilla.org/rest/bug/1017315/comment', body=json.dumps({}), status=200, content_type='application/json', match_querystring=True) bug.add_comment("I like sausages") assert len(responses.calls) == 3
def test_we_can_update_a_bug_with_login_token(bug_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, rest_url('bug', 1017315), body=json.dumps(bug_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy() bug = bugzilla.get(1017315) responses.reset() responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/bug/1017315', body=json.dumps(bug_return), status=200, content_type='application/json') clone = Bug(bugsy=bugzilla, **bug.to_dict()) clone.status = 'NEW' clone.update() assert clone.id == 1017315 assert clone.status == 'RESOLVED'
def test_update_post_required_fields(attachment_return): resp_dict = {'attachments': [{}]} for k, v in attachment_return['bugs']['1017315'][0].items(): if k in Attachment.UPDATE_FIELDS: resp_dict['attachments'][0][k] = copy.deepcopy(v) resp_dict['attachments'][0]['summary'] = 'Updated summary' def request_callback(request): header = {} body = json.dumps(json.loads(request.body), sort_keys=True) if body != json.dumps(resp_dict['attachments'][0], sort_keys=True): return 500, header, "Invalid payload supplied" else: return 200, header, json.dumps(resp_dict) attach_id = attachment_return['bugs']['1017315'][0]['id'] responses.add_callback( responses.PUT, 'https://bugzilla.mozilla.org/rest/bug/attachment/%s' % attach_id, callback=request_callback, content_type='application/json', ) bugzilla = Bugsy() attachment = Attachment(bugzilla, **attachment_return['bugs']['1017315'][0]) attachment.summary = 'Updated summary' attachment.update() assert attachment.summary == 'Updated summary'
def test_we_can_search_whiteboard_fields(): whiteboard_return = { "bugs" : [ { "component" : "Marionette", "product" : "Testing", "summary" : "Tracking bug for uplifting is_displayed issue fix for WebDriver" }, { "component" : "Marionette", "product" : "Testing", "summary" : "Marionette thinks that the play button in the music app is not displayed" } ] } url_params = dict( assigned_to='*****@*****.**', whiteboard='affects', short_desc_type='allwordssubstr', ) responses.add(responses.GET, rest_url('bug', **url_params), body=json.dumps(whiteboard_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy() bugs = bugzilla.search_for\ .assigned_to('*****@*****.**')\ .whiteboard("affects")\ .search() assert len(responses.calls) == 1 assert len(bugs) == 2 assert bugs[0].product == whiteboard_return['bugs'][0]['product'] assert bugs[0].summary == whiteboard_return['bugs'][0]['summary']
def test_that_we_can_search_for_a_specific_user(): user_return = { "bugs" : [ { "product" : "addons.mozilla.org", "summary" : "Add Selenium tests to the repository" }, { "product" : "addons.mozilla.org", "summary" : "Add Ids to links to help with testability" }, { "product" : "addons.mozilla.org", "summary" : "Add a name for AMO Themes sort links for testability" }, { "product" : "addons.mozilla.org", "summary" : "Missing ID for div with class \"feature ryff\" (Mobile Add-on: Foursquare)" } ] } responses.add(responses.GET, rest_url('bug', assigned_to='*****@*****.**'), body=json.dumps(user_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy() bugs = bugzilla.search_for\ .assigned_to('*****@*****.**')\ .search() assert len(responses.calls) == 1 assert len(bugs) == 4 assert bugs[0].product == user_return['bugs'][0]['product'] assert bugs[0].summary == user_return['bugs'][0]['summary']
def test_we_can_remove_tags_to_bug_comments(bug_return, comments_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, rest_url('bug', 1017315), body=json.dumps(bug_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = bugzilla.get(1017315) responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/bug/1017315/comment', body=json.dumps(comments_return), status=200, content_type='application/json', match_querystring=True) comments = bug.get_comments() responses.add(responses.PUT, 'https://bugzilla.mozilla.org/rest/bug/comment/8589785/tags', body=json.dumps(["spam", "foo"]), status=200, content_type='application/json', match_querystring=True) comments[0].remove_tags("foo") assert len(responses.calls) == 4
def test_we_can_get_username_with_userid_cookie(): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/user/1234?token=1234-abcd', body='{"users": [{"name": "*****@*****.**"}]}', status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy(userid='1234', cookie='abcd') assert bugzilla.username == '*****@*****.**'
def test_bug_update_updates_copy_dict(bug_return, comments_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = Bug(bugzilla, **bug_return['bugs'][0]) bug.status = 'NEW' diff = bug.diff() bug_dict = copy.deepcopy(bug_return) bug_dict['bugs'][0]['status'] = 'NEW' responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/bug/1017315', body=json.dumps(bug_dict), status=200, content_type='application/json') responses.add(responses.PUT, 'https://bugzilla.mozilla.org/rest/bug/1017315', body=json.dumps(diff), status=200, content_type='application/json') bugzilla.put(bug) bug.update() assert bug._copy['status'] == 'NEW'
def test_we_can_search_with_change_history_field_throws_when_not_given_a_list( ): return_1 = { "bugs": [{ "component": "CSS Parsing and Computation", "product": "Core", "summary": "Map \"rebeccapurple\" to #663399 in named color list." }] } responses.add( responses.GET, 'https://bugzilla.mozilla.org/rest/bug?chfieldfrom=2014-12-01&chfieldto=2014-12-05&include_fields=version&include_fields=id&include_fields=summary&include_fields=status&include_fields=op_sys&include_fields=resolution&include_fields=product&include_fields=component&include_fields=platform&chfield=[Bug Creation]&chfield=Alias&chfieldvalue=foo', body=json.dumps(return_1), status=200, content_type='application/json', match_querystring=False) try: bugzilla = Bugsy() bugs = bugzilla.search_for\ .change_history_fields('[Bug Creation]', 'foo')\ .timeframe('2014-12-01', '2014-12-05')\ .search() except Exception as e: assert str(e) == "fields should be a list"
def test_attachment_retrieval(attachment_return, bug_return): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, rest_url('bug', 1017315), json=bug_return, status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/bug/1017315/attachment', json=attachment_return, status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = bugzilla.get(1017315) attachments = bug.get_attachments() assert len(attachments) == 1 attachment = attachments[0].to_dict() for k, v in attachment.items(): if k in ['creation_time', 'last_change_time']: orig = attachment_return['bugs']['1017315'][0][k] assert v == datetime.datetime.strptime(orig, '%Y-%m-%dT%H:%M:%SZ') else: orig = attachment_return['bugs']['1017315'][0][k] assert v == orig
def test_we_can_put_a_current_bug(): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) bug_dict = example_return.copy() bug_dict['summary'] = 'I love foo but hate bar' responses.add(responses.PUT, 'https://bugzilla.mozilla.org/rest/bug/1017315', body=json.dumps(bug_dict), status=200, content_type='application/json') responses.add(responses.GET, rest_url('bug', 1017315), body=json.dumps(example_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = Bug(**example_return['bugs'][0]) bug.summary = 'I love foo but hate bar' bug.assigned_to = "*****@*****.**" bugzilla.put(bug) assert bug.summary == 'I love foo but hate bar' assert bug.assigned_to == "*****@*****.**"
def test_bugsyexception_raised_for_http_500_when_commenting_on_a_bug(): responses.add( responses.GET, 'https://bugzilla.mozilla.org/rest/login?login=foo&password=bar', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) responses.add(responses.GET, rest_url('bug', 1017315, token='foobar'), body=json.dumps(example_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = bugzilla.get(1017315) responses.add( responses.POST, 'https://bugzilla.mozilla.org/rest/bug/1017315/comment?token=foobar', body='Internal Server Error', status=500, content_type='text/html', match_querystring=True) with pytest.raises(BugsyException) as e: bug.add_comment("I like sausages") assert str( e.value ) == "Message: We received a 500 error with the following: Internal Server Error Code: None"
def test_we_can_add_multiple_emails_to_cc_list(): bug = None bugzilla = None with responses.RequestsMock() as rsps: rsps.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) rsps.add(responses.GET, rest_url('bug', 1017315), body=json.dumps(example_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") bug = bugzilla.get(1017315) import copy bug_dict = copy.deepcopy(example_return) bug_dict['bugs'][0]['cc_detail'].append({ u'id': 438921, u'email': u'*****@*****.**', u'name': u'[email protected] ', u'real_name': u'AutomatedTester' }) bug_dict['bugs'][0]['cc_detail'].append({ u'id': 438922, u'email': u'*****@*****.**', u'name': u'[email protected] ', u'real_name': u'Foobar' }) updated_bug = None with responses.RequestsMock() as rsps: rsps.add(responses.PUT, 'https://bugzilla.mozilla.org/rest/bug/1017315', body=json.dumps(bug_dict), status=200, content_type='application/json', match_querystring=True) rsps.add(responses.GET, rest_url('bug', 1017315), body=json.dumps(bug_dict), status=200, content_type='application/json', match_querystring=True) bug.cc = ["*****@*****.**", "*****@*****.**"] updated_bug = bugzilla.put(bug) cced = updated_bug.cc assert isinstance(cced, list) assert [ u"*****@*****.**", u"*****@*****.**", u"*****@*****.**", u"*****@*****.**", u"*****@*****.**", u"*****@*****.**" ] == cced
def test_we_only_ask_for_the_include_fields_while_logged_in(): include_return = { "bugs" : [ { "component" : "Marionette", "flags" : [], "id" : 861874, "op_sys" : "Gonk (Firefox OS)", "platform" : "Other", "product" : "Testing", "resolution" : "", "status" : "REOPENED", "summary" : "Tracking bug for uplifting is_displayed issue fix for WebDriver", "version" : "unspecified" }, { "component" : "Marionette", "flags" : [ { "creation_date" : "2013-11-26T14:16:09Z", "id" : 758758, "modification_date" : "2013-11-26T14:16:09Z", "name" : "needinfo", "requestee" : "*****@*****.**", "setter" : "*****@*****.**", "status" : "?", "type_id" : 800 } ], "id" : 862156, "op_sys" : "Gonk (Firefox OS)", "platform" : "ARM", "product" : "Testing", "resolution" : "", "status" : "NEW", "summary" : "Marionette thinks that the play button in the music app is not displayed", "version" : "unspecified" } ] } responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) url_params = dict( include_fields=Bugsy.DEFAULT_SEARCH + ['flags'], ) responses.add(responses.GET, rest_url('bug', **url_params), body=json.dumps(include_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy('foo', 'bar') bugs = bugzilla.search_for\ .include_fields('flags')\ .search() assert len(responses.calls) == 2 assert len(bugs) == 2 assert bugs[0].product == include_return['bugs'][0]['product']
def test_validate_api_key(): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/valid_login?login=foo', body='true', status=200, content_type='application/json', match_querystring=True) Bugsy(username='******', api_key='goodkey') assert (responses.calls[0].request.headers['X-Bugzilla-API-Key'] == 'goodkey')
def test_init(attachment_return): bugzilla = Bugsy() source = attachment_return['bugs']['1017315'][0] attachment = Attachment(bugzilla, **source) attach_dict = attachment.to_dict() for k in attachment_return['bugs']['1017315'][0]: if k in ['creation_time', 'last_change_time']: continue assert attach_dict[k] == source[k]
def test_we_get_a_login_exception_when_details_are_wrong(): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login?login=foo&password=bar', body='{"message": "The username or password you entered is not valid."}', status=400, content_type='application/json', match_querystring=True) try: Bugsy("foo", "bar") assert 1 == 0, "Should have thrown an error" except LoginException as e: assert str(e) == "Message: The username or password you entered is not valid. Code: None"
def test_we_can_get_a_bug(): responses.add(responses.GET, rest_url('bug', 1017315), body=json.dumps(example_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy() bug = bugzilla.get(1017315) assert bug.id == 1017315 assert bug.status == 'RESOLVED' assert bug.summary == 'Schedule Mn tests on opt Linux builds on cedar'
def test_we_can_set_the_user_agent_to_bugsy(): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) Bugsy("foo", "bar") assert responses.calls[0].request.headers['User-Agent'] == "Bugsy"
def test_we_can_know_when_bugsy_is_authenticated_using_password(): responses.add(responses.GET, 'https://bugzilla.mozilla.org/rest/login', body='{"token": "foobar"}', status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy("foo", "bar") assert bugzilla.authenticated
def test_we_can_search_components(): include_return = { "bugs" : [ { "component" : "Marionette", "flags" : [], "id" : 861874, "op_sys" : "Gonk (Firefox OS)", "platform" : "Other", "product" : "Testing", "resolution" : "", "status" : "REOPENED", "summary" : "Tracking bug for uplifting is_displayed issue fix for WebDriver", "version" : "unspecified" }, { "component" : "Marionette", "flags" : [ { "creation_date" : "2013-11-26T14:16:09Z", "id" : 758758, "modification_date" : "2013-11-26T14:16:09Z", "name" : "needinfo", "requestee" : "*****@*****.**", "setter" : "*****@*****.**", "status" : "?", "type_id" : 800 } ], "id" : 862156, "op_sys" : "Gonk (Firefox OS)", "platform" : "ARM", "product" : "Testing", "resolution" : "", "status" : "NEW", "summary" : "Marionette thinks that the play button in the music app is not displayed", "version" : "unspecified" } ] } url_params = dict( component="Marionette" ) responses.add(responses.GET, rest_url('bug', **url_params), body=json.dumps(include_return), status=200, content_type='application/json', match_querystring=True) bugzilla = Bugsy() bugs = bugzilla.search_for\ .component('Marionette')\ .search() assert len(responses.calls) == 1 assert len(bugs) == 2 assert bugs[0].to_dict()['flags'] == include_return['bugs'][0]['flags']