class Jira_Edit_Issue(API_Slack_Dialog):
    def __init__(self, issue_id, field):
        super().__init__()
        self.issue_id = issue_id
        self.field = field
        self.issue = None
        self.api_issues = API_Issues()
        self.submit_label = 'Save'

    def setup(self):
        self.callback_id = 'jira_edit_issue'
        self.title = 'Edit {0}'.format(self.issue_id)
        self.issue = self.api_issues.issue(self.issue_id)
        if not self.issue:
            self.add_element_text('ERROR - Issue not found: {0}'.format(
                self.issue_id))
        else:
            key = "{0}::{1}".format(self.issue_id, self.field)
            value = self.issue.get(self.field)
            #todo: add different type of edit fields based on field name
            self.add_element_textarea(self.field, key, value)

        return self

    def render(self):
        return {
            "callback_id": self.callback_id,
            "title": self.title,
            "submit_label": self.submit_label,
            "notify_on_cancel": self.notify_on_cancel,
            "elements": self.elements
        }
Exemple #2
0
    def add_nodes_from_issue(self, issue_key):

        self.add_node(issue_key)  # .expand_node(issue_key)

        from osbot_jira.api.API_Issues import API_Issues
        api_issues = API_Issues()
        issue = api_issues.issue(issue_key)
        if issue is None:
            print('no data received for key: {0}'.format(issue_key))
            return self

        links = issue.get('Issue Links')
        if links:
            available_links = "{0}".format('\n'.join(list(set(links))))
            available_links_key = "links_for_{0}".format(issue_key)
            self.add_node(available_links_key,
                          available_links,
                          color='#C0C0C0')
            self.add_link(issue_key, available_links_key)

            #print('handling {0} with {1} links'.format(issue_key, len(links)))
            for link_type, values in links.items():
                if (self.link_types is not []) and (link_type
                                                    not in self.link_types):
                    #print('skipping links')
                    continue
                link_type_key = '{0}::{1}'.format(link_type, issue_key)
                self.add_node(link_type_key, link_type, color='yellow')
                self.add_link(issue_key, link_type_key)
                if values:
                    for link_key in values:
                        link_issue = api_issues.issue(link_key)
                        summary = "{0} \n{1}".format(link_issue.get('Summary'),
                                                     link_key)
                        self.add_node(link_key, summary)
                        self.add_link(
                            link_type_key,
                            link_key,
                        )
        else:
            print('no links for {0}'.format(issue_key))
