# Path: bugwarrior/services/trac.py
# class TracService(IssueService):
#     ISSUE_CLASS = TracIssue
#     CONFIG_SCHEMA = TracConfig
# 
#     def __init__(self, *args, **kw):
#         super().__init__(*args, **kw)
#         if self.config.username:
#             password = self.get_password('password', self.config.username)
# 
#             auth = urllib.parse.quote_plus(
#                 f'{self.config.username}:{password}@')
#         else:
#             auth = ''
# 
#         self.trac = None
#         uri = f'{self.config.scheme}://{auth}{self.config.base_uri}/'
#         if self.config.no_xmlrpc:
#             self.uri = uri
#         else:
#             self.trac = offtrac.TracServer(uri + 'login/xmlrpc')
# 
#     @staticmethod
#     def get_keyring_service(config):
#         return f"https://{config.username}@{config.base_uri}/"
# 
#     def annotations(self, tag, issue, issue_obj):
#         annotations = []
#         # without offtrac, we can't get issue comments
#         if self.trac is None:
#             return annotations
#         changelog = self.trac.server.ticket.changeLog(issue['number'])
#         for time, author, field, oldvalue, newvalue, permament in changelog:
#             if field == 'comment':
#                 annotations.append((author, newvalue, ))
# 
#         url = issue_obj.get_processed_url(issue['url'])
#         return self.build_annotations(annotations, url)
# 
#     def get_owner(self, issue):
#         tag, issue = issue
#         return issue.get('owner', None) or None
# 
#     def issues(self):
#         base_url = "https://" + self.config.base_uri
#         if self.trac:
#             tickets = self.trac.query_tickets('status!=closed&max=0')
#             tickets = list(map(self.trac.get_ticket, tickets))
#             issues = [(self.target, ticket[3]) for ticket in tickets]
#             for i in range(len(issues)):
#                 issues[i][1]['url'] = "%s/ticket/%i" % (base_url, tickets[i][0])
#                 issues[i][1]['number'] = tickets[i][0]
#         else:
#             resp = requests.get(
#                 self.uri + 'query',
#                 params={
#                     'status': '!closed',
#                     'max': '0',
#                     'format': 'csv',
#                     'col': ['id', 'summary', 'owner', 'priority', 'component'],
#                 })
#             if resp.status_code != 200:
#                 raise RuntimeError("Trac responded with %s" % resp)
#             # strip Trac's bogus BOM
#             text = resp.text[1:].lstrip('\ufeff')
#             tickets = list(csv.DictReader(StringIO.StringIO(text.encode('utf-8'))))
#             issues = [(self.target, ticket) for ticket in tickets]
#             for i in range(len(issues)):
#                 issues[i][1]['url'] = "%s/ticket/%s" % (base_url, tickets[i]['id'])
#                 issues[i][1]['number'] = int(tickets[i]['id'])
# 
#         log.debug(" Found %i total.", len(issues))
# 
#         issues = list(filter(self.include, issues))
#         log.debug(" Pruned down to %i", len(issues))
# 
#         for project, issue in issues:
#             issue_obj = self.get_issue_for_record(issue)
#             extra = {
#                 'annotations': self.annotations(project, issue, issue_obj),
#                 'project': project,
#             }
#             issue_obj.update_extra(extra)
#             yield issue_obj
# 
# Path: tests/base.py
# class ServiceTest(ConfigTest):
#     GENERAL_CONFIG = {
#         'interactive': False,
#         'annotation_length': 100,
#         'description_length': 100,
#     }
#     SERVICE_CONFIG = {
#     }
# 
#     @classmethod
#     def setUpClass(cls):
#         cls.maxDiff = None
# 
#     def get_mock_service(
#         self, service_class, section='unspecified',
#         config_overrides=None, general_overrides=None
#     ):
#         options = {
#             'general': {**self.GENERAL_CONFIG, 'targets': section},
#             section: self.SERVICE_CONFIG.copy(),
#         }
#         if config_overrides:
#             options[section].update(config_overrides)
#         if general_overrides:
#             options['general'].update(general_overrides)
# 
#         service_config = service_class.CONFIG_SCHEMA(**options[section])
#         main_config = schema.MainSectionConfig(**options['general'])
#         main_config.data = data.BugwarriorData(self.lists_path)
# 
#         return service_class(service_config, main_config, section)
# 
#     @staticmethod
#     def add_response(url, **kwargs):
#         responses.add(responses.GET, url, match_querystring=True, **kwargs)
# 
# class AbstractServiceTest(abc.ABC):
#     """ Ensures that certain test methods are implemented for each service. """
#     @abc.abstractmethod
#     def test_to_taskwarrior(self):
#         """ Test Service.to_taskwarrior(). """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def test_issues(self):
#         """
#         Test Service.issues().
# 
#         - When the API is accessed via requests, use the responses library to
#         mock requests.
#         - When the API is accessed via a third party library, substitute a fake
#         implementation class for it.
#         """
#         raise NotImplementedError


from bugwarrior.services.trac import TracService
from .base import ServiceTest, AbstractServiceTest



class FakeTracTicket:
    @staticmethod
    def changeLog(issuenumber):
        return []


class FakeTracServer:
    ticket = FakeTracTicket()


class FakeTracLib:
    server = FakeTracServer()

    def __init__(self, record):
        self.record = record

    @staticmethod
    def query_tickets(query):
        return ['something']

    def get_ticket(self, ticket):
        return (1, None, None, self.record)


