def create(title, body=None, locked=False, number=1, **kwargs): target = Issue(Mock(), Mock(), dict(), True) raw_data = { 'locked': locked } _patch_object(monkeypatch, target, number=number, title=title, body=body, raw_data=raw_data) return target
def test_metatable_checker_grade_integration_add_success(mocker): MetaResponse = namedtuple('MetaResponse', 'exists item_id item_name geometry_type') Grade = namedtuple('Grade', 'check grade issue') grade = MetaTableChecker('table.name', {}).grade(add=True, report_value=MetaResponse( True, 'item id', 'item name', 'geometry type')) attributes = {} issue = Issue(REQUESTER, {}, attributes, True) issue.create_comment = spy = mocker.MagicMock() conductor.publish_grades( {'table.name': [Grade('meta table', grade, issue)]}, True) spy.assert_called_once_with('''## conductor results for table.name | check | status | | - | :-: | | meta table | | | - item id | :+1: | | - item name | :+1: | | - geometry type | :+1: |''')
def test_publish_sheets_integration_test_remove_all_pass(mocker): SheetResponse = namedtuple('SheetResponse', 'valid messages') Grade = namedtuple('Grade', 'check grade issue') grades = { 'Description': True, 'Data Source': True, 'Deprecated': True, } grade = GSheetChecker('fake.table', 'id', 'name', 'TESTING').grade(add=False, report_value=SheetResponse( True, grades)) attributes = {} issue = Issue(REQUESTER, {}, attributes, True) issue.create_comment = spy = mocker.MagicMock() conductor.publish_grades( {'table.name': [Grade('sheetchecker', grade, issue)]}, True) spy.assert_called_once_with('''## conductor results for table.name | check | status | | - | :-: | | sheetchecker | | | - deprecation issue link | :+1: |''')
def test_extract_metadata_from_issue_body_returns_none_when_not_found(): headers = {} attributes = {'body': 'text\nmore text\n<!-- some comments -->'} issue = Issue(REQUESTER, headers, attributes, True) metadata = conductor.extract_metadata_from_issue_body(issue, notify=False) assert metadata is None
def get_events_for_document(raw_document): gh = Github(settings.GH_TOKEN) document = Issue(gh._Github__requester, {}, raw_document, completed=True) raw_document['events'] = [] for event in document.get_events(): raw_document['events'].append(event.raw_data) wait_for_rate(event) return raw_document
def create(title, body=None, locked=False, number=1, **kwargs): raw_data = { 'title': title, 'body': body, 'number': number, 'locked': locked } raw_data.update(kwargs) # Set url to a unique value, because that's how issues are compared raw_data['url'] = str(hash(tuple(raw_data.values()))) return Issue(Mock(), Mock(), raw_data, True)
def create(title, body=None, locked=False, number=1, labels=[], **kwargs): raw_data = { 'title': title, 'body': body, 'number': number, 'locked': locked, 'labels': [dict(name=label) for label in labels] } raw_data.update(kwargs) # Set url to a unique value, because that's how issues are compared raw_data['url'] = text_type(hash(json.dumps(raw_data))) return Issue(Mock(), Mock(), raw_data, True)
def test_notify_is_called_when_metadata_is_empty(mocker): mocker.patch('conductor.conductor._notify_missing_metadata') headers = {} attributes = {'body': 'text\nmore text\n<!-- some comments -->'} issue = Issue(REQUESTER, headers, attributes, True) metadata = conductor.extract_metadata_from_issue_body(issue, notify=True) assert metadata is None conductor._notify_missing_metadata.assert_called_once_with(issue)
def test_can_extract_metadata_from_issue_body(): headers = {} attributes = { 'body': 'text\n<!-- some comments -->\n<!-- conductor = {"table":"schema.table","when":"2020-07no_entry6T09:00:00.000Z"} -->\nmore text' } issue = Issue(REQUESTER, headers, attributes, True) metadata = conductor.extract_metadata_from_issue_body(issue, notify=False) assert list(metadata.keys()) == ['table', 'when']
def test_publish_grades_formats_table(mocker): Grade = namedtuple('Grade', 'check grade issue') attributes = {} issue = Issue(REQUESTER, {}, attributes, True) issue.create_comment = spy = mocker.MagicMock() conductor.publish_grades({'table.name': [Grade('check', 'grade', issue)]}, True) spy.assert_called_once_with( '## conductor results for table.name\n\n| check | status |\n| - | :-: |\n| check | grade |' )
def get_events_for_document(raw_document): gh = get_gh_client() document = Issue(gh._Github__requester, {}, raw_document, completed=True) raw_document['events'] = [] try: for event in document.get_events(): raw_document['events'].append(event.raw_data) wait_for_rate(event) except UnknownObjectException: # If this object no longer exist don't do anything pass return raw_document
def test_grade_report(mocker): Report = namedtuple('Report', 'check issue report grader') Grade = namedtuple('Grade', 'check grade issue') ConductorIssue = namedtuple('ConductorIssue', 'issue introduction') issue = ConductorIssue(Issue(REQUESTER, {}, {}, True), True) grader = mocker.MagicMock(return_value='pass') grades = conductor.grade_reports( {'table.name': [Report('check 1', issue, True, grader)]}) grader.assert_called_once_with(True, True) assert len(grades) == 1 assert grades['table.name'][0] == Grade('check 1', 'pass', issue.issue)
def test_table_checker_grade_integration_remove_fail(mocker): Grade = namedtuple('Grade', 'check grade issue') grade = TableChecker('table.name', {}).grade(add=False, report_value=True) attributes = {} issue = Issue(REQUESTER, {}, attributes, True) issue.create_comment = spy = mocker.MagicMock() conductor.publish_grades( {'table.name': [Grade('tablechecker', grade, issue)]}, True) spy.assert_called_once_with('''## conductor results for table.name | check | status | | - | :-: | | tablechecker | :no_entry: |''')
def test_url_checker_grade_integration_add_success(mocker): Grade = namedtuple('Grade', 'check grade issue') grade = UrlChecker().grade(add=True, report_value=True) attributes = {} issue = Issue(REQUESTER, {}, attributes, True) issue.create_comment = spy = mocker.MagicMock() conductor.publish_grades( {'table.name': [Grade('urlchecker', grade, issue)]}, True) spy.assert_called_once_with('''## conductor results for table.name | check | status | | - | :-: | | urlchecker | :+1: |''')
def prs_by_contributor(self, committers: set[str]) -> dict[ NamedUser, list[(Issue, Issue)]]: """ Returns a dict of Pull Requests, associated by committer, within the last :var self.since_day: days of :var self.today:. """ # Search for PRs and Issues on the parent repo if running on a fork repo_name = self.repo.full_name if self.repo.parent is None else self.repo.parent.full_name query = (f"repo:{repo_name} is:issue linked:pr is:closed closed:" f"{self.since_day()}..{self.today}") linked_issues = self.search_issues(query=query) prs_by_contributor: dict[NamedUser, list[(Issue, Issue)]] = {} for linked_issue in linked_issues: timeline = linked_issue.get_timeline() pull_request: Optional[Issue] = None for event in timeline: if event.id is not None: continue if event.event != GH_TIMELINE_EVENT_TYPE_CROSS_REFERENCE: continue pr_text: dict[str] = event.raw_data["source"]["issue"] if "pull_request" not in pr_text: continue pull_request = Issue(self.repo.__getattribute__("_requester"), event.raw_headers, pr_text, completed=True) # Do not break, in case the Issue has ever been linked to more than 1 PR in the past if pull_request is None: raise Exception( f"Unable to find a linked Pull Request for Issue {self.repo.full_name}#{linked_issue.number}") # Skip unmerged PRs if "merged_at" not in pull_request.pull_request.raw_data: continue author = pull_request.user if author.login in committers: continue if author not in prs_by_contributor: prs_by_contributor[author] = [] prs_by_contributor[author].append((pull_request, linked_issue)) return prs_by_contributor
def get_issue(me, org, repo, issue_num): headers, data = me._requester.requestJsonAndCheck( "GET", f"/repos/{org}/{repo}/issues/{issue_num}" ) return Issue(me._requester, headers, data, completed=True)