Exemple #3
0
class Edit_UI():
    def __init__(self, issue_id=None, issues=None):
        self.issue_id = issue_id
        self.issues = issues
        self.columns = [
            'Key', 'Summary', 'Issue Link', 'Description', 'Status'
        ]  # 'Latest_Information'
        self.projects = ['TASK', 'OUTCOME', 'KEYRESULT', 'QUESTION']
        self.issue_types = ['Task', 'Outcome', 'KeyResult', 'Question']
        self.link_types = ['is delivered by', 'is parent of', 'uses']
        self.qgrid_to_jira = QGrid_To_Jira(None)
        self.api_jira = self.qgrid_to_jira.api_jira
        self.api_jira_rest = self.qgrid_to_jira.api_jira_rest
        self.api_issues = API_Issues()

    def ui_add_issue(self):
        self.dropdown_project = widgets.Dropdown(options=self.projects,
                                                 description='Project')
        self.dropdown_issue_type = widgets.Dropdown(options=self.issue_types,
                                                    description='Issue Type')
        self.dropdown_link_type = widgets.Dropdown(options=self.link_types,
                                                   description='Link  Type')
        self.text_summary = widgets.Text(value='new_issue',
                                         description='Summary')
        self.button_create_issue = widgets.Button(description='Create Issue',
                                                  icon='plus-square')

        def on_click_create_issue(b):
            self.on_create_issue()

        self.button_create_issue.on_click(on_click_create_issue)
        return widgets.HBox([
            self.dropdown_project, self.dropdown_issue_type,
            self.dropdown_link_type, self.text_summary,
            self.button_create_issue
        ])

    def ui_link_issue(self):
        self.add_link_dropdown_issue_type = widgets.Dropdown(
            options=self.link_types, description='Link Type')
        self.add_link_text_issue_id = widgets.Text(value='',
                                                   description='Issue Id')
        self.add_link_button_create_issue = widgets.Button(
            description='Link Issue', icon='link')

        def on_click_link_issue(b):
            self.on_link_issue()

        self.add_link_button_create_issue.on_click(on_click_link_issue)

        return widgets.HBox([
            self.add_link_dropdown_issue_type, self.add_link_text_issue_id,
            self.add_link_button_create_issue
        ])

    def ui_load_issue(self):
        self.output_area = widgets.Output(layout={
            'border': '1px solid black',
            'width': '1200px'
        })
        self.button_status = widgets.Button(description='...',
                                            layout=widgets.Layout(width='50%'))
        self.text_issue_id = widgets.Text(value=self.issue_id,
                                          description='Issue Id:')
        self.button_load = widgets.Button(description='Load Data',
                                          icon='download')
        self.button_load.style.button_color = 'lightblue'

        def on_button_clicked(b):
            self.issues = None  # to force data reload
            self.issue_id = self.text_issue_id.value
            self.button_status.style.button_color = 'orange'
            self.button_status.description = 'Loading Data from {0}'.format(
                self.issue_id)
            if self.create_grid():
                self.button_status.description = 'Done'
                self.button_status.style.button_color = 'lightgreen'

        self.button_load.on_click(on_button_clicked)

        return widgets.HBox(
            [self.text_issue_id, self.button_load, self.button_status])

    def ui_add_grid(self):
        def on_value_change_local(event, qgrid_widget):
            self.on_value_change(event, qgrid_widget)

        self.grid = qgrid.show_grid(pd.DataFrame([]),
                                    grid_options={'maxVisibleRows': 100})
        self.grid.on('cell_edited', on_value_change_local)

        self.create_grid()
        return self.grid

    def show_ui(self,
                show_load_issue=True,
                show_add_issue=True,
                show_add_link=True,
                show_qgrid=True,
                show_output=True):
        items = []

        if show_load_issue: items.append(self.ui_load_issue())
        if show_add_link: items.append(self.ui_link_issue())
        if show_add_issue: items.append(self.ui_add_issue())
        if show_qgrid: items.append(self.ui_add_grid())
        if show_output: items.append(self.output_area)

        self.vbox = widgets.VBox(items)

        return self.vbox

    def on_create_issue(self):
        qgrid_to_jira = QGrid_To_Jira(None)
        with self.output_area:
            project = self.dropdown_project.value
            issue_type = self.dropdown_issue_type.value
            link_type = self.dropdown_link_type.value
            summary = self.text_summary.value
            #status = '...'
            issue_id = self.issue_id
            print(
                f"Creating '{issue_type}' issue in project '{project}' with summary '{summary}', and link '{link_type}' to '{issue_id}'"
            )
        try:
            # Create issue
            self.button_status.style.button_color = '#E59866'
            self.button_status.description = "Creating '{0}' issue in project '{1}'".format(
                issue_type, project)

            new_issue_id = qgrid_to_jira.api_jira.issue_create(
                project, summary, '', issue_type).key

            # Link issue
            self.button_status.style.button_color = 'orange'
            self.button_status.description = "Linking new issue '{0}' issue to '{1}'".format(
                new_issue_id, issue_id)

            qgrid_to_jira.api_jira.issue_add_link(issue_id, link_type,
                                                  new_issue_id)

            # Update Grid
            self.button_status.style.button_color = 'darkorange'
            self.button_status.description = 'Adding new issue to grid'

            self.add_row_to_grid(new_issue_id, summary, link_type)

            self.button_status.description = 'all done'
            self.button_status.style.button_color = 'lightgreen'
        except Exception as error:
            self.button_status.description = 'Error creating issue or link (see output area'
            self.button_status.style.button_color = 'pink'
            with self.output_area:
                print("{0}".format(error))

    def on_link_issue(self):
        from_key = self.issue_id
        link_type = self.add_link_dropdown_issue_type.value
        to_key = self.add_link_text_issue_id.value

        with self.output_area:
            try:
                self.api_jira.issue_add_link(from_key, link_type, to_key)
                self.button_status.style.button_color = 'lightgreen'
                self.button_status.description = 'Link added ok'
                summary = self.api_issues.issue(to_key).get(
                    'Summary')  # get Summary value from ELK
                self.add_row_to_grid(
                    to_key, summary,
                    link_type)  # add row to the bottom of the grid
            except Exception as error:
                print("Error: {0}".format(error))
                self.button_status.style.button_color = 'pink'
                self.button_status.description = 'Link Error (double check that the issue id exists)'

    def on_value_change(self, event, qgrid_widget):
        key = event.get('index')
        field = event.get('column')
        value = event.get('new')
        old = event.get('old')
        with self.output_area:
            print(
                "updating field '{0}' with value '{1}' on issue '{2}'".format(
                    field, value, key))

        self.button_status.style.button_color = 'orange'

        qgrid_to_jira = QGrid_To_Jira(None)
        if field == 'Issue Link':
            with self.output_area:
                if type(
                        old
                ) is not str:  # todo: find better way to do this. 'old' value is an from pandas.core.series import Series , and the old value doesn't seem to be in there (self.grid.get_selected_df()[old.name].values[0] also didn't seem work)
                    print(
                        "Error: can't remove link issue when multiple entries exist the the same issue id"
                    )
                else:
                    self.button_status.description = "Replacing Issue field {0} with {1}".format(
                        old, value)
                    result = qgrid_to_jira.jira_update_issue_link(
                        self.issue_id, key, old, value)
        else:
            self.button_status.description = "Updating field {0} on {1}".format(
                field, key)
            result = qgrid_to_jira.jira_update_field(key, field, value)
        if result.get('status') == 'ok':
            self.button_status.style.button_color = 'lightgreen'
            self.button_status.description = 'Issue updated ok'
        else:
            self.button_status.style.button_color = 'pink'
            self.button_status.description = 'Update Error: {0}'.format(
                result.get('data'))

    def add_row_to_grid(self, issue_id, summary, link_type):
        columns = list(self.grid.df.columns)
        new_row = [('Key', issue_id)]
        for name in columns:
            value = ''
            if name == 'Summary': value = summary
            if name == 'Issue Link': value = link_type
            new_row.append((name, value))
        self.grid.add_row(new_row)

    def create_grid(self):
        if self.issue_id:
            try:
                # self.graph    = jira.graph_links(self.issue_id, 'all', 1)
                # self.df_graph = graph_table(self.graph,self.columns).fillna('')
                df_issues = self.get_issue_df()
                if len(df_issues) > 0:
                    self.grid.df = self.get_issue_df()
                    return True
                message = f"No links found for '{self.issue_id}'"
            except Exception as error:
                with self.output_area:
                    print('error :{0}'.format(error))
                message = 'Create Grid Error: {0}'.format(error)
            self.button_status.style.button_color = 'pink'
            self.button_status.description = message
        return False

    def get_issue_df(self):
        if self.issues is None:
            self.issues = self.get_issues()
        return pd.DataFrame(self.issues,
                            columns=self.columns).set_index('Key').fillna('')

    def get_issues(self):
        root_issue = self.api_issues.issue(self.issue_id)
        if root_issue == {}:
            return []
        issues = [root_issue]
        issue_links = root_issue.get('Issue Links')
        for link_type, linked_issues in issue_links.items():
            for linked_issue in linked_issues:
                issue = self.api_issues.issue(linked_issue)
                #issue = self.api_jira_rest.issue(linked_issue)  # much slower than using elk
                issue['Issue Link'] = link_type
                issues.append(issue)
        return issues