class TestTracIssue(AbstractServiceTest, ServiceTest):
    SERVICE_CONFIG = {
        'service': 'trac',

# Path: bugwarrior/services/trac.py
# class TracService(IssueService):
#     ISSUE_CLASS = TracIssue
#     CONFIG_SCHEMA = TracConfig
# 
#     def __init__(self, *args, **kw):
#         super().__init__(*args, **kw)
#         if self.config.username:
#             password = self.get_password('password', self.config.username)
# 
#             auth = urllib.parse.quote_plus(
#                 f'{self.config.username}:{password}@')
#         else:
#             auth = ''
# 
#         self.trac = None
#         uri = f'{self.config.scheme}://{auth}{self.config.base_uri}/'
#         if self.config.no_xmlrpc:
#             self.uri = uri
#         else:
#             self.trac = offtrac.TracServer(uri + 'login/xmlrpc')
# 
#     @staticmethod
#     def get_keyring_service(config):
#         return f"https://{config.username}@{config.base_uri}/"
# 
#     def annotations(self, tag, issue, issue_obj):
#         annotations = []
#         # without offtrac, we can't get issue comments
#         if self.trac is None:
#             return annotations
#         changelog = self.trac.server.ticket.changeLog(issue['number'])
#         for time, author, field, oldvalue, newvalue, permament in changelog:
#             if field == 'comment':
#                 annotations.append((author, newvalue, ))
# 
#         url = issue_obj.get_processed_url(issue['url'])
#         return self.build_annotations(annotations, url)
# 
#     def get_owner(self, issue):
#         tag, issue = issue
#         return issue.get('owner', None) or None
# 
#     def issues(self):
#         base_url = "https://" + self.config.base_uri
#         if self.trac:
#             tickets = self.trac.query_tickets('status!=closed&max=0')
#             tickets = list(map(self.trac.get_ticket, tickets))
#             issues = [(self.target, ticket[3]) for ticket in tickets]
#             for i in range(len(issues)):
#                 issues[i][1]['url'] = "%s/ticket/%i" % (base_url, tickets[i][0])
#                 issues[i][1]['number'] = tickets[i][0]
#         else:
#             resp = requests.get(
#                 self.uri + 'query',
#                 params={
#                     'status': '!closed',
#                     'max': '0',
#                     'format': 'csv',
#                     'col': ['id', 'summary', 'owner', 'priority', 'component'],
#                 })
#             if resp.status_code != 200:
#                 raise RuntimeError("Trac responded with %s" % resp)
#             # strip Trac's bogus BOM
#             text = resp.text[1:].lstrip('\ufeff')
#             tickets = list(csv.DictReader(StringIO.StringIO(text.encode('utf-8'))))
#             issues = [(self.target, ticket) for ticket in tickets]
#             for i in range(len(issues)):
#                 issues[i][1]['url'] = "%s/ticket/%s" % (base_url, tickets[i]['id'])
#                 issues[i][1]['number'] = int(tickets[i]['id'])
# 
#         log.debug(" Found %i total.", len(issues))
# 
#         issues = list(filter(self.include, issues))
#         log.debug(" Pruned down to %i", len(issues))
# 
#         for project, issue in issues:
#             issue_obj = self.get_issue_for_record(issue)
#             extra = {
#                 'annotations': self.annotations(project, issue, issue_obj),
#                 'project': project,
#             }
#             issue_obj.update_extra(extra)
#             yield issue_obj
# 
# Path: tests/base.py
# class ServiceTest(ConfigTest):
#     GENERAL_CONFIG = {
#         'interactive': False,
#         'annotation_length': 100,
#         'description_length': 100,
#     }
#     SERVICE_CONFIG = {
#     }
# 
#     @classmethod
#     def setUpClass(cls):
#         cls.maxDiff = None
# 
#     def get_mock_service(
#         self, service_class, section='unspecified',
#         config_overrides=None, general_overrides=None
#     ):
#         options = {
#             'general': {**self.GENERAL_CONFIG, 'targets': section},
#             section: self.SERVICE_CONFIG.copy(),
#         }
#         if config_overrides:
#             options[section].update(config_overrides)
#         if general_overrides:
#             options['general'].update(general_overrides)
# 
#         service_config = service_class.CONFIG_SCHEMA(**options[section])
#         main_config = schema.MainSectionConfig(**options['general'])
#         main_config.data = data.BugwarriorData(self.lists_path)
# 
#         return service_class(service_config, main_config, section)
# 
#     @staticmethod
#     def add_response(url, **kwargs):
#         responses.add(responses.GET, url, match_querystring=True, **kwargs)
# 
# class AbstractServiceTest(abc.ABC):
#     """ Ensures that certain test methods are implemented for each service. """
#     @abc.abstractmethod
#     def test_to_taskwarrior(self):
#         """ Test Service.to_taskwarrior(). """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def test_issues(self):
#         """
#         Test Service.issues().
# 
#         - When the API is accessed via requests, use the responses library to
#         mock requests.
#         - When the API is accessed via a third party library, substitute a fake
#         implementation class for it.
#         """
#         raise NotImplementedError


# Path: tests/test_trac.py
from bugwarrior.services.trac import TracService
from .base import ServiceTest, AbstractServiceTest




class FakeTracTicket:
    @staticmethod
    def changeLog(issuenumber):
        return []


class FakeTracServer:
    ticket = FakeTracTicket()


class FakeTracLib:
    server = FakeTracServer()

    def __init__(self, record):
        self.record = record

    @staticmethod
    def query_tickets(query):
        return ['something']

    def get_ticket(self, ticket):
        return (1, None, None, self.record)


class TestTracIssue(AbstractServiceTest, ServiceTest):
    SERVICE_CONFIG = {
        'service': 'trac',

        'trac.base_uri': 'ljlkajsdfl.com',