diff --git a/README.md b/README.md index 26d4d8afc..765a61dc0 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Each enriched index includes one or more types of documents, which are summarize - **Mozillaclub**: each document includes event information. - **Nttp**: each document corresponds to a message. - **Onion Study/Community Structure**: each document corresponds to an author in a specific quarter, split by organization and project. That means we have an entry for the author’s overall contributions in a given quarter, one entry for the author in each one of the projects he contributed to in that quarter and the same for the author in each of the organizations he is affiliated to in that quarter. This way we store results of onion analysis computed overall, by project and by organization +- **Pagure**: each document corresponds to an issue. - **Phabricator**: each document corresponds to a task. - **Pipermail**: each document corresponds to a message. - **Puppetforge**: each document corresponds to a module. diff --git a/grimoire_elk/enriched/pagure.py b/grimoire_elk/enriched/pagure.py new file mode 100644 index 000000000..b9b5eb9df --- /dev/null +++ b/grimoire_elk/enriched/pagure.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015-2020 Bitergia +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Authors: +# Animesh Kumar +# + +import logging +from datetime import datetime +from grimoirelab_toolkit.datetime import (unixtime_to_datetime, + datetime_utcnow) +from .utils import get_time_diff_days +from .enrich import Enrich, metadata +from ..elastic_mapping import Mapping as BaseMapping + +logger = logging.getLogger(__name__) + +MAX_SIZE_BULK_ENRICHED_ITEMS = 200 +ISSUE_TYPE = 'issue' +COMMENT_TYPE = 'comment' +ISSUE_COMMENT_TYPE = 'issue_comment' + + +class Mapping(BaseMapping): + + @staticmethod + def get_elastic_mappings(es_major): + """Get Elasticsearch mapping. + + :param es_major: major version of Elasticsearch, as string + :returns: dictionary with a key, 'items', with the mapping + """ + + mapping = """ + { + "properties": { + "title_analyzed": { + "type": "text", + "index": true + }, + "body_analyzed": { + "type": "text", + "index": true + }, + "id": { + "type": "keyword" + } + } + } + """ + + return {"items": mapping} + + +class PagureEnrich(Enrich): + mapping = Mapping + + comment_roles = ['user'] + issue_roles = ['user', 'assignee'] + + def __init__(self, db_sortinghat=None, db_projects_map=None, json_projects_map=None, + db_user='', db_password='', db_host=''): + super().__init__(db_sortinghat, db_projects_map, json_projects_map, + db_user, db_password, db_host) + + def set_elastic(self, elastic): + self.elastic = elastic + + def get_field_author(self): + return "user" + + def get_field_date(self): + """ Field with the date in the JSON enriched items """ + + return "grimoire_creation_date" + + def get_field_unique_id(self): + return "id" + + def get_identities(self, item): + """ Return the identities from an item """ + + item = item['data'] + for identity in self.issue_roles: + if item[identity]: + user = self.get_sh_identity(item[identity]) + if user: + yield user + + # Comments + if 'comments' in item: + for comment in item['comments']: + if 'user' in comment: + user = comment.get('user', None) + identity = self.get_sh_identity(user) + yield identity + + def get_sh_identity(self, item, identity_field=None): + identity = {} + + user = item # by default a specific user dict is expected + if isinstance(item, dict) and 'data' in item: + user = item['data'][identity_field] + elif identity_field: + user = item[identity_field] + + if not user: + return identity + + identity['email'] = None + identity['name'] = user.get('fullname', None) + identity['username'] = user.get('name', None) + return identity + + def add_gelk_metadata(self, eitem): + eitem['metadata__gelk_version'] = self.gelk_version + eitem['metadata__gelk_backend_name'] = self.__class__.__name__ + eitem['metadata__enriched_on'] = datetime_utcnow().isoformat() + + def get_project_repository(self, eitem): + repo = eitem['origin'] + return repo + + def get_time_to_first_attention(self, item): + """Get the first date at which a comment was made to the issue by someone + other than the user who created the issue + """ + comment_dates = [unixtime_to_datetime(float(comment['date_created'])).isoformat() for comment + in item['comments'] if item['user']['name'] != comment['user']['name']] + if comment_dates: + return min(comment_dates) + return None + + def __get_reactions(self, item): + reactions = {} + + item_reactions = item.get('reactions', {}) + for reaction in item_reactions: + reactions['reaction_{}'.format(reaction)] = item_reactions[reaction] + + return reactions + + def get_rich_issue_comments(self, comments, eitem): + ecomments = [] + + for comment in comments: + ecomment = {} + + for f in self.RAW_FIELDS_COPY: + ecomment[f] = eitem[f] + + # Copy data from the enriched issue + ecomment['issue_id'] = eitem['id'] + ecomment['issue_title'] = eitem['title'] + ecomment['issue_status'] = eitem['status'] + ecomment['issue_created_at'] = eitem['created_at'] + ecomment['issue_updated_at'] = eitem['updated_at'] + ecomment['issue_closed_at'] = eitem['closed_at'] + ecomment['issue_pull_requests'] = eitem['related_prs'] + ecomment['item_type'] = COMMENT_TYPE + + # Copy data from the raw comment + ecomment['body'] = comment['comment'][:self.KEYWORD_MAX_LENGTH] + ecomment['body_analyzed'] = comment['comment'] + + # extract reactions and add it to enriched item + ecomment.update(self.__get_reactions(comment)) + + if 'edited_on' in comment and comment['edited_on']: + ecomment['comment_updated_at'] = unixtime_to_datetime(float(comment['edited_on'])).isoformat() + editor = comment['editor'] + ecomment['comment_updated_by_name'] = editor.get('fullname', None) + ecomment['comment_updated_by_username'] = editor.get('name', None) + + ecomment['comment_created_at'] = unixtime_to_datetime(float(comment['date_created'])).isoformat() + ecomment['comment_changed_at'] = \ + ecomment['comment_updated_at'] if 'comment_updated_at' in ecomment else ecomment['comment_created_at'] + ecomment['notification'] = comment['notification'] + ecomment['parent'] = comment['parent'] + + author = comment.get('user', None) + if author: + ecomment['comment_author_username'] = author.get('name', None) + ecomment['comment_author_name'] = author.get('fullname', None) + + # Add id info to allow to coexistence of items of different types in the same index + ecomment['id'] = '{}_issue_comment_{}'.format(eitem['id'], comment['id']) + ecomment.update(self.get_grimoire_fields(ecomment['comment_changed_at'], ISSUE_COMMENT_TYPE)) + + if self.sortinghat: + comment['changed_at'] = ecomment['comment_changed_at'] + ecomment.update(self.get_item_sh(comment, self.comment_roles, 'changed_at')) + + if self.prjs_map: + ecomment.update(self.get_item_project(ecomment)) + + if 'project' in eitem: + ecomment['project'] = eitem['project'] + + self.add_repository_labels(ecomment) + self.add_metadata_filter_raw(ecomment) + self.add_gelk_metadata(ecomment) + + ecomments.append(ecomment) + + return ecomments + + def enrich_issue(self, item, eitem): + eitems = [] + + comments = item['data'].get('comments', []) + if comments: + rich_item_comments = self.get_rich_issue_comments(comments, eitem) + eitems.extend(rich_item_comments) + + return eitems + + def enrich_items(self, ocean_backend): + items_to_enrich = [] + num_items = 0 + ins_items = 0 + + for item in ocean_backend.fetch(): + eitem = self.get_rich_item(item) + + if item['category'] == ISSUE_TYPE: + items_to_enrich.append(eitem) + eitems = self.enrich_issue(item, eitem) + items_to_enrich.extend(eitems) + + if len(items_to_enrich) < MAX_SIZE_BULK_ENRICHED_ITEMS: + continue + + num_items += len(items_to_enrich) + ins_items += self.elastic.bulk_upload(items_to_enrich, self.get_field_unique_id()) + items_to_enrich = [] + + if len(items_to_enrich) > 0: + num_items += len(items_to_enrich) + ins_items += self.elastic.bulk_upload(items_to_enrich, self.get_field_unique_id()) + + if num_items != ins_items: + missing = num_items - ins_items + logger.error("%s/%s missing items for Pagure", str(missing), str(num_items)) + + logger.info("%s/%s items inserted for Pagure", str(ins_items), str(num_items)) + + return num_items + + @metadata + def get_rich_item(self, item): + + rich_item = {} + if item['category'] == 'issue': + rich_item = self.__get_rich_issue(item) + self.add_repository_labels(rich_item) + self.add_metadata_filter_raw(rich_item) + else: + logger.error("[pagure] rich item not defined for Pagure category {}".format(item['category'])) + + return rich_item + + def __get_rich_issue(self, item): + + rich_issue = {} + + for f in self.RAW_FIELDS_COPY: + if f in item: + rich_issue[f] = item[f] + else: + rich_issue[f] = None + + # The real data + issue = item['data'] + + rich_issue['author_username'] = None + rich_issue['author_name'] = None + if 'user' in issue and issue['user']: + author = issue['user'] + rich_issue['author_username'] = author.get('name', None) + rich_issue['author_name'] = author.get('fullname', None) + + rich_issue['assignee_username'] = None + rich_issue['assignee_name'] = None + if 'assignee' in issue and issue['assignee']: + assignee = issue['assignee'] + rich_issue['assignee_username'] = assignee.get('name', None) + rich_issue['assignee_name'] = assignee.get('fullname', None) + + if 'closed_by' in issue and issue['closed_by']: + closed_by = issue['closed_by'] + rich_issue['closed_by_username'] = closed_by.get('name', None) + rich_issue['closed_by_name'] = closed_by.get('fullname', None) + + if 'closed_at' in issue and issue['closed_at']: + rich_issue['closed_at'] = unixtime_to_datetime(float(issue['closed_at'])).isoformat() + else: + rich_issue['closed_at'] = None + + rich_issue['id'] = issue['id'] + rich_issue['title'] = issue['title'] + rich_issue['title_analyzed'] = issue['title'] + rich_issue['content'] = issue['content'] + rich_issue['status'] = issue['status'] + rich_issue['close_status'] = issue['close_status'] + rich_issue['num_comments'] = len(issue['comments']) + rich_issue['created_at'] = unixtime_to_datetime(float(issue['date_created'])).isoformat() + rich_issue['updated_at'] = unixtime_to_datetime(float(issue['last_updated'])).isoformat() + rich_issue['blocks'] = issue['blocks'] + rich_issue['private'] = issue['private'] + rich_issue['priority'] = issue['priority'] + rich_issue['milestone'] = issue['milestone'] + rich_issue['related_prs'] = issue['related_prs'] + rich_issue['tags'] = issue['tags'] + rich_issue['custom_fields'] = issue['custom_fields'] + rich_issue['item_type'] = ISSUE_TYPE + + rich_issue['time_to_close_days'] = \ + get_time_diff_days(rich_issue['created_at'], rich_issue['closed_at']) + + if issue['status'] != 'Closed': + rich_issue['time_open_days'] = \ + get_time_diff_days(rich_issue['created_at'], datetime.utcnow()) + else: + rich_issue['time_open_days'] = rich_issue['time_to_close_days'] + + if self.prjs_map: + rich_issue.update(self.get_item_project(rich_issue)) + + rich_issue['time_to_first_attention'] = None + if len(issue['comments']) != 0: + rich_issue['time_to_first_attention'] = \ + get_time_diff_days(rich_issue['created_at'], self.get_time_to_first_attention(issue)) + + rich_issue.update(self.get_grimoire_fields(rich_issue['updated_at'], "issue")) + + if self.sortinghat: + item[self.get_field_date()] = rich_issue[self.get_field_date()] + rich_issue.update(self.get_item_sh(item, self.issue_roles)) + + return rich_issue diff --git a/grimoire_elk/raw/pagure.py b/grimoire_elk/raw/pagure.py new file mode 100644 index 000000000..bb26004d5 --- /dev/null +++ b/grimoire_elk/raw/pagure.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015-2020 Bitergia +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Authors: +# Animesh Kumar +# + +from .elastic import ElasticOcean +from ..elastic_mapping import Mapping as BaseMapping + + +class Mapping(BaseMapping): + + @staticmethod + def get_elastic_mappings(es_major): + """Get Elasticsearch mapping. + + :param es_major: major version of Elasticsearch, as string + :returns: dictionary with a key, 'items', with the mapping + """ + + mapping = ''' + { + "dynamic":true, + "properties": { + "data": { + "dynamic":false, + "properties": {} + } + } + } + ''' + + return {"items": mapping} + + +class PagureOcean(ElasticOcean): + """Pagure Ocean feeder""" + + mapping = Mapping + + @classmethod + def get_perceval_params_from_url(cls, url): + """ Get the perceval params given a URL for the data source """ + + params = [] + url_params = url.split('/') + + if len(url_params) == 5: + namespace = url.split('/')[-2] + params.append(namespace) + + repository = url.split('/')[-1] + params.append(repository) + + return params diff --git a/grimoire_elk/utils.py b/grimoire_elk/utils.py index 367e3d085..b2003ba40 100755 --- a/grimoire_elk/utils.py +++ b/grimoire_elk/utils.py @@ -56,6 +56,7 @@ from perceval.backends.core.mediawiki import MediaWiki, MediaWikiCommand from perceval.backends.core.meetup import Meetup, MeetupCommand from perceval.backends.core.nntp import NNTP, NNTPCommand +from perceval.backends.core.pagure import Pagure, PagureCommand from perceval.backends.core.phabricator import Phabricator, PhabricatorCommand from perceval.backends.core.pipermail import Pipermail, PipermailCommand from perceval.backends.core.twitter import Twitter, TwitterCommand @@ -102,6 +103,7 @@ from .enriched.meetup import MeetupEnrich from .enriched.mozillaclub import MozillaClubEnrich from .enriched.nntp import NNTPEnrich +from .enriched.pagure import PagureEnrich from .enriched.phabricator import PhabricatorEnrich from .enriched.pipermail import PipermailEnrich from .enriched.puppetforge import PuppetForgeEnrich @@ -140,6 +142,7 @@ from .raw.meetup import MeetupOcean from .raw.mozillaclub import MozillaClubOcean from .raw.nntp import NNTPOcean +from .raw.pagure import PagureOcean from .raw.phabricator import PhabricatorOcean from .raw.pipermail import PipermailOcean from .raw.puppetforge import PuppetForgeOcean @@ -237,6 +240,7 @@ def get_connectors(): "meetup": [Meetup, MeetupOcean, MeetupEnrich, MeetupCommand], "mozillaclub": [MozillaClub, MozillaClubOcean, MozillaClubEnrich, MozillaClubCommand], "nntp": [NNTP, NNTPOcean, NNTPEnrich, NNTPCommand], + "pagure": [Pagure, PagureOcean, PagureEnrich, PagureCommand], "phabricator": [Phabricator, PhabricatorOcean, PhabricatorEnrich, PhabricatorCommand], "pipermail": [Pipermail, PipermailOcean, PipermailEnrich, PipermailCommand], "puppetforge": [PuppetForge, PuppetForgeOcean, PuppetForgeEnrich, PuppetForgeCommand], diff --git a/releases/unreleased/add-support-for-pagure.yml b/releases/unreleased/add-support-for-pagure.yml new file mode 100644 index 000000000..ab4f40e58 --- /dev/null +++ b/releases/unreleased/add-support-for-pagure.yml @@ -0,0 +1,11 @@ +--- +title: Add support for Pagure +category: added +author: Animesh Kumar +issue: 821 +notes: > + Added support for creating raw and enriched indexes + of Pagure. Issued from a Pagure repository are enriched. + Additionally, the comments of these issues (if present) are also + enriched. The schema for this backend has also been added. + Tests have been included accordingly. diff --git a/schema/pagure.csv b/schema/pagure.csv new file mode 100644 index 000000000..fa2dce568 --- /dev/null +++ b/schema/pagure.csv @@ -0,0 +1,87 @@ +name,type,aggregatable,description +assignee_bot,boolean,true,"True if the given assignee is identified as a bot." +assignee_domain,keyword,true,"Domain associated to the assignee in SortingHat profile." +assignee_gender,keyword,true,"Assignee gender, based on her name (disabled by default)." +assignee_gender_acc,long,true,"Assignee gender accuracy (disabled by default)." +assignee_id,keyword,true,"Assignee Id from SortingHat." +assignee_multi_org_names,keyword,true,"List of the assignee organizations from SortingHat profile." +assignee_name,keyword,true,"Assignee name." +assignee_org_name,keyword,true,"Assignee organization name." +assignee_user_name,keyword,true,"Assignee user name from SortingHat." +assignee_username,keyword,true,"Assignee user name from Pagure." +assignee_uuid,keyword,true,"Assignee UUID from SortingHat." +author_bot,boolean,true,"True if the given author is identified as a bot." +author_domain,keyword,true,"Domain associated to the author in SortingHat profile." +author_gender,keyword,true,"Author gender, based on her name (disabled by default)." +author_gender_acc,keyword,true,"Author gender accuracy (disabled by default)." +author_id,keyword,true,"Author Id from SortingHat." +author_multi_org_names,keyword,true,"List of the author organizations from SortingHat profile." +author_name,keyword,true,"Author name." +author_org_name,keyword,true,"Author organization name." +author_user_name,keyword,true,"Author user name from SortingHat." +author_username,keyword,true,"Author user name from GitLab." +author_uuid,keyword,true,"Author UUID from SortingHat." +body,keyword,true,"Body of the Comment." +body_analyzed,text,false,"Body of the Comment." +blocks,keyword,true,"Issue blocks." +close_status,keyword,true,"Issue close status." +closed_at,date,true,"Date in which the Issue was closed." +closed_by_name,keyword,true,"Issue closed by name." +closed_by_username,keyword,true,"Issue closed by username." +comment_author_name,keyword,true,"Comment author name." +comment_author_username,keyword,true,"Comment author username." +comment_created_at,date,true,"Date in which comment was created." +comment_changed_at,date,true,"Date in which comment was last modified." +comment_updated_at,date,true,"Date in which comment was last updated. If not updated it is null." +content,keyword,true,"Issue content." +created_at,date,true,"Date in which the Issue was created." +custom_fields,keyword,true,"Custom fields of the Issue." +grimoire_creation_date,date,true,"Issue/Comment creation date." +id,keyword,true,"Issue/Comment Id in Pagure." +is_pagure_issue,long,true,"1 indicating this is an Issue, used for counting in case other kind of items could be stored in the same index or alias." +is_pagure_issue_comment,long,true,"1 indicating this is a Comment of an Issue." +issue_closed_at,date,true,"Date when an Issue was closed." +issue_created_at,date,true,"Date when an Issue was opened." +issue_id,long,true,"Issue ID on Pagure." +issue_pull_requests.id,keyword,true,"Id of Pull request related to the Issue." +issue_pull_requests.title,keyword,true,"Title of Pull request related to the Issue." +issue_status,keyword,true,"Status of the Issue." +issue_title,keyword,true,"Issue title." +issue_updated_at,date,true,"Date when the Issue was updated." +item_type,keyword,true,"Type of item(Issue/Comment)." +metadata__enriched_on,date,true,"Date when the item was enriched." +metadata__gelk_backend_name,keyword,true,"Name of the backend used to enrich information." +metadata__gelk_version,keyword,true,"Version of the backend used to enrich information." +metadata__timestamp,date,true,"Date when the item was stored in RAW index." +metadata__updated_on,date,true,"Date when the item was updated on its original data source." +milestone,keyword,true,"Assigned milestone." +num_comments,long,true,"Number of comments in the Issue." +notification,boolean,true,"True if notification is enabled." +origin,keyword,true,"Original URL where the repository was retrieved from." +parent,keyword,true,"Parent of the comment." +priority,keyword,true,"Priority assigned to the Issue." +private,boolean,true,"True if Issue is private." +project,keyword,true,"Project." +project_1,keyword,true,"Project (if more than one level is allowed in project hierarchy)." +related_prs.id,keyword,true,"Id of Pull request related to the Issue." +related_prs.title,keyword,true,"Title of Pull request related to the Issue." +repository_labels,keyword,true,"Custom repository labels defined by the user." +status,keyword,true,"Status of the Issue." +tag,keyword,true,"Perceval tag." +tags,keyword,true,"Tags assigned to the Issue." +time_open_days,float,true,"Time open in days." +time_to_close_days,float,true,"Time to close Issue in days." +time_to_first_attention,float,true,"Time in days from creation to first comment added by an author different from the one who created this Issue." +title,keyword,true,"Issue title." +title_analyzed,text,false,"Issue title split by by terms to allow searching." +updated_at,date,true,"Date when the Issue was updated." +user_bot,boolean,true,"True if the given user is identified as a bot." +user_domain,keyword,true,"Domain associated to the assignee in SortingHat profile." +user_gender,keyword,true,"Assignee gender, based on her name (disabled by default)." +user_gender_acc,long,true,"Assignee gender accuracy (disabled by default)." +user_id,keyword,true,"Assignee Id from SortingHat." +user_name,keyword,true,"User's name from SortingHat profile" +user_org_name,keyword,true,"User's organization name from SortingHat profile." +user_user_name,keyword,true,"User's username from SortingHat profile." +user_uuid,keyword,true,"User's UUID from SortingHat profile." +uuid,keyword,true,"Perceval UUID." \ No newline at end of file diff --git a/tests/data/pagure.json b/tests/data/pagure.json new file mode 100644 index 000000000..180ff7201 --- /dev/null +++ b/tests/data/pagure.json @@ -0,0 +1,697 @@ +[ + { + "backend_name": "Pagure", + "backend_version": "0.1.2", + "category": "issue", + "classified_fields_filtered": null, + "data": { + "assignee": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + }, + "blocks": [ + "3" + ], + "close_status": null, + "closed_at": null, + "closed_by": null, + "comments": [ + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue assigned to animeshk08", + "date_created": "1583438698", + "edited_on": null, + "editor": null, + "id": 631112, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + } + ], + "content": "This is the body of the issue", + "custom_fields": [], + "date_created": "1583438446", + "depends": [], + "id": 1, + "last_updated": "1583438698", + "milestone": null, + "priority": null, + "private": false, + "related_prs": [], + "status": "Open", + "tags": [], + "title": "Issue Title 1", + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + "origin": "https://pagure.io/Test-group/Project-example-namespace", + "perceval_version": "0.13.0", + "search_fields": { + "item_id": "1", + "namespace": "Test-group", + "repo": "Project-example-namespace" + }, + "tag": "https://pagure.io/Test-group/Project-example-namespace", + "timestamp": 1586702417.916355, + "updated_on": 1583438698.0, + "uuid": "893a1834d540c3d454fae3852d89c6317952b180" + }, + { + "backend_name": "Pagure", + "backend_version": "0.1.2", + "category": "issue", + "classified_fields_filtered": null, + "data": { + "assignee": null, + "blocks": [], + "close_status": null, + "closed_at": null, + "closed_by": null, + "comments": [ + { + "comment": "Comment", + "date_created": "1583508416", + "edited_on": null, + "editor": null, + "id": 631225, + "notification": false, + "parent": null, + "reactions": { + "Thumbs down": [ + "animeshk0806" + ] + }, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "related #4 ", + "date_created": "1586700534", + "edited_on": null, + "editor": null, + "id": 641603, + "notification": false, + "parent": null, + "reactions": { + "Heart": [ + "animeshk0806" + ], + "Thumbs up": [ + "animeshk0806" + ] + }, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Custom field Field 1 adjusted to Field 1 value added\n- Issue set to the milestone: Milestone1", + "date_created": "1586701266", + "edited_on": null, + "editor": null, + "id": 641608, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "Related PR: https://pagure.io/Test-group/Project-example-namespace/pull-request/4", + "date_created": "1586701737", + "edited_on": null, + "editor": null, + "id": 641612, + "notification": false, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + } + ], + "content": "This is body", + "custom_fields": [ + { + "key_data": null, + "key_type": "text", + "name": "Field 1", + "value": "Field 1 value added" + } + ], + "date_created": "1583508401", + "depends": [ + "3" + ], + "id": 2, + "last_updated": "1586701737", + "milestone": "Milestone1", + "priority": null, + "private": false, + "related_prs": [], + "status": "Open", + "tags": [], + "title": "Issue Title 3", + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + "origin": "https://pagure.io/Test-group/Project-example-namespace", + "perceval_version": "0.13.0", + "search_fields": { + "item_id": "2", + "namespace": "Test-group", + "repo": "Project-example-namespace" + }, + "tag": "https://pagure.io/Test-group/Project-example-namespace", + "timestamp": 1586702417.916913, + "updated_on": 1586701737.0, + "uuid": "25e3d4d5bda945145c36d1ebedfab74a5dacec7e" + }, + { + "backend_name": "Pagure", + "backend_version": "0.1.2", + "category": "issue", + "classified_fields_filtered": null, + "data": { + "assignee": { + "fullname": "Animesh Kumar Singh", + "name": "animeshk0806" + }, + "blocks": [ + "2" + ], + "close_status": null, + "closed_at": null, + "closed_by": null, + "comments": [ + { + "comment": "This is comment 1", + "date_created": "1586699484", + "edited_on": null, + "editor": null, + "id": 641596, + "notification": false, + "parent": null, + "reactions": { + "Confused": [ + "animeshk0806" + ], + "Thumbs up": [ + "animeshk0806" + ] + }, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue assigned to animeshk0806", + "date_created": "1586699543", + "edited_on": null, + "editor": null, + "id": 641597, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "This is comment 2 edited", + "date_created": "1586699690", + "edited_on": "1586699744", + "editor": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + }, + "id": 641598, + "notification": false, + "parent": null, + "reactions": { + "Thumbs up": [ + "animeshk08" + ] + }, + "user": { + "fullname": "Animesh Kumar Singh", + "name": "animeshk0806" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue marked as blocking: #2", + "date_created": "1586699806", + "edited_on": null, + "editor": null, + "id": 641599, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue marked as depending on: #1", + "date_created": "1586699833", + "edited_on": null, + "editor": null, + "id": 641600, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk0806**:\n- Issue **un**marked as blocking: #2\n- Issue **un**marked as depending on: #1", + "date_created": "1586699858", + "edited_on": null, + "editor": null, + "id": 641601, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar Singh", + "name": "animeshk0806" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue marked as blocking: #2\n- Issue marked as depending on: #1", + "date_created": "1586699903", + "edited_on": null, + "editor": null, + "id": 641602, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue tagged with: Tag1", + "date_created": "1586700737", + "edited_on": null, + "editor": null, + "id": 641604, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue set to the milestone: Milestone1", + "date_created": "1586701212", + "edited_on": null, + "editor": null, + "id": 641607, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + } + ], + "content": "This is the body of sample issue", + "custom_fields": [], + "date_created": "1586699455", + "depends": [ + "1" + ], + "id": 3, + "last_updated": "1586701212", + "milestone": "Milestone1", + "priority": null, + "private": false, + "related_prs": [], + "status": "Open", + "tags": [ + "Tag1" + ], + "title": "Sample Title 3", + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + "origin": "https://pagure.io/Test-group/Project-example-namespace", + "perceval_version": "0.13.0", + "search_fields": { + "item_id": "3", + "namespace": "Test-group", + "repo": "Project-example-namespace" + }, + "tag": "https://pagure.io/Test-group/Project-example-namespace", + "timestamp": 1586702417.917566, + "updated_on": 1586701212.0, + "uuid": "bb3b4c187085b3fce84367d08f13a534aff38848" + }, + { + "backend_name": "Pagure", + "backend_version": "0.1.2", + "category": "issue", + "classified_fields_filtered": null, + "data": { + "assignee": null, + "blocks": [], + "close_status": null, + "closed_at": "1586700911", + "closed_by": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + }, + "comments": [ + { + "comment": "Issue close coment", + "date_created": "1586700912", + "edited_on": null, + "editor": null, + "id": 641605, + "notification": false, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue status updated to: Closed (was: Open)", + "date_created": "1586700912", + "edited_on": null, + "editor": null, + "id": 641606, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + } + ], + "content": "This is sample issue 4\r\n", + "custom_fields": [], + "date_created": "1586700892", + "depends": [], + "id": 5, + "last_updated": "1586700912", + "milestone": null, + "priority": null, + "private": false, + "related_prs": [], + "status": "Closed", + "tags": [], + "title": "Sample title 4", + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + "origin": "https://pagure.io/Test-group/Project-example-namespace", + "perceval_version": "0.13.0", + "search_fields": { + "item_id": "5", + "namespace": "Test-group", + "repo": "Project-example-namespace" + }, + "tag": "https://pagure.io/Test-group/Project-example-namespace", + "timestamp": 1586702417.918565, + "updated_on": 1586700912.0, + "uuid": "47217aab9eedd19a08b70d8c01e00e683a7a3239" + }, + { + "backend_name": "Pagure", + "backend_version": "0.1.2", + "category": "issue", + "classified_fields_filtered": null, + "data": { + "assignee": { + "fullname": "Animesh Kumar Singh", + "name": "animeshk0806" + }, + "blocks": [], + "close_status": "Close status 1", + "closed_at": "1586701522", + "closed_by": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + }, + "comments": [ + { + "comment": "**Metadata Update from @animeshk08**:\n- Custom field Field 1 adjusted to Value 1\n- Issue assigned to animeshk0806", + "date_created": "1586701422", + "edited_on": null, + "editor": null, + "id": 641609, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "Merges #4 ", + "date_created": "1586701436", + "edited_on": null, + "editor": null, + "id": 641610, + "notification": false, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Custom field Field 1 reset (from Value 1)\n- Issue close_status updated to: Close satus 1\n- Issue status updated to: Closed (was: Open)", + "date_created": "1586701522", + "edited_on": null, + "editor": null, + "id": 641611, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + } + ], + "content": "Comment of issue 5", + "custom_fields": [], + "date_created": "1586701392", + "depends": [], + "id": 6, + "last_updated": "1586701522", + "milestone": "Milestone1", + "priority": null, + "private": false, + "related_prs": [], + "status": "Closed", + "tags": [ + "Tag1" + ], + "title": "Sample issue 5", + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + "origin": "https://pagure.io/Test-group/Project-example-namespace", + "perceval_version": "0.13.0", + "search_fields": { + "item_id": "6", + "namespace": "Test-group", + "repo": "Project-example-namespace" + }, + "tag": "https://pagure.io/Test-group/Project-example-namespace", + "timestamp": 1586702417.919084, + "updated_on": 1586701522.0, + "uuid": "b36c3f0a80187ce4c8ea07162c19c37a12670a9e" + }, + { + "backend_name": "Pagure", + "backend_version": "0.1.2", + "category": "issue", + "classified_fields_filtered": null, + "data": { + "assignee": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + }, + "blocks": [ + "3" + ], + "close_status": null, + "closed_at": null, + "closed_by": null, + "comments": [ + { + "comment": "**Metadata Update from @animeshk08**:\n- Issue assigned to animeshk08", + "date_created": "1583438698", + "edited_on": null, + "editor": null, + "id": 631232, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + } + ], + "content": "**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************", + "custom_fields": [], + "date_created": "1583438446", + "depends": [], + "id": 7, + "last_updated": "1583438698", + "milestone": null, + "priority": null, + "private": false, + "related_prs": [], + "status": "Open", + "tags": [], + "title": "Issue Title 1", + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + "origin": "https://pagure.io/Test-group/Project-example-namespace", + "perceval_version": "0.13.0", + "search_fields": { + "item_id": "1", + "namespace": "Test-group", + "repo": "Project-example-namespace" + }, + "tag": "https://pagure.io/Test-group/Project-example-namespace", + "timestamp": 1586702417.916355, + "updated_on": 1583438698.0, + "uuid": "893a1834d3d454f540cae3852d89c361795280b1" + }, + { + "backend_name": "Pagure", + "backend_version": "0.1.2", + "category": "message", + "classified_fields_filtered": null, + "data": { + "assignee": { + "fullname": "Animesh Kumar Singh", + "name": "animeshk0806" + }, + "blocks": [], + "close_status": "Close status 1", + "closed_at": "1586701522", + "closed_by": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + }, + "comments": [ + { + "comment": "**Metadata Update from @animeshk08**:\n- Custom field Field 1 adjusted to Value 1\n- Issue assigned to animeshk0806", + "date_created": "1586701422", + "edited_on": null, + "editor": null, + "id": 741209, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "Merges #4 ", + "date_created": "1586701436", + "edited_on": null, + "editor": null, + "id": 741210, + "notification": false, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + { + "comment": "**Metadata Update from @animeshk08**:\n- Custom field Field 1 reset (from Value 1)\n- Issue close_status updated to: Close satus 1\n- Issue status updated to: Closed (was: Open)", + "date_created": "1586701522", + "edited_on": null, + "editor": null, + "id": 7416234, + "notification": true, + "parent": null, + "reactions": {}, + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + } + ], + "content": "Comment of issue 5", + "custom_fields": [], + "date_created": "1586701392", + "depends": [], + "id": 8, + "last_updated": "1586701522", + "milestone": "Milestone1", + "priority": null, + "private": false, + "related_prs": [], + "status": "Closed", + "tags": [ + "Tag1" + ], + "title": "Sample issue 5", + "user": { + "fullname": "Animesh Kumar", + "name": "animeshk08" + } + }, + "origin": "https://pagure.io/Test-group/Project-example-namespace", + "perceval_version": "0.13.0", + "search_fields": { + "item_id": "20", + "namespace": "Test-group", + "repo": "Project-example-namespace" + }, + "tag": "https://pagure.io/Test-group/Project-example-namespace", + "timestamp": 1586702417.919084, + "updated_on": 1586701522.0, + "uuid": "126c3f0a80187ce4c8ea07162c19c37a12670a9e" + } +] \ No newline at end of file diff --git a/tests/data/projects-release.json b/tests/data/projects-release.json index 8eb474843..38b991855 100644 --- a/tests/data/projects-release.json +++ b/tests/data/projects-release.json @@ -81,6 +81,9 @@ "phabricator": [ "https://phabricator.wikimedia.org" ], + "pagure": [ + "https://pagure.io/Test-group/Project-example-namespace" + ], "pipermail": [ "https://mail.gnome.org/archives/libart-hackers/" ], diff --git a/tests/test_pagure.py b/tests/test_pagure.py new file mode 100644 index 000000000..106e1c558 --- /dev/null +++ b/tests/test_pagure.py @@ -0,0 +1,247 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015-2019 Bitergia +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Authors: +# Animesh Kumar +# +import logging +import unittest + +import requests +from base import TestBaseBackend +import grimoire_elk.enriched.pagure as pagure_enriched +from grimoire_elk.enriched.utils import REPO_LABELS +from grimoire_elk.raw.pagure import PagureOcean + + +class TestPagure(TestBaseBackend): + """Test Pagure backend""" + + connector = "pagure" + ocean_index = "test_" + connector + enrich_index = "test_" + connector + "_enrich" + + def test_has_identites(self): + """Test value of has_identities method""" + + enrich_backend = self.connectors[self.connector][2]() + self.assertTrue(enrich_backend.has_identities()) + + def test_items_to_raw(self): + """Test whether JSON items are properly inserted into ES""" + + result = self._test_items_to_raw() + + self.assertEqual(result['items'], 7) + self.assertEqual(result['raw'], 7) + self.assertEqual(result['items'], result['raw']) + + def test_raw_to_enrich(self): + """Test whether the raw index is properly enriched""" + + result = self._test_raw_to_enrich() + + self.assertEqual(result['raw'], 7) + self.assertEqual(result['enrich'], 26) + + enrich_backend = self.connectors[self.connector][2]() + + item = self.items[0] + eitem = enrich_backend.get_rich_item(item) + self.assertEqual(item['category'], 'issue') + self.assertEqual(eitem['id'], 1) + self.assertEqual(eitem['origin'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['tag'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['author_username'], 'animeshk08') + self.assertEqual(eitem['assignee_username'], 'animeshk08') + self.assertEqual(eitem['title'], 'Issue Title 1') + self.assertEqual(eitem['status'], 'Open') + self.assertIsNone(eitem['close_status']) + self.assertEqual(eitem['num_comments'], 1) + self.assertListEqual(eitem['blocks'], ['3']) + self.assertListEqual(eitem['tags'], []) + self.assertListEqual(eitem['custom_fields'], []) + self.assertIsNone(eitem['time_to_close_days']) + self.assertGreater(eitem['time_open_days'], 0.0) + self.assertIsNone(eitem['time_to_first_attention']) + + item = self.items[1] + eitem = enrich_backend.get_rich_item(item) + self.assertEqual(item['category'], 'issue') + self.assertEqual(eitem['id'], 2) + self.assertEqual(eitem['origin'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['tag'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['author_username'], 'animeshk08') + self.assertIsNone(eitem['assignee_username']) + self.assertEqual(eitem['title'], 'Issue Title 3') + self.assertEqual(eitem['status'], 'Open') + self.assertIsNone(eitem['close_status']) + self.assertEqual(eitem['num_comments'], 4) + self.assertListEqual(eitem['blocks'], []) + self.assertListEqual(eitem['tags'], []) + self.assertIsNotNone(eitem['custom_fields']) + self.assertIsNone(eitem['time_to_close_days']) + self.assertGreater(eitem['time_open_days'], 0.0) + self.assertIsNone(eitem['time_to_first_attention']) + + item = self.items[2] + eitem = enrich_backend.get_rich_item(item) + self.assertEqual(item['category'], 'issue') + self.assertEqual(eitem['id'], 3) + self.assertEqual(eitem['origin'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['tag'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['author_username'], 'animeshk08') + self.assertEqual(eitem['assignee_username'], 'animeshk0806') + self.assertEqual(eitem['title'], 'Sample Title 3') + self.assertEqual(eitem['status'], 'Open') + self.assertEqual(eitem['milestone'], 'Milestone1') + self.assertIsNone(eitem['close_status']) + self.assertEqual(eitem['num_comments'], 9) + self.assertListEqual(eitem['blocks'], ['2']) + self.assertListEqual(eitem['tags'], ['Tag1']) + self.assertListEqual(eitem['custom_fields'], []) + self.assertIsNone(eitem['time_to_close_days']) + self.assertGreater(eitem['time_open_days'], 0.0) + self.assertEqual(eitem['time_to_first_attention'], 0.0) + + item = self.items[3] + eitem = enrich_backend.get_rich_item(item) + self.assertEqual(item['category'], 'issue') + self.assertEqual(eitem['id'], 5) + self.assertEqual(eitem['origin'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['tag'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['author_username'], 'animeshk08') + self.assertIsNone(eitem['assignee_username']) + self.assertEqual(eitem['closed_by_username'], 'animeshk08') + self.assertEqual(eitem['title'], 'Sample title 4') + self.assertEqual(eitem['status'], 'Closed') + self.assertIsNone(eitem['milestone']) + self.assertIsNone(eitem['close_status']) + self.assertEqual(eitem['num_comments'], 2) + self.assertListEqual(eitem['blocks'], []) + self.assertListEqual(eitem['tags'], []) + self.assertListEqual(eitem['custom_fields'], []) + self.assertEqual(eitem['time_to_close_days'], 0.0) + self.assertEqual(eitem['time_open_days'], 0.0) + self.assertIsNone(eitem['time_to_first_attention']) + + item = self.items[4] + eitem = enrich_backend.get_rich_item(item) + self.assertEqual(item['category'], 'issue') + self.assertEqual(eitem['id'], 6) + self.assertEqual(eitem['origin'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['tag'], 'https://pagure.io/Test-group/Project-example-namespace') + self.assertEqual(eitem['author_username'], 'animeshk08') + self.assertEqual(eitem['assignee_username'], 'animeshk0806') + self.assertEqual(eitem['closed_by_username'], 'animeshk08') + self.assertEqual(eitem['title'], 'Sample issue 5') + self.assertEqual(eitem['status'], 'Closed') + self.assertEqual(eitem['milestone'], 'Milestone1') + self.assertEqual(eitem['close_status'], 'Close status 1') + self.assertEqual(eitem['num_comments'], 3) + self.assertListEqual(eitem['blocks'], []) + self.assertListEqual(eitem['tags'], ['Tag1']) + self.assertListEqual(eitem['custom_fields'], []) + self.assertEqual(eitem['time_to_close_days'], 0.0) + self.assertEqual(eitem['time_open_days'], 0.0) + self.assertIsNone(eitem['time_to_first_attention']) + + def test_enrich_repo_labels(self): + """Test whether the field REPO_LABELS is present in the enriched items""" + + self._test_raw_to_enrich() + enrich_backend = self.connectors[self.connector][2]() + + for item in self.items: + eitem = enrich_backend.get_rich_item(item) + if eitem and 'id' in eitem: + self.assertIn(REPO_LABELS, eitem) + + def test_raw_to_enrich_sorting_hat(self): + """Test enrich with SortingHat""" + + result = self._test_raw_to_enrich(sortinghat=True) + self.assertEqual(result['raw'], 7) + self.assertEqual(result['enrich'], 26) + + enrich_backend = self.connectors[self.connector][2]() + enrich_backend.sortinghat = True + + url = self.es_con + "/" + self.enrich_index + "/_search" + response = enrich_backend.requests.get(url, verify=False).json() + for hit in response['hits']['hits']: + source = hit['_source'] + if 'author_uuid' in source: + self.assertIn('author_domain', source) + self.assertIn('author_gender', source) + self.assertIn('author_gender_acc', source) + self.assertIn('author_org_name', source) + self.assertIn('author_bot', source) + self.assertIn('author_multi_org_names', source) + + def test_perceval_params(self): + """Test the extraction of perceval params from an URL""" + + url = "https://pagure.io/Test-group/Project-example-namespace" + expected_params = [ + 'Test-group', 'Project-example-namespace' + ] + self.assertListEqual(PagureOcean.get_perceval_params_from_url(url), expected_params) + + url = "https://pagure.io/Project-example" + expected_params = [ + 'Project-example' + ] + self.assertListEqual(PagureOcean.get_perceval_params_from_url(url), expected_params) + + def test_raw_to_enrich_projects(self): + """Test enrich with Projects""" + + result = self._test_raw_to_enrich(projects=True) + self.assertEqual(result['raw'], 7) + self.assertEqual(result['enrich'], 26) + + res = requests.get(self.es_con + "/" + self.enrich_index + "/_search", verify=False) + for eitem in res.json()['hits']['hits']: + self.assertEqual(eitem['_source']['project'], "grimoire") + + def test_refresh_identities(self): + """Test refresh identities""" + + result = self._test_refresh_identities() + # ... ? + + def test_refresh_project(self): + """Test refresh project field for all sources""" + + result = self._test_refresh_project() + # ... ? + + def test_max_bulk_item_exceed(self): + """Test bulk upload of documents when number of documents + exceeds max bulk item limit""" + pagure_enriched.MAX_SIZE_BULK_ENRICHED_ITEMS = 2 + result = self._test_raw_to_enrich(projects=True) + self.assertEqual(result['raw'], 7) + self.assertEqual(result['enrich'], 26) + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s') + logging.getLogger("urllib3").setLevel(logging.WARNING) + logging.getLogger("requests").setLevel(logging.WARNING) + unittest.main(warnings='ignore')