Exemple #4
0
class Jp_Graph_Data:
    def __init__(self):
        self.lambda_graph = Lambda('osbot_jira.lambdas.graph')
        self.api_issues = API_Issues()
        self.gs_bot_jira = GS_Bot_Jira()
        self.graph_commands = Lambda_Graph_Commands()
        self.elk_to_slack = ELK_to_Slack()

    def lambda_invoke(self, params):
        result = self.lambda_graph.invoke({'params': params, 'data': {}})
        return json_loads(result)

    def issue(self, issue_id):
        return self.api_issues.issue(issue_id)

    def issues(self, issue_id):
        return self.api_issues.issues(issue_id)

    def jira_links(self, source, depth=1):
        params = ['links', source, depth]
        return self.gs_bot_jira.cmd_links(params, save_graph=False)

    def jira_search(self, query):
        params = query.split(' ')
        query = self.elk_to_slack.get_search_query(params)
        return self.api_issues.search_using_lucene(query)

    def graph_expand(self, source, depth, link_types):
        params = [source, depth, link_types]
        return self.graph_commands.expand(params=params, save_graph=False)

        #data = json..invoke(params))
        #nodes = data.get('nodes')
        #edges = data.get('edges')

    def draw_graph(self, graph):
        nodes = graph.nodes
        edges = graph.edges
        import networkx as nx
        import matplotlib.pyplot as plt

        size = 40
        plt.figure(figsize=(size, size))
        G = nx.DiGraph()

        for node in nodes:
            G.add_node(node)

        for edge in edges:
            G.add_edge(edge[0], edge[2], label=edge[1])

        edge_labels = nx.get_edge_attributes(G, 'label')

        # pos = nx.spring_layout(G)
        # pos=nx.nx_pydot.graphviz_layout(G,prog='dot')
        pos = nx.nx_pydot.graphviz_layout(G)

        nx.draw_networkx_nodes(G, pos, node_shape='', node_size=100)
        nx.draw_networkx_labels(G, pos, font_size=16)
        nx.draw_networkx_edges(G, pos)
        nx.draw_networkx_edge_labels(G,
                                     pos=pos,
                                     edge_labels=edge_labels,
                                     font_size=10)
class Jira_View_Issue():
    def __init__(self, issue_id=None, channel=None, team_id=None, event=None):
        self.issue_id = issue_id
        self.channel = channel
        self.team_id = team_id
        self.event = event
        self.api_issues = API_Issues()
        self.api_jira = API_Jira()
        self.issue = None
        self.action_id = 'Jira_View_Issue'
        self.slack_blocks = API_Slack_Blocks()

    # refactor this to base class
    def message_not_supported_action(self, action=''):
        return {
            "text":
            ':red_circle: Sorry, action not recognized : {0}'.format(action),
            "attachments": [],
            'replace_original':
            False
        }

    def message_execution_error(self, error):
        return {
            "text":
            ':red_circle: Sorry, there was an error executing the requested action: {0}'
            .format(error),
            "attachments": [],
            'replace_original':
            False
        }

    def handle_action(self, event):
        self.send_message('aaaa')
        action = Misc.array_pop(event.get('actions'), 0)
        action_value = Misc.get_value(action, 'value')
        try:
            target = getattr(self, action_value)
        except:
            channel = event.get('channel').get('id')
            team_id = event.get('team').get('id')
            # temp code (refactor when adding full support for blocks)
            text = ':point_right: message not recognised: {0}'.format(action)
            API_Slack_Blocks().set_text(text).send_message(channel, team_id)

            return self.message_not_supported_action(
                action)  # event.get('original_message'))

        try:
            return target(event)
        except Exception as error:
            return self.message_execution_error(error)

    def load_issue(self, issue_id=None):
        if issue_id:
            self.issue_id = issue_id
        self.issue = self.api_issues.issue(self.issue_id)
        return self

    def create(self):
        self.load_issue()
        if self.issue:
            key = self.issue.get('Key')
            summary = self.issue.get('Summary')
            latest_info = self.issue.get('Latest_Information')
            description = self.issue.get('Description')
            issue_type = self.issue.get('Issue Type')
            jira_link = "https://glasswall.atlassian.net/browse/{0}".format(
                key)  # todo: put the glasswall jira url in a site config value
            #key_link    = "{0}/browse/{1}".format(self.api_issues.server_url(), key)

            add_layout = self.slack_blocks.add_layout_section

            #text = "*{0}*:\n<{1}|{2} - {3}>".format(issue_type,key_link,key, summary)
            text = ":point_right: *Issue*: <{1}|{2} - {3}>".format(
                issue_type, jira_link, key, summary)

            add_layout(self.issue_id).add_text(text).render()
            if latest_info:
                add_layout().add_text(
                    '*Latest Info:* \n{0}'.format(latest_info)).render()
            if description:
                add_layout().add_text(
                    '*Description:* \n{0}'.format(description)).render()

            actions_section = self.slack_blocks.add_layout_actions(
                self.action_id)
            footer_section = self.slack_blocks.add_layout_context()

            #actions_section.add_button('Edit Issue Field', self.issue_id) \
            actions_section.add_button('View Links'      , self.issue_id) \
                           .add_button('Screenshot'      , self.issue_id) \
                           .add_button('Reload Issue'    , self.issue_id) \
                           .add_button('Raw Issue Data'  , self.issue_id)
            # .add_button('Change Status', self.issue_id)

            self.add_block_actions_with_transitions(self.slack_blocks)

            self.add_select_with_issue_links()

            self.add_block_edit_issue_field(self.slack_blocks)

            self.slack_blocks.add_text('*Actions*')
            actions_section.render()

            self.slack_blocks.add_divider()
            footer_items = [
                'Status: *{0}*'.format(self.issue.get('Status')),
                'Rating: *{0}*'.format(self.issue.get('Rating')),
                'Priority: *{0}*'.format(self.issue.get('Priority')),
                'Issue Type: *{0}*'.format(self.issue.get('Issue Type')),
                'Assignee: *{0}*'.format(self.issue.get('Assignee')),
                'Labels: *{0}*'.format(self.issue.get('Labels')),
                'Creator: *{0}*'.format(self.issue.get('Creator')),
                'Created: *{0}*'.format(
                    self.issue.get('Created').split('T').pop(0)),
                'Updated: *{0}*'.format(
                    self.issue.get('Updated').split('T').pop(0))
            ]
            footer_section.add_texts(footer_items).render()

            #issue_data = "```{0}```".format(json.dumps(self.issue,indent=4))
            #self.slack_blocks.add_layout_section().add_text(issue_data).render()

            #self.slack_ui.text = "<{0}|{1} - {2}>".format(key_link,key, summary)
            #self.add_overflow('abc', 'chose one' ,[('aaaa','aaaa_1'),('bbbb','bbbb_2')])
            #self.add_button('Edit Issue')
            #self.add_button('An Replay')

            self.slack_blocks.add_attachment({
                'text':
                'Issue *{0}* Status: `{1}`'.format(self.issue_id,
                                                   self.issue.get('Status')),
                'color':
                'good'
            })
            return True
        else:
            self.slack_blocks.add_layout_section().add_text(
                ':red_circle: Issue not found: `{0}`'.format(
                    self.issue_id)).render()
            return False

    def send(self):
        if self.channel:
            result = self.slack_blocks.send_message(self.channel, self.team_id)
            if type(result) == dict and result.get('ok') is False:
                error_messages = result.get('response_metadata').get(
                    'messages')
                self.send_message(
                    ':red_circle: Error in `Jira_View_Issue.send`; ```{0}```'.
                    format(error_messages))
            return result

    def create_and_send(self):
        if self.create():
            self.send_message(
                ':point_right: *Loading data for issue: `{0}`* :point_left:'.
                format(self.issue_id))
        return self.send()

    # def an_replay(self, event):
    #     original_message = event.get('original_message')
    #     return {
    #         'text'            : "{0}".format(event), #original_message.get('text'),
    #         'attachments'     : original_message.get('attachments'),
    #         'replace_original': True
    #     }

    def add_select_with_issue_links(self):
        issue_links = self.issue.get('Issue Links')
        if issue_links:
            actions = self.slack_blocks.add_layout_actions(
                action_id='Jira_View_Issue')
            option_groups = []
            size = 0
            for issue_type, links in issue_links.items():
                options = {}
                for link_issue_id in links:
                    link_issue = self.api_issues.issue(link_issue_id)
                    if link_issue:
                        link_summary = link_issue.get('Summary')
                        link_issue_type = link_issue.get('Issue Type')
                        text = "{0} - {1}".format(link_issue_type,
                                                  link_summary)[0:75]
                        if options.get(link_issue_type) is None:
                            options[link_issue_type] = [
                            ]  # use this to sort by link_issue_type
                        options[link_issue_type].append((text, link_issue_id))
                        #options.append((text , link_issue_id))

                options_sorted = []
                for key, values in options.items():
                    for value in values:
                        options_sorted.append(value)
                        size += 1
                option_groups.append((issue_type, options_sorted))

            self.slack_blocks.add_text(
                '*{0} Linked issues* (select to view)'.format(size))
            actions.add_select(
                'Issue Links',
                option_groups=option_groups)  #, action_id='view_issue')

            return actions.render()

    def create_ui_actions_with_transitions(self,
                                           issue_id=None,
                                           current_status=None,
                                           show_intro=True):
        if issue_id:
            self.issue_id = issue_id
        view = API_Slack_Blocks()
        self.add_block_actions_with_transitions(view, current_status,
                                                show_intro)
        return view.send_message(self.channel, self.team_id)

    def add_block_actions_with_transitions(self,
                                           view,
                                           current_status=None,
                                           show_intro=True):
        if self.issue is None:
            self.issue = self.api_issues.issue(self.issue_id)
        if current_status is None:  # this helps with the situation when the issue has just been updated but the data has not reached out to ELK
            current_status = self.issue.get('Status')
        transitions = self.api_jira.issue_next_transitions(self.issue_id)
        if show_intro:
            view.add_text("*Change issue status to*: (click to change)")
        if len(transitions) > 0:
            actions = view.add_layout_actions(action_id='Jira_View_Issue')
            for key, value in transitions.items():
                if key != current_status:
                    action_id = "transition_to::{0}".format(value)
                    value = "{0}::{1}::{2}".format(self.issue_id, value, key)
                    actions.add_button(key, value=value, action_id=action_id)

            return actions.render()
        view.add_text('...no Transitions available...')

    def create_ui_edit_issue_field(self):
        view = API_Slack_Blocks()
        self.add_block_edit_issue_field(view)
        return view.send_message(self.channel, self.team_id)

    def add_block_edit_issue_field(self, view):
        view.add_text("*Edit Issue Field:* (select to edit)".format(
            self.issue_id))
        self.issue = self.api_issues.issue(self.issue_id)
        if self.issue:
            #fields = set(self.issue)
            fields = [
                'Summary', 'Description', 'Labels'
                #'Assignee','Description', 'Labels', 'Latest Information','Summary',
                #'Priority','Rating','Email', 'Slack ID','Image_Url'
            ]
            action_id = 'Jira_View_Issue::edit_field::{0}'.format(
                self.issue_id)
            view.add_select(action_id, 'Field to edit', fields)

    # callback methods

    def send_message(self, message):
        if self.channel:
            return slack_message(message, [], self.channel, self.team_id)
        else:
            return message

    def edit_field(self, action):
        try:
            selected_option = action.get('selected_option')
            field = selected_option.get('text').get('text')
            issue_id = action.get('action_id').split('::').pop(3)
            trigger_id = self.event.get('trigger_id')
            slack_dialog = Jira_Edit_Issue(issue_id, field).setup().render()
            from gw_bot.api.API_Slack import API_Slack
            API_Slack(self.channel,
                      self.team_id).slack.dialog_open(trigger_id=trigger_id,
                                                      dialog=slack_dialog)
        except Exception as error:
            self.send_message(
                ':red_circle: Error in edit_field: {0}'.format(error))

    def issue_links(self, action):
        self.view_issue(action)

    def reload_issue(self, action):
        self.view_issue(action)

    def screenshot(self, action):
        issue_id = action.get('value')
        payload = {
            'params': ['screenshot', issue_id],
            'channel': self.channel,
            'team_id': self.team_id
        }
        Lambda('osbot_jira.lambdas.jira').invoke_async(payload)

    def raw_issue_data(self, action):
        issue_id = action.get('value')
        issue = API_Issues().issue(issue_id)
        if issue:
            issue_data = "```{0}```".format(json.dumps(issue, indent=4))
            return self.send_message(issue_data)

    def view_issue(self, action):
        issue_id = action.get('value')
        if issue_id is None:
            selected_option = action.get('selected_option')
            if selected_option:
                issue_id = selected_option.get('value')
        if issue_id:
            payload = {
                'params': ['issue', issue_id],
                'channel': self.channel,
                'team_id': self.team_id
            }
            Lambda('osbot_jira.lambdas.jira').invoke_async(payload)
        else:
            self.send_message(
                ':red_circle: Error in View Issue, no issue id found in action :{0}'
                .format(action))

    def view_links(self, action):
        try:
            issue_id = action.get('value')
            self.send_message(
                ':point_right: Viewing all links for issue: `{0}`'.format(
                    issue_id))
            payload = {
                'params': ['links', issue_id, 'all', '1'],
                'channel': self.channel,
                'team_id': self.team_id
            }
            Lambda('osbot_jira.lambdas.jira').invoke_async(payload)
        except Exception as error:
            self.send_message(
                ':red_circle: Error in View Links for issue with id `{0}`: {1}'
                .format(issue_id, error))

    def change_status(self, action):
        try:
            self.issue_id = action.get('value')
            self.create_ui_actions_with_transitions()
        except Exception as error:
            self.send_message(
                ':red_circle: Error in change_status: {0}'.format(error))

    def edit_issue_field(self, action):
        try:
            self.issue_id = action.get('value')
            self.create_ui_edit_issue_field()
        except Exception as error:
            self.send_message(
                ':red_circle: Error in change_status: {0}'.format(error))

    def transition_to(self, action):
        value_split = action.get('value').split('::')
        issue_id = Misc.array_pop(value_split, 0)
        transition_to = Misc.array_pop(value_split, 0)
        transition_name = Misc.array_pop(value_split, 0)
        try:
            self.api_jira.issue_transition_to_id(issue_id, transition_to)
            self.send_message(
                ':white_check_mark: Changed `{0}` status to: *{1}*. Here are the new transitions available '
                .format(issue_id, transition_name))
            self.create_ui_actions_with_transitions(issue_id,
                                                    transition_name,
                                                    show_intro=False)
        except Exception as error:
            self.send_message(
                ':red_circle: Error in transition_to: {0}'.format(error))
Exemple #6
0
class Test_API_Issues(unittest.TestCase):
    def setUp(self):
        self.key = 'RISK-1515'
        self.api = API_Issues()

    def test_epic_issues(self):
        results = self.api.epic_issues('SEC-2024')
        assert len(list(results)) > 10

    def test_issue(self):
        issue = self.api.issue(self.key)
        assert issue.get('Key') == self.key

    @unittest.skip('todo: fix: error on "if item[\'found\'] is False:" line')
    def test_issues(self):
        keys = ['RISK-1499', 'RISK-1496', 'AAA']
        #result = self.api.elastic.es.mget(index='jira',
        #                                    doc_type='item',
        #                       body={'ids': keys})
        results = self.api.elastic().get_many(keys)
        #Dev.pprint(results)

    def test_issues_all(self):
        assert len(self.api.issues_all('jira')) > 2000

    def test_issues_created_in_last(self):
        result = self.api.issues_created_in_last("3d")
        assert len(result) > 10

    def test_issues_updated_in_last(self):
        result = self.api.issues_updated_in_last("3d")
        assert len(result) > 10

    def test_issues_created_in_last_nnn(self):
        assert len(self.api.issues_created_in_last_seconds(
            1 * 24 * 60 * 60)) > 0
        assert len(self.api.issues_created_in_last_minutes(1 * 24 * 60)) > 0
        assert len(self.api.issues_created_in_last_hours(1 * 24)) > 0
        assert len(self.api.issues_created_in_last_days(1)) > 0
        assert len(self.api.issues_created_in_last_weeks(1)) > 0
        assert len(self.api.issues_created_in_last_months(1)) > 0

    @unittest.skip('fails in CodeBuild')
    def test_create_issue_table(self):
        table = self.api.create_issue_table('RISK-424')
        table.save_tmp()
        #Dev.print(table.puml)

    def test_labels(self):
        result = self.api.labels()
        assert 'VULN-2160' in result['AWSrisk']
        assert len(result) > 650

    def test_link_types(self):
        result = self.api.link_types()
        assert len(result) > 100

    def test_keys(self):
        keys = self.api.keys()
        assert 'VULN-10' in keys
        assert len(keys) > 15000

    def test_search(self):
        assert len(self.api.search("aw", "Summary", 100)) > 0
        assert len(self.api.search("R1", "Labels", 10)) > 0
        assert self.api.search("GSP-95", "Key",
                               10).pop().get('Key') == "GSP-95"

    def test_search_using_lucene(self):
        query = 'Project:RISK AND Status:"Fixed"'
        results = self.api.search_using_lucene(query)
        assert len(results) > 200

    # def test_stakeholders(self):
    #     result = self.api.stakeholders()
    #     #Dev.pprint(result)
    #     #Dev.pprint(len(set(result)))

    ### move these to separate analysis file

    @unittest.skip('Fails in CodeBuild')
    def test_graph_issue_links_plant_uml(self):
        puml = self.api.graph_issue_links_plant_uml(self.key)
        puml.save_tmp()
        puml._dev_send_to_slack()