def test_sad_graceful_fail_on_attempt_to_create_issue_with_invalid_sprint_value( ): """ gracefully fail on an attempt to create a JIRA Story with a non-valid Sprint value """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = { "Summary": "Recombinant DNA faulty with respect to distal remortix", "Sprint": 329007 } with py.test.raises(JiraProxyError) as excinfo: jp.createIssue(AGL_PROJECT, "Story", work_item) actualErrorMessage = excErrorMessage(excinfo) assert re.search(r"Sprint (does not|doesn't) exist", actualErrorMessage)
def test_sad_refuse_create_when_attempt_to_supply_comment(): """ should not be able to create a Comment at issue creation """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = { "Summary": "bowling alley decor", "Comment": "Green Bowling balls suck." } with py.test.raises(JiraIssueError) as excinfo: jp.createIssue(PROJECT_KEY_1, "Bug", work_item) actualErrorMessage = excErrorMessage(excinfo) assert r'Unrecognized field |Comment|' in actualErrorMessage
def test_create_story_with_original_estimate_field_set(): """ create a new JIRA Story with the OriginalEstimate field value set """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = { "Summary": 'Units of hard labor required to spring ex-presidential candidates from prison', # "timetracking" : {'originalEstimate' : '4m 2w 3d'} } "timetracking": { 'originalEstimate': '6w 2d 4h' } } issue_key = jp.createIssue(PROJECT_KEY_1, "Story", work_item) issue_key_patt = re.compile(f'^{PROJECT_KEY_1}-\\d+') assert issue_key_patt.match(issue_key) story_issue = jp.getIssue(issue_key) #print( story_issue.attributes ) #print( "Issue: #{issue_key} Summary: #{story_issue['Summary']}" ) #print( "timeestimate: #{story_issue.timeestimate}" ) #print( "timeoriginalestimate: #{story_issue.timeoriginalestimate}" ) #print( "---------------------------------------------" ) #print( "Time Tracking: #{story_issue['Time Tracking']}" ) #print( "---------------------------------------------" ) #print( "Time Tracking: -> originalEstimate #{story_issue['Time Tracking']['originalEstimate']}" ) assert story_issue['Time Tracking']['originalEstimate'] == "6w 2d 4h" assert jp.deleteIssue(issue_key)
def test_update_original_estimate_field(): """ create an issue without originalEstimate and later update it with originalEstimate """ original_estimate = '2d 4h' remaining_estimate = '2d 6h' jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = {"Summary": "Another Blustery Day"} issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) issue = jp.getIssue(issue_key) assert issue['Time Tracking'] == {} issue['Time Tracking'] = {'originalEstimate': original_estimate} # don't try this: # issue['Time Tracking']['originalEstimate'] = original_estimate # It will not work and you will be sad and you will gnash your teeth... assert jp.updateIssue(issue) == True issueAgain = jp.getIssue(issue_key) assert issueAgain['Time Tracking']['originalEstimate'] == original_estimate assert issueAgain['Time Tracking'][ 'remainingEstimate'] == original_estimate # you have to set the whole 'Time Tracking' item so that the originalEstimate is not overwritten issue['Time Tracking'] = { 'originalEstimate': original_estimate, 'remainingEstimate': remaining_estimate } assert jp.updateIssue(issue) == True issueAgain = jp.getIssue(issue_key) assert issueAgain['Time Tracking']['originalEstimate'] == original_estimate assert issueAgain['Time Tracking'][ 'remainingEstimate'] == remaining_estimate assert jp.deleteIssue(issue_key)
def test_create_issue_with_non_default_priority_and_version_and_component_values( ): """ create a JIRA issue with non-default priority value along with version and components values """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = {'Summary' : "stuck vontracular relay caused moribundal shudders " + \ "while accelerative mode shunt activated", 'Reporter' : "testuser", 'Assignee' : "devuser", 'Description' : "ice blocks whizzed dangerously close to several portholes", #"Priority" : "Critical", # in Jira6 "Priority" : "High", 'Due Date' : "2020-09-20", 'Environment' : "Screaming 60's", 'Affects Version/s' : "vanilla", #'fixversions' : "lemon", 'Fix Version/s' : "cherry, peach", 'Component/s' : "Routing" # not required, must be in list of allowedValues, } issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) issue_key_patt = re.compile(f'^{PROJECT_KEY_1}-\\d+') assert issue_key_patt.match(issue_key) assert jp.deleteIssue(issue_key)
def test_transition_bug_to_resolved_state(): """ transition an ON_DEMAND instance Bug in the 'RW' project to Resolved """ """ jp = JiraProxy(GOOD_VANILLA_SERVER_DEV_USER_CONFIG) work_item = {"Summary" : "Benkmeister Fullmore writez stuff"} issue_key = jp.createIssue(PROJECT_KEY_4, "Bug", work_item) jp.transitionIssueState(issue_key, "Released", "Done" ) issue = jp.getIssue(issue_key) assert issue.Status == "Released" assert issue.Resolution == "Done" assert jp.deleteIssue(issue_key) """ jp = JiraProxy(GOOD_VANILLA_ONDEMAND_CONFIG) work_item = {"Summary" : "Benkmeister Fullmore writez stuff"} issue_key = jp.createIssue(PROJECT_KEY_4, "Bug", work_item) jp.transitionIssueState(issue_key, "Resolved", "Done" ) issue = jp.getIssue(issue_key) assert issue.Status == "Resolved" assert issue.Resolution == "Done" assert jp.deleteIssue(issue_key)
def test_transition_new_issue_to_resolved_state_with_reso_in_restrictive_workflow(): """ transition a new issue to the Resolved state with a resolution in restrictive workflow """ jp = JiraProxy(GOOD_VANILLA_ONDEMAND_CONFIG) work_item = {"Summary" : "Daytime TV spokesdroid says Be Sassy!"} issue_key = jp.createIssue(PROJECT_KEY_4, "Bug", work_item) jp.transitionIssueState(issue_key, "Resolved", "Cannot Reproduce") issue = jp.getIssue(issue_key) assert issue.Status == "Resolved" assert issue.Resolution == "Cannot Reproduce" jp.transitionIssueState(issue_key, "Reopened") issue = jp.getIssue(issue_key) assert issue.Status == "Reopened" jp.transitionIssueState(issue_key, "Closed", "Fixed") # for ON_DEMAND issue = jp.getIssue(issue_key) assert issue.Status == "Closed" jp.transitionIssueState(issue_key, "Reopened") issue = jp.getIssue(issue_key) assert issue.Status == "Reopened" jp.transitionIssueState(issue_key, "Resolved") issue = jp.getIssue(issue_key) assert issue.Status == "Resolved" assert jp.deleteIssue(issue_key)
def test_create_issue_with_several_custom_fields(): """ create a JIRA issue with several custom fields set """ #jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) jp = JiraProxy(GOOD_VANILLA_ONDEMAND_CONFIG) work_item = { "Summary": "potash deposit extraction shifting towards foreign suppliers", # "Reporter" : "testuser", # "Assignee" : "devuser", #"Priority" : "Lowest", "Severity": "Cosmetic", "RallyID": 123453532, #"Rally Creation Date" : "2001-01-04T01:45:17" #"Rally Creation Date" : "Earth Day" #"RallyProject" : "Burnside Barbers", } issue_key = jp.createIssue(OD_PROJECT_KEY_1, "Bug", work_item) issue_key_patt = re.compile(f'^{OD_PROJECT_KEY_1}-\\d+') assert issue_key_patt.match(issue_key) assert jp.deleteIssue(issue_key)
def test_update_with_non_default_priority_and_versions_components_fields(): """ create a JIRA issue and then update it with non-default priority value along with version and components values """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = { 'Summary': "stuck vontracular relay caused moribundal" " shudders while accelerative mode shunt activated", 'Reporter': GOOD_VANILLA_SERVER_CONFIG['user'], 'Assignee': JIRA_DEV_USER, 'Description': "ice blocks whizzed dangerously close to several portholes", 'Due Date': "2016-02-20", 'Environment': "Screaming 60's", 'Affects Version/s': "cherry", #'Fix Version/s' : "lemon", #'Fix Version/s' : "cherry, peach", #'Components' : "Routing" # not required, must be in list of allowedValues, } issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) issue = jp.getIssue(issue_key) issue["Priority"] = "Highest" issue["Affects Version/s"] = "vanilla,peach" jp.updateIssue(issue) issue = jp.getIssue(issue_key) assert issue.Priority == "Highest" assert set(issue["Affects Version/s"]) == set(["vanilla", "peach"]) assert jp.deleteIssue(issue_key)
def test_update_several_custom_fields(): """ create a JIRA issue and update several custom fields """ #jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) jp = JiraProxy(GOOD_VANILLA_ONDEMAND_CONFIG) work_item = { "Summary": "potash deposit extraction shifting towards foreign suppliers", #"Reporter" : GOOD_VANILLA_SERVER_CONFIG['user'], "Assignee": JIRA_DEV_USER, "Priority": "Lowest", "Severity": "Cosmetic", "RallyID": 123453532, "Support Review Date": '2021-12-14T11:28:45', 'RallyLink': 'https://rally1.rallydev.com/slm/detail/3243432' } issue_key = jp.createIssue(OD_PROJECT_KEY_1, "Bug", work_item) issue = jp.getIssue(issue_key) issue.RallyItem = "S879324" issue.RallyID = 9883990192 issue["Support Review Date"] = "2021-02-13T15:43:30" assert jp.updateIssue(issue) == True issue = jp.getIssue(issue_key) assert issue.RallyItem == "S879324" assert issue.RallyID == 9883990192 assert '2021-02-13T' in issue["Support Review Date"] assert jp.deleteIssue(issue_key)
def test_sad_issue_create_with_invalid_project(): """ raises an error on attempt to create a minimal JIRA issue via the createIssue method using an invalid project identifier """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = {"Summary": "kindergarten hopscotch games"} with py.test.raises(JiraProxyError) as excinfo: issue_key = jp.createIssue(BAD_PROJECT_KEY_1, "Bug", work_item) actualErrorMessage = excErrorMessage(excinfo) assert 'Could not find project for identifier:' in actualErrorMessage
def test_transition_new_issue_to_Closed_state_without_resolution_in_restrictive_workflow(): """ transition a new issue to Closed state without a resolution in restrictive workflow """ jp = JiraProxy(GOOD_VANILLA_ONDEMAND_CONFIG) work_item = {"Summary" : "Your life is an insult to the galaxy", "Priority" : "Highest"} issue_key = jp.createIssue(PROJECT_KEY_4, "Bug", work_item) jp.transitionIssueState(issue_key, "Closed") issue = jp.getIssue(issue_key) assert issue.Status == "Closed" assert jp.deleteIssue(issue_key)
def test_create_bug_with_multiple_affects_version_values(): """ create a new Jira Bug with a multiple valid Affects Version/s values """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) item_data = {'Summary' : 'Narrow morbid futons for sales', 'Affects Version/s' : 'apple,lime' } issue_key = jp.createIssue(PROJECT_KEY_1, 'Bug', item_data) issue = jp.getIssue(issue_key) assert set(issue['Affects Version/s']) == set(['apple', 'lime'])
def test_create_bug_with_single_affects_version_value(): """ create a new Jira Bug with a single valid Affects Version/s value """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) item_data = {'Summary' : 'Narrow morbid futons for sales', 'Affects Version/s' : 'orange' } issue_key = jp.createIssue(PROJECT_KEY_1, 'Bug', item_data) issue = jp.getIssue(issue_key) assert issue['Affects Version/s'] == ['orange']
def test_create_bug_with_target_release_value(): """ create a new Jira Bug with a valid Target Release value """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) item_data = {'Summary' : 'Archery nomads on a rampage for doilies', 'Target Release' : 'lime' } issue_key = jp.createIssue(PROJECT_KEY_1, 'Bug', item_data) issue = jp.getIssue(issue_key) assert issue['Target Release'] == 'lime'
def test_create_new_issue_via_on_demand_connection(): """ create a minimal JIRA issue via the createIssue method over https """ jp = JiraProxy(GOOD_VANILLA_ONDEMAND_CONFIG) work_item = {"Summary" : "kindergarten hopscotch games"} issue_key = jp.createIssue(ON_DEMAND_PROJECT_KEY_1, "Bug", work_item) issue_key_patt = re.compile(f'{ON_DEMAND_PROJECT_KEY_1}-\\d+') assert issue_key_patt.search(issue_key) is not None jp.deleteIssue(issue_key)
def test_minimal_create_with_valid_project(): """ should create a minimal JIRA issue via the createIssue method when given valid project name """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = {"Summary": "kindergarten hopscotch games"} issue_key = jp.createIssue(PROJECT_NAME_1, "Bug", work_item) issue_key_patt = re.compile(f'^{PROJECT_KEY_1}-\\d+') assert issue_key_patt.match(issue_key) assert jp.deleteIssue(issue_key)
def test_transition_newly_created_issue_to_resolved_state_with_a_resolution(): """ transition a newly created issue to the Resolved state with a resolution """ jp = JiraProxy(GOOD_VANILLA_SERVER_DEV_USER_CONFIG) work_item = {"Summary" : "Roller Coaster assembly point"} issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) jp.transitionIssueState(issue_key, "Done") issue = jp.getIssue(issue_key) assert issue.Status == "Done" assert issue.Resolution == "Done" assert jp.deleteIssue(issue_key)
def test_decent_error_message_for_getComments_when_issue_key_nonexistent(): """ Error message should be useful when key does nt exist in getComments """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = {"Summary": "Comments about games."} issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) jp.deleteIssue(issue_key) with py.test.raises(JiraProxyError) as excinfo: jp.getComments(issue_key) actualErrorMessage = excErrorMessage(excinfo) assert 'Issue Does Not Exist' in actualErrorMessage
def test_transition_new_issue_to_resolved_state_without_resolution_in_restrictive_workflow(): """ transition a new issue to Resolved state without a resolution in restrictive workflow """ jp = JiraProxy(GOOD_VANILLA_ONDEMAND_CONFIG) work_item = {"Summary" : "Don't be sassy with me!"} issue_key = jp.createIssue(PROJECT_KEY_4, "Bug", work_item) jp.transitionIssueState(issue_key, "Resolved") issue = jp.getIssue(issue_key) assert issue.Status == "Resolved" assert issue.Resolution is None assert jp.deleteIssue(issue_key)
def test_transition_newly_created_issue_to_closed_state_in_restricted_workflow(): """ transition a newly created issue to the Closed state in restricted workflow """ jp = JiraProxy(GOOD_VANILLA_ONDEMAND_CONFIG) work_item = {"Summary" : "Hand Grenades and horseshoes"} issue_key = jp.createIssue(PROJECT_KEY_4, "Bug", work_item) jp.transitionIssueState(issue_key, "Closed", "Won't Do") issue = jp.getIssue(issue_key) assert issue.Status == "Closed" assert issue.Resolution == "Won't Do" assert jp.deleteIssue(issue_key)
def test_create_story_setting_one_value_for_label(): """ create a JIRA New Story issue that sets one label standard field """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = {"Summary": 'Labels of one state', "Labels": 'Confusion'} issue_key = jp.createIssue(PROJECT_KEY_1, "Story", work_item) issue_key_patt = re.compile(f'^{PROJECT_KEY_1}-\\d+') assert issue_key_patt.match(issue_key) story_issue = jp.getIssue(issue_key) assert story_issue['Labels'] == "Confusion" assert jp.deleteIssue(issue_key)
def test_disallow_adding_a_blank_comment(): """ should be not be able to add a blank comment with the addComment method. """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) work_item = {"Summary": "Comments about games."} issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) comment_1 = "" with py.test.raises(JiraProxyError) as excinfo: jp.addComment(issue_key, comment_1) actualErrorMessage = excErrorMessage(excinfo) assert 'Comment body can not be empty!' in actualErrorMessage assert jp.deleteIssue(issue_key)
def test_error_on_attempt_to_transition_new_issue_to_in_progress_state_with_a_resolution(): """ error out on an attempt transition a newly created issue to the In Progress state with a resolution """ jp = JiraProxy(GOOD_VANILLA_SERVER_DEV_USER_CONFIG) work_item = {"Summary" : "Roller Coaster assembly point"} issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) with py.test.raises(JiraProxyError) as excinfo: jp.transitionIssueState(issue_key, "In Progress", "Won't Do") actualErrorMessage = excErrorMessage(excinfo) assert 'resolution' in actualErrorMessage assert jp.deleteIssue(issue_key)
def disable_test_resolution_attribute_uses_display_name_when_configured_to_use_custom_restrictive_workflow(): """ Resolution attribute uses Display Name when Jira is configured to use a custom workflow that is more restrictive than the simplified default workflow """ jp = JiraProxy(GOOD_VANILLA_SERVER_DEV_USER_CONFIG) work_item = {"Summary" : "Roller Coaster scream tester"} issue_key = jp.createIssue(PROJECT_KEY_4, "Bug", work_item) jp.transitionIssueState(issue_key, "Resolved", "Won't Do" ) issue = jp.getIssue(issue_key) assert issue.Status == "Resolved" assert issue.Resolution == "Won't Do" assert jp.deleteIssue(issue_key)
def test_transition_newly_created_issue_to_in_progress_state(): """ transition a newly created issue to the In Progress state """ jp = JiraProxy(GOOD_VANILLA_SERVER_DEV_USER_CONFIG) work_item = {"Summary" : "Roller Coaster assembly point"} issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) # If the PROJECT_KEY_4 is used the following line would work #assert "Start Progress" in transitions.keys() jp.transitionIssueState(issue_key, "In Progress") issue = jp.getIssue(issue_key) assert issue.Status == "In Progress" assert jp.deleteIssue(issue_key)
def test_list_transitions_for_newly_created_issue_by_regular(): """ list transitions that an newly created issue can use with getTransitions as a regular user """ jp = JiraProxy(GOOD_VANILLA_SERVER_REG_USER_CONFIG) work_item = {"Summary" : "Elitch Gardens is just OK."} issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) transitions = jp.getTransitions(issue_key) # If the PROJECT_KEY_4 is used the following lines would work #assert "Start Progress" in transitions.keys() #assert "Resolve Issue" in transitions.keys() #assert "Start Progress" in transitions.keys() assert "To Do" in transitions.keys() assert jp.deleteIssue(issue_key)
def test_query_using_components_with_ampersand_in_value(): """ will return issues using jql that for Component/s that use & in their name """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) doof_data = { 'Summary': 'Morti and Rekso went bogging', 'components': 'Sun & Moon' } issue_key = jp.createIssue(PROJECT_KEY_1, 'Bug', doof_data) jql = f'{proj1} AND Component/s = "Sun & Moon" ' jira_issues = jp.getIssuesWithJql(jql) assert len(jira_issues) > 0 assert "Sun & Moon" in jira_issues[0]["Component/s"] jp.deleteIssue(issue_key)
def test_query_using_components_with_question_mark_in_value(): """ will return issues using jql that for Component/s that use ? in their name """ jp = JiraProxy(GOOD_VANILLA_SERVER_CONFIG) doof_data = { 'Summary': 'Steepify glide path to oil dump', 'components': 'Tallest?' } issue_key = jp.createIssue(PROJECT_KEY_1, 'Bug', doof_data) jql = f'{proj1} AND Component/s = "Tallest?" ' jira_issues = jp.getIssuesWithJql(jql) assert len(jira_issues) > 0 assert "Tallest?" in jira_issues[0]["Component/s"] jp.deleteIssue(issue_key)
def test_error_on_attempt_to_transition_new_issue_to_in_progress_state_with_invalid_resolution(): """ error out on an attempt transition a newly created issue to the In Progress state with an invalid resolution """ jp = JiraProxy(GOOD_VANILLA_SERVER_DEV_USER_CONFIG) work_item = {"Summary" : "Roller Coaster Speed Test"} issue_key = jp.createIssue(PROJECT_KEY_1, "Bug", work_item) with py.test.raises(JiraProxyError) as excinfo: jp.transitionIssueState(issue_key, "Done", "Too Slow") actualErrorMessage = excErrorMessage(excinfo) assert "'resolution' cannot be set. It is not on the appropriate screen, or unknown" in actualErrorMessage assert 'proposed Resolution value |Too Slow|' in actualErrorMessage assert jp.deleteIssue(issue_key)