You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by he...@apache.org on 2016/01/27 19:43:29 UTC
[1/5] allura git commit: [#8054] remove a docstring Google Code
reference
Repository: allura
Updated Branches:
refs/heads/master c5b6ce55f -> eabfc16b1
[#8054] remove a docstring Google Code reference
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/eabfc16b
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/eabfc16b
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/eabfc16b
Branch: refs/heads/master
Commit: eabfc16b1a5f5d728c16da2b054f80f4d23c3b8a
Parents: d4dda57
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jan 27 13:34:47 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 13:42:50 2016 -0500
----------------------------------------------------------------------
ForgeImporters/forgeimporters/base.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/eabfc16b/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 25399ea..32be2bd 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -420,7 +420,7 @@ class ToolImporter(object):
`source` value of the :class:`ProjectImporter` for this importer to
be discovered during full-project imports. E.g.::
- source = 'Google Code'
+ source = 'GitHub'
.. py:attribute:: controller
[5/5] allura git commit: [#8054] delete Google Code importers and
tests
Posted by he...@apache.org.
[#8054] delete Google Code importers and tests
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b956fe30
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b956fe30
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b956fe30
Branch: refs/heads/master
Commit: b956fe30b11639df2cb68374eae5b221fa72e88c
Parents: c5b6ce5
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jan 26 13:58:43 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 13:42:50 2016 -0500
----------------------------------------------------------------------
ForgeImporters/docs/importers/google.rst | 30 -
.../forgeimporters/google/__init__.py | 449 --------------
ForgeImporters/forgeimporters/google/code.py | 154 -----
ForgeImporters/forgeimporters/google/project.py | 68 ---
ForgeImporters/forgeimporters/google/tasks.py | 39 --
.../google/templates/code/index.html | 31 -
.../google/templates/project.html | 68 ---
.../google/templates/tracker/index.html | 27 -
.../forgeimporters/google/tests/__init__.py | 16 -
.../forgeimporters/google/tests/test_code.py | 146 -----
.../forgeimporters/google/tests/test_init.py | 130 ----
ForgeImporters/forgeimporters/google/tracker.py | 224 -------
.../tests/data/google/empty-issue.html | 306 ----------
.../data/google/test-issue-first-page.html | 548 -----------------
.../tests/data/google/test-issue-prev-page.html | 431 -------------
.../tests/data/google/test-issue.html | 535 ----------------
.../forgeimporters/tests/google/__init__.py | 16 -
.../tests/google/functional/__init__.py | 16 -
.../tests/google/functional/test_tracker.py | 316 ----------
.../tests/google/test_extractor.py | 607 -------------------
.../forgeimporters/tests/google/test_tasks.py | 33 -
.../forgeimporters/tests/google/test_tracker.py | 336 ----------
22 files changed, 4526 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/docs/importers/google.rst
----------------------------------------------------------------------
diff --git a/ForgeImporters/docs/importers/google.rst b/ForgeImporters/docs/importers/google.rst
deleted file mode 100644
index 5ed7306..0000000
--- a/ForgeImporters/docs/importers/google.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-.. Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-
-Google Code
-===========
-
-This importer imports projects and tools from Google Code.
-
-:mod:`forgeimporters.google`
-----------------------------
-
-.. autoclass:: forgeimporters.google.project.GoogleCodeProjectImporter
- :members:
-
-.. autoclass:: forgeimporters.google.tracker.GoogleCodeTrackerImporter
- :members:
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/__init__.py b/ForgeImporters/forgeimporters/google/__init__.py
deleted file mode 100644
index 302544e..0000000
--- a/ForgeImporters/forgeimporters/google/__init__.py
+++ /dev/null
@@ -1,449 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import re
-import urllib
-from urllib2 import HTTPError
-from urlparse import urlparse, urljoin, parse_qs
-from collections import defaultdict
-import logging
-import os
-
-import requests
-from BeautifulSoup import BeautifulSoup
-from formencode import validators as fev
-
-from allura.lib import helpers as h
-from allura import model as M
-from forgeimporters.base import ProjectExtractor
-from forgeimporters.base import File
-
-
-log = logging.getLogger(__name__)
-
-
-def _as_text(node, chunks=None):
- """
- Similar to node.text, but preserves whitespace around tags,
- and converts <br/>s to \n.
- """
- if chunks is None:
- chunks = []
- for n in node:
- if isinstance(n, basestring):
- chunks.append(n)
- elif n.name == 'br':
- chunks.append('\n')
- else:
- _as_text(n, chunks)
- return ''.join(chunks)
-
-
-def _as_markdown(tag, project_name):
- fragments = []
- for fragment in tag:
- if getattr(fragment, 'name', None) == 'a':
- href = urlparse(fragment['href'])
- qs = parse_qs(href.query)
- gc_link = not href.netloc or href.netloc == 'code.google.com'
- path_parts = href.path.split('/')
- target_project = None
- if gc_link:
- if len(path_parts) >= 5 and path_parts[1] == 'a':
- target_project = '/'.join(path_parts[1:5])
- elif len(path_parts) >= 3:
- target_project = path_parts[2]
- internal_link = target_project == project_name
- if gc_link and internal_link and 'id' in qs:
- # rewrite issue 123 project-internal issue links
- fragment = '[%s](#%s)' % (fragment.text, qs['id'][0])
- elif gc_link and internal_link and 'r' in qs:
- # rewrite r123 project-internal revision links
- fragment = '[r%s]' % qs['r'][0]
- elif gc_link:
- # preserve GC-internal links (probably issue PROJECT:123
- # inter-project issue links)
- fragment = '[%s](%s)' % (
- h.plain2markdown(
- fragment.text, preserve_multiple_spaces=True, has_html_entities=True),
- # possibly need to adjust this URL for /a/ hosted domain URLs,
- # but it seems fragment['href'] always starts with / so it replaces the given path
- urljoin('https://code.google.com/p/%s/issues/' %
- project_name, fragment['href']),
- )
- else:
- # convert all other links to Markdown syntax
- fragment = '[%s](%s)' % (fragment.text, fragment['href'])
- elif getattr(fragment, 'name', None) == 'i':
- # preserve styling of "(No comment was entered for this change.)"
- # messages
- fragment = '*%s*' % h.plain2markdown(fragment.text,
- preserve_multiple_spaces=True, has_html_entities=True)
- elif getattr(fragment, 'name', None) == 'b':
- # preserve styling of issue template
- fragment = '**%s**' % h.plain2markdown(fragment.text,
- preserve_multiple_spaces=True, has_html_entities=True)
- elif getattr(fragment, 'name', None) == 'br':
- # preserve forced line-breaks
- fragment = '\n'
- else:
- # convert all others to plain MD
- fragment = h.plain2markdown(
- unicode(fragment), preserve_multiple_spaces=True, has_html_entities=True)
- fragments.append(fragment)
- return ''.join(fragments).strip()
-
-
-def csv_parser(page):
- lines = page.readlines()
- if not lines:
- return []
- # skip CSV header
- lines = lines[1:]
- # skip "next page here" info footer
- if not lines[-1].startswith('"'):
- lines.pop()
- # remove CSV wrapping (quotes, commas, newlines)
- return [line.strip('",\n') for line in lines]
-
-
-class GoogleCodeProjectNameValidator(fev.FancyValidator):
- not_empty = True
- messages = {
- 'invalid': 'Please enter a project URL, or a project name containing '
- 'only letters, numbers, and dashes.',
- 'unavailable': 'This project is unavailable for import',
- }
-
- def _to_python(self, value, state=None):
- project_name_re = re.compile(r'^[a-z0-9][a-z0-9-]{,61}$')
- if project_name_re.match(value):
- # just a name
- project_name = value
- else:
- # try as a URL
- project_name = None
- project_name_simple = None
- url = urlparse(value.strip())
- if url.netloc.endswith('.googlecode.com'):
- project_name = url.netloc.split('.')[0]
- elif url.netloc == 'code.google.com':
- path_parts = url.path.lstrip('/').split('/')
- if len(path_parts) >= 2 and path_parts[0] == 'p':
- project_name = path_parts[1]
- elif len(path_parts) >= 4 and path_parts[0] == 'a' and path_parts[2] == 'p':
- project_name_simple = path_parts[3]
- project_name = '/'.join(path_parts[0:4])
-
- if not project_name_simple:
- project_name_simple = project_name
-
- if not project_name or not project_name_re.match(project_name_simple):
- raise fev.Invalid(self.message('invalid', state), value, state)
-
- if not GoogleCodeProjectExtractor(project_name).check_readable():
- raise fev.Invalid(self.message('unavailable', state), value, state)
- return project_name
-
-
-def split_project_name(project_name):
- '''
- For hosted projects, the project_name includes the hosted domain. Split, like:
-
- :param str project_name: "a/eclipselabs.org/p/restclient-tool"
- :return: ``("/a/eclipselabs.org", "restclient-tool")``
- '''
- if project_name.startswith('a/'):
- hosted_domain_prefix = '/a/' + project_name.split('/')[1]
- project_name = project_name.split('/')[3]
- else:
- hosted_domain_prefix = ''
- project_name = project_name
- return hosted_domain_prefix, project_name
-
-
-class GoogleCodeProjectExtractor(ProjectExtractor):
- BASE_URL = 'http://code.google.com'
- RE_REPO_TYPE = re.compile(r'(svn|hg|git)')
-
- PAGE_MAP = {
- 'project_info': BASE_URL + '{hosted_domain_prefix}/p/{project_name}/',
- 'source_browse': BASE_URL + '{hosted_domain_prefix}/p/{project_name}/source/browse/',
- 'issues_csv': BASE_URL + '{hosted_domain_prefix}/p/{project_name}/issues/csv?can=1&colspec=ID&sort=ID&start={start}',
- 'issue': BASE_URL + '{hosted_domain_prefix}/p/{project_name}/issues/detail?id={issue_id}',
- }
-
- LICENSE_MAP = defaultdict(lambda: 'Other/Proprietary License', {
- 'Apache License 2.0': 'Apache License V2.0',
- 'Artistic License/GPL': 'Artistic License',
- 'Eclipse Public License 1.0': 'Eclipse Public License',
- 'GNU GPL v2': 'GNU General Public License version 2.0 (GPLv2)',
- 'GNU GPL v3': 'GNU General Public License version 3.0 (GPLv3)',
- 'GNU Lesser GPL': 'GNU Library or Lesser General Public License version 2.0 (LGPLv2)',
- 'MIT License': 'MIT License',
- 'Mozilla Public License 1.1': 'Mozilla Public License 1.1 (MPL 1.1)',
- 'New BSD License': 'BSD License',
- 'Other Open Source': 'Open Software License',
- })
-
- DEFAULT_ICON = 'http://www.gstatic.com/codesite/ph/images/defaultlogo.png'
-
- def get_page_url(self, page_name, **kw):
- # override, to handle hosted domains
- hosted_domain_prefix, project_name = split_project_name(self.project_name)
- return self.PAGE_MAP[page_name].format(
- project_name=urllib.quote(project_name),
- hosted_domain_prefix=hosted_domain_prefix,
- **kw)
-
- def check_readable(self):
- resp = requests.head(self.get_page_url('project_info'))
- return resp.status_code == 200
-
- def get_short_description(self, project):
- page = self.get_page('project_info')
- project.short_description = page.find(
- itemprop='description').text.strip()
-
- def get_icon(self, project):
- page = self.get_page('project_info')
- icon_url = urljoin(self.url, page.find(itemprop='image').get('src'))
- if icon_url == self.DEFAULT_ICON:
- return
- icon_name = urllib.unquote(urlparse(icon_url).path).split('/')[-1]
- icon = File(icon_url, icon_name)
- filetype = icon.type
- # work around Google Code giving us bogus file type
- if filetype.startswith('text/html'):
- filetype = 'image/png'
- M.ProjectFile.save_image(
- icon_name, icon.file, filetype,
- square=True, thumbnail_size=(48, 48),
- thumbnail_meta={'project_id': project._id, 'category': 'icon'})
-
- def get_license(self, project):
- page = self.get_page('project_info')
- license = page.find(text='Code license').findNext().find(
- 'a').text.strip()
- trove = M.TroveCategory.query.get(fullname=self.LICENSE_MAP[license])
- project.trove_license.append(trove._id)
-
- def get_repo_type(self):
- page = self.get_page('source_browse')
- repo_type = page.find(id="crumb_root")
- if not repo_type:
- raise Exception("Couldn't detect repo type: no #crumb_root in "
- "{0}".format(self.url))
- re_match = self.RE_REPO_TYPE.match(repo_type.text.lower())
- if re_match:
- return re_match.group(0)
- else:
- raise Exception("Unknown repo type: {0}".format(repo_type.text))
-
- @classmethod
- def iter_issues(cls, project_name):
- """
- Iterate over all issues for a project,
- using paging to keep the responses reasonable.
- """
- extractor = cls(project_name)
- issue_ids = extractor.get_issue_ids(start=0)
- while issue_ids:
- for issue_id in sorted(issue_ids):
- try:
- yield (int(issue_id), cls(project_name, 'issue', issue_id=issue_id))
- except HTTPError as e:
- if e.code == 404:
- log.warn('Unable to load GC issue: %s #%s: %s: %s',
- project_name, issue_id, e, e.url)
- continue
- else:
- raise
- # get any new issues that were created while importing
- # (jumping back a few in case some were deleted and new ones added)
- new_ids = extractor.get_issue_ids(start=len(issue_ids) - 10)
- issue_ids = new_ids - issue_ids
-
- def get_issue_ids(self, start=0):
- limit = 100
-
- issue_ids = set()
- page = self.get_page('issues_csv', parser=csv_parser, start=start)
- while page:
- if len(page) <= 0:
- return
- issue_ids.update(page)
- start += limit
- page = self.get_page('issues_csv', parser=csv_parser, start=start)
- return issue_ids
-
- def get_issue_summary(self):
- text = self.page.find(id='issueheader').findAll(
- 'td', limit=2)[1].span.text.strip()
- bs = BeautifulSoup(text, convertEntities=BeautifulSoup.HTML_ENTITIES)
- return bs.text
-
- def get_issue_description(self):
- return _as_markdown(self.page.find(id='hc0').pre, self.project_name)
-
- def get_issue_created_date(self):
- return self.page.find(id='hc0').find('span', 'date').get('title')
-
- def get_issue_mod_date(self):
- comments = list(self.iter_comments())
- if comments:
- last_update = comments[-1]
- return last_update.created_date
- else:
- return self.get_issue_created_date()
-
- def get_issue_creator(self):
- a = self.page.find(id='hc0').find(True, 'userlink')
- return UserLink(a)
-
- def get_issue_status(self):
- tag = self.page.find(id='issuemeta').find(
- 'th', text=re.compile('Status:')).findNext().span
- if tag:
- return tag.text.strip()
- else:
- return ''
-
- def get_issue_owner(self):
- tag = self.page.find(id='issuemeta').find(
- 'th', text=re.compile('Owner:')).findNext().find(True, 'userlink')
- if tag:
- return UserLink(tag)
- else:
- return None
-
- def get_issue_labels(self):
- label_nodes = self.page.find(id='issuemeta').findAll('a', 'label')
- return [_as_text(l) for l in label_nodes]
-
- def get_issue_attachments(self):
- return _get_attachments(self.page.find(id='hc0'))
-
- def get_issue_stars(self):
- stars_re = re.compile(r'(\d+) (person|people) starred this issue')
- stars = self.page.find(id='issueheader').find(text=stars_re)
- if stars:
- return int(stars_re.search(stars).group(1))
- return 0
-
- def iter_comments(self):
- # first, get all pages if there are multiple pages of comments
- looking_for_comment_pages = True
- comment_page_urls = [self.url]
- while looking_for_comment_pages:
- first_comment = self.page.find('div', 'vt issuecomment')
- looking_for_comment_pages = False
- if first_comment and 'cursor_off' not in first_comment['class']:
- # this is not a real comment, just forward/back links
- for link in first_comment.findAll('a'):
- if link.text.startswith('Older'):
- prev_comments_page = urljoin(self.url, link['href'])
- comment_page_urls.insert(0, prev_comments_page)
- looking_for_comment_pages = True
- self.get_page(prev_comments_page) # prep for next iteration of loop
-
- # then go through those to get the actual comments
- for comment_page_url in comment_page_urls:
- self.get_page(comment_page_url)
- # regular comments have cursor_off class
- for comment in self.page.findAll('div', 'cursor_off vt issuecomment'):
- yield Comment(comment, self.project_name)
-
-
-
-
-
-class UserLink(object):
-
- def __init__(self, tag):
- self.name = tag.text.strip()
- if tag.get('href'):
- self.url = urljoin(
- GoogleCodeProjectExtractor.BASE_URL, tag.get('href'))
- else:
- self.url = None
-
- def __str__(self):
- if self.url:
- return '[{name}]({url})'.format(name=self.name, url=self.url)
- else:
- return self.name
-
-
-def _get_attachments(tag):
- attachment_links = tag.find('div', 'attachments')
- if attachment_links:
- attachments = []
- for a in attachment_links.findAll('a', text='Download'):
- url = a.parent.get('href')
- try:
- attachment = Attachment(url)
- except Exception:
- log.exception('Could not get attachment: %s', url)
- else:
- attachments.append(attachment)
- return attachments
- else:
- return []
-
-
-class Comment(object):
-
- def __init__(self, tag, project_name):
- self.author = UserLink(
- tag.find('span', 'author').find(True, 'userlink'))
- self.created_date = tag.find('span', 'date').get('title')
- self.body = _as_markdown(tag.find('pre'), project_name)
- self._get_updates(tag)
- self.attachments = _get_attachments(tag)
-
- def _get_updates(self, tag):
- _updates = tag.find('div', 'updates')
- self.updates = {
- b.text: b.nextSibling.strip()
- for b in _updates.findAll('b')} if _updates else {}
-
- @property
- def annotated_text(self):
- text = (
- u'*Originally posted by:* {author}\n'
- u'\n'
- u'{body}\n'
- u'\n'
- u'{updates}'
- ).format(
- author=self.author,
- body=self.body,
- updates='\n'.join(
- '**%s** %s' % (k, v)
- for k, v in self.updates.items()
- ),
- )
- return text
-
-
-class Attachment(File):
-
- def __init__(self, url):
- url = urljoin(GoogleCodeProjectExtractor.BASE_URL, url)
- filename = parse_qs(urlparse(url).query)['name'][0]
- super(Attachment, self).__init__(url, filename)
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/code.py b/ForgeImporters/forgeimporters/google/code.py
deleted file mode 100644
index 6a3f43c..0000000
--- a/ForgeImporters/forgeimporters/google/code.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import urllib2
-
-import formencode as fe
-from formencode import validators as fev
-
-from pylons import tmpl_context as c
-from pylons import app_globals as g
-from tg import (
- expose,
- flash,
- redirect,
-)
-from tg.decorators import (
- with_trailing_slash,
- without_trailing_slash,
-)
-
-from allura.lib import validators as v
-from allura.lib.decorators import require_post
-from allura import model as M
-
-from forgeimporters.base import (
- ToolImporter,
- ToolImportController,
-)
-from forgeimporters.google import GoogleCodeProjectExtractor
-from forgeimporters.google import GoogleCodeProjectNameValidator
-from forgeimporters.google import split_project_name
-
-REPO_URLS = {
- 'svn': 'http://{project_name}.googlecode.com/svn/',
- 'svn-hosted': 'http://svn.codespot.com{hosted_domain_prefix}/{project_name}/',
- 'git': 'https://code.google.com{hosted_domain_prefix}/p/{project_name}/',
- 'hg': 'https://code.google.com{hosted_domain_prefix}/p/{project_name}/',
-}
-
-
-def get_repo_url(project_name, type_):
- hosted_domain_prefix, project_name = split_project_name(project_name)
- if hosted_domain_prefix and type_ == 'svn':
- type_ = 'svn-hosted'
- return REPO_URLS[type_].format(project_name=project_name,
- hosted_domain_prefix=hosted_domain_prefix)
-
-
-class GoogleRepoImportForm(fe.schema.Schema):
- gc_project_name = GoogleCodeProjectNameValidator()
- mount_point = fev.UnicodeString()
- mount_label = fev.UnicodeString()
-
- def __init__(self, *args):
- pass
-
- def _to_python(self, value, state):
- value = super(self.__class__, self)._to_python(value, state)
-
- gc_project_name = value['gc_project_name']
- mount_point = value['mount_point']
- try:
- repo_type = GoogleCodeProjectExtractor(
- gc_project_name).get_repo_type()
- except urllib2.HTTPError as e:
- if e.code == 404:
- msg = 'No such project'
- else:
- msg = str(e)
- msg = 'gc_project_name:' + msg
- raise fe.Invalid(msg, value, state)
- except Exception:
- raise
- tool_class = g.entry_points['tool'][repo_type]
- try:
- value['mount_point'] = v.MountPointValidator(
- tool_class).to_python(mount_point)
- except fe.Invalid as e:
- raise fe.Invalid('mount_point:' + str(e), value, state)
- return value
-
-
-class GoogleRepoImportController(ToolImportController):
- import_form = GoogleRepoImportForm
-
- @with_trailing_slash
- @expose('jinja:forgeimporters.google:templates/code/index.html')
- def index(self, **kw):
- return dict(importer=self.importer,
- target_app=self.target_app)
-
- @without_trailing_slash
- @expose()
- @require_post()
- def create(self, gc_project_name, mount_point, mount_label, **kw):
- if self.importer.enforce_limit(c.project):
- self.importer.post(
- project_name=gc_project_name,
- mount_point=mount_point,
- mount_label=mount_label)
- flash('Repo import has begun. Your new repo will be available '
- 'when the import is complete.')
- else:
- flash(
- 'There are too many imports pending at this time. Please wait and try again.', 'error')
- redirect(c.project.url() + 'admin/')
-
-
-class GoogleRepoImporter(ToolImporter):
- target_app_ep_names = ('git', 'hg', 'svn')
- source = 'Google Code'
- controller = GoogleRepoImportController
- tool_label = 'Source Code'
- tool_description = 'Import your primary SVN, Git, or Hg repo from Google Code'
-
- def import_tool(self, project, user, project_name=None, mount_point=None,
- mount_label=None, **kw):
- """ Import a Google Code repo into a new SVN, Git, or Hg Allura tool.
-
- """
- extractor = GoogleCodeProjectExtractor(project_name, 'source_browse')
- repo_type = extractor.get_repo_type()
- repo_url = get_repo_url(project_name, repo_type)
- app = project.install_app(
- repo_type,
- mount_point=mount_point or 'code',
- mount_label=mount_label or 'Code',
- init_from_url=repo_url,
- import_id={
- 'source': self.source,
- 'project_name': project_name,
- }
- )
- M.AuditLog.log(
- 'import tool %s from %s on %s' % (
- app.config.options.mount_point,
- project_name, self.source,
- ), project=project, user=user, url=app.url)
- g.post_event('project_updated')
- return app
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/project.py b/ForgeImporters/forgeimporters/google/project.py
deleted file mode 100644
index 9ffade1..0000000
--- a/ForgeImporters/forgeimporters/google/project.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from tg import expose, validate
-from tg.decorators import with_trailing_slash
-
-from allura.lib.decorators import require_post
-
-from forgeimporters import base
-from forgeimporters.google import tasks
-from forgeimporters.google import GoogleCodeProjectNameValidator
-
-
-log = logging.getLogger(__name__)
-
-
-class GoogleCodeProjectForm(base.ProjectImportForm):
- project_name = GoogleCodeProjectNameValidator()
-
-
-class GoogleCodeProjectImporter(base.ProjectImporter):
-
- """
- Project importer for Google Code.
-
- This imports project metadata, including summary, icon, and license,
- as well as providing the UI for importing individual tools during project
- import.
- """
- source = 'Google Code'
- process_validator = GoogleCodeProjectForm(source)
- index_template = 'jinja:forgeimporters.google:templates/project.html'
-
- def after_project_create(self, project, **kw):
- project.set_tool_data('google-code', project_name=project.name)
- tasks.import_project_info.post(project.name)
-
- @with_trailing_slash
- @expose(index_template)
- def index(self, **kw):
- return super(self.__class__, self).index(**kw)
-
- @require_post()
- @expose()
- @validate(process_validator, error_handler=index)
- def process(self, **kw):
- return super(self.__class__, self).process(**kw)
-
- @expose('json:')
- @validate(process_validator)
- def check_names(self, **kw):
- return super(self.__class__, self).check_names(**kw)
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tasks.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tasks.py b/ForgeImporters/forgeimporters/google/tasks.py
deleted file mode 100644
index b0cb76f..0000000
--- a/ForgeImporters/forgeimporters/google/tasks.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from pylons import tmpl_context as c
-from pylons import app_globals as g
-
-from ming.orm import ThreadLocalORMSession
-
-from allura.lib.decorators import task
-
-from forgeimporters.base import ImportErrorHandler
-from forgeimporters.google import GoogleCodeProjectExtractor
-
-
-@task
-def import_project_info(project_name):
- from forgeimporters.google.project import GoogleCodeProjectImporter
- importer = GoogleCodeProjectImporter(None)
- with ImportErrorHandler(importer, project_name, c.project) as handler:
- extractor = GoogleCodeProjectExtractor(project_name, 'project_info')
- extractor.get_short_description(c.project)
- extractor.get_icon(c.project)
- extractor.get_license(c.project)
- ThreadLocalORMSession.flush_all()
- g.post_event('project_updated')
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/templates/code/index.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/code/index.html b/ForgeImporters/forgeimporters/google/templates/code/index.html
deleted file mode 100644
index e2cef0c..0000000
--- a/ForgeImporters/forgeimporters/google/templates/code/index.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{#-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--#}
-{% extends 'forgeimporters:templates/importer_base.html' %}
-
-{% block title %}
-{{c.project.name}} / Import your repo from Google Code
-{% endblock %}
-
-{% block importer_fields %}
-<div>
- <label for="gc_project_name">Google Code project name (as it appears in a URL)</label>
- <input name="gc_project_name" value="{{ c.form_values['gc_project_name'] }}" />
- {{ error('gc_project_name') }}
-</div>
-{% endblock %}
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/templates/project.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/project.html b/ForgeImporters/forgeimporters/google/templates/project.html
deleted file mode 100644
index a00c0dd..0000000
--- a/ForgeImporters/forgeimporters/google/templates/project.html
+++ /dev/null
@@ -1,68 +0,0 @@
-{#-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--#}
-{% extends 'forgeimporters:templates/project_base.html' %}
-
-{% block extra_js %}
- {{super()}}
- <script type="text/javascript">
- function suggest_name() { // overrides base suggest_names
- var $project_shortname = $('#project_shortname');
- if (!manual) {
- var name_or_url = $('#project_name').val().replace(/\s/g, '').toLowerCase();
- name_or_url = name_or_url.replace(/\/$/, ''); // strip any trailing slash
- var a = $('<a>', {href: name_or_url})[0]; // leverage DOM to parse URL
- var project_name;
- var old_style = a.hostname.match(/^(.*)\.googlecode\.com$/);
- if (old_style) {
- project_name = old_style[1];
- } else {
- var parts = a.pathname.split('/');
- project_name = parts.pop();
- }
- $project_shortname.val(project_name);
- }
- $project_shortname.trigger('change');
- }
- </script>
-{% endblock %}
-
-{% block project_fields %}
- <div class="grid-7">
- <label>Google Project Name or URL</label>
- </div>
- <div class="grid-10">
- <input id="project_name" name="project_name" value="{{c.form_values['project_name']}}" autofocus/>
- <div id="project_name_error" class="error{% if not c.form_errors['project_name'] %} hidden{% endif %}">
- {{c.form_errors['project_name']}}
- </div>
- </div>
-
- <div class="grid-7" style="clear:left">
- <label>{{config.site_name}} URL Name</label>
- </div>
- <div class="grid-10">
- <input id="project_shortname" name="project_shortname" value="{{c.form_values['project_shortname']}}"/>
- <div id="project_shortname_error" class="error{% if not c.form_errors['project_shortname'] %} hidden{% endif %}">
- {{c.form_errors['project_shortname']}}
- </div>
- <div id="project-url">
- http://{{request.environ['HTTP_HOST']}}{{importer.neighborhood.url()}}<span id="url-fragment">{{c.form_values['project_shortname']}}</span>
- </div>
- </div>
-{% endblock %}
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/templates/tracker/index.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/tracker/index.html b/ForgeImporters/forgeimporters/google/templates/tracker/index.html
deleted file mode 100644
index 08d0084..0000000
--- a/ForgeImporters/forgeimporters/google/templates/tracker/index.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{#-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--#}
-{% extends 'forgeimporters:templates/importer_base.html' %}
-
-{% block importer_fields %}
-<div>
- <label for="gc_project_name">Google Code project name (as it appears in a URL)</label>
- <input name="gc_project_name" value="{{ c.form_values['gc_project_name'] }}" />
- {{ error('gc_project_name') }}
-</div>
-{% endblock %}
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tests/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/__init__.py b/ForgeImporters/forgeimporters/google/tests/__init__.py
deleted file mode 100644
index 144e298..0000000
--- a/ForgeImporters/forgeimporters/google/tests/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tests/test_code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/test_code.py b/ForgeImporters/forgeimporters/google/tests/test_code.py
deleted file mode 100644
index 1b6cacc..0000000
--- a/ForgeImporters/forgeimporters/google/tests/test_code.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from unittest import TestCase
-from mock import Mock, patch
-from ming.odm import ThreadLocalORMSession
-
-from allura.tests import TestController
-from allura import model as M
-
-
-# important to be distinct from 'test' which ForgeSVN uses, so that the
-# tests can run in parallel and not clobber each other
-test_project_with_repo = 'test2'
-
-
-from forgeimporters.google.code import (
- get_repo_url,
- GoogleRepoImporter,
-)
-
-
-class TestGetRepoUrl(TestCase):
-
- def test_svn(self):
- r = get_repo_url('projname', 'svn')
- self.assertEqual(r, 'http://projname.googlecode.com/svn/')
-
- def test_git(self):
- r = get_repo_url('projname', 'git')
- self.assertEqual(r, 'https://code.google.com/p/projname/')
-
- def test_hg(self):
- r = get_repo_url('projname', 'hg')
- self.assertEqual(r, 'https://code.google.com/p/projname/')
-
- def test_svn_hosted(self):
- r = get_repo_url('a/eclipselabs.org/p/projname', 'svn')
- self.assertEqual(r, 'http://svn.codespot.com/a/eclipselabs.org/projname/')
-
- def test_git_hosted(self):
- r = get_repo_url('a/eclipselabs.org/p/projname', 'git')
- self.assertEqual(r, 'https://code.google.com/a/eclipselabs.org/p/projname/')
-
- def test_hg_hosted(self):
- r = get_repo_url('a/eclipselabs.org/p/projname', 'hg')
- self.assertEqual(r, 'https://code.google.com/a/eclipselabs.org/p/projname/')
-
-
-class TestGoogleRepoImporter(TestCase):
-
- def _make_project(self, gc_proj_name=None):
- project = Mock()
- project.get_tool_data.side_effect = lambda *args: gc_proj_name
- return project
-
- @patch('forgeimporters.google.code.g')
- @patch('forgeimporters.google.code.M')
- @patch('forgeimporters.google.code.GoogleCodeProjectExtractor')
- @patch('forgeimporters.google.code.get_repo_url')
- def test_import_tool_happy_path(self, get_repo_url, gcpe, M, g):
- gcpe.return_value.get_repo_type.return_value = 'git'
- get_repo_url.return_value = 'http://remote/clone/url/'
- p = self._make_project(gc_proj_name='myproject')
- u = Mock(name='c.user')
- app = p.install_app.return_value
- app.config.options.mount_point = 'code'
- app.url = 'foo'
- GoogleRepoImporter().import_tool(p, u, project_name='project_name')
- get_repo_url.assert_called_once_with('project_name', 'git')
- p.install_app.assert_called_once_with('git',
- mount_point='code',
- mount_label='Code',
- init_from_url='http://remote/clone/url/',
- import_id={
- 'source': 'Google Code',
- 'project_name': 'project_name',
- },
- )
- M.AuditLog.log.assert_called_once_with(
- 'import tool code from project_name on Google Code',
- project=p, user=u, url='foo')
- g.post_event.assert_called_once_with('project_updated')
-
-
-class TestGoogleRepoImportController(TestController, TestCase):
-
- def test_index(self):
- r = self.app.get(
- '/p/{}/admin/ext/import/google-code-repo/'.format(test_project_with_repo))
- self.assertIsNotNone(r.html.find(attrs=dict(name="gc_project_name")))
- self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
- self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
-
- @patch('forgeimporters.google.code.GoogleCodeProjectExtractor')
- @patch('forgeimporters.base.import_tool')
- def test_create(self, import_tool, extractor):
- extractor.return_value.get_repo_type.return_value = 'git'
- params = dict(gc_project_name='poop',
- mount_label='mylabel',
- mount_point='mymount',
- )
- r = self.app.post(
- '/p/{}/admin/ext/import/google-code-repo/create'.format(test_project_with_repo),
- params,
- status=302)
- self.assertEqual(
- r.location, 'http://localhost/p/{}/admin/'.format(test_project_with_repo))
- self.assertEqual(
- u'mymount', import_tool.post.call_args[1]['mount_point'])
- self.assertEqual(
- u'mylabel', import_tool.post.call_args[1]['mount_label'])
- self.assertEqual(
- u'poop', import_tool.post.call_args[1]['project_name'])
-
- @patch('forgeimporters.google.code.GoogleCodeProjectExtractor')
- @patch('forgeimporters.base.import_tool')
- def test_create_limit(self, import_tool, extractor):
- extractor.return_value.get_repo_type.return_value = 'git'
- project = M.Project.query.get(shortname=test_project_with_repo)
- project.set_tool_data('GoogleRepoImporter', pending=1)
- ThreadLocalORMSession.flush_all()
- params = dict(gc_project_name='poop',
- mount_label='mylabel',
- mount_point='mymount',
- )
- r = self.app.post(
- '/p/{}/admin/ext/import/google-code-repo/create'.format(test_project_with_repo),
- params,
- status=302).follow()
- self.assertIn('Please wait and try again', r)
- self.assertEqual(import_tool.post.call_count, 0)
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tests/test_init.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/test_init.py b/ForgeImporters/forgeimporters/google/tests/test_init.py
deleted file mode 100644
index 37bf4c2..0000000
--- a/ForgeImporters/forgeimporters/google/tests/test_init.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from nose.tools import assert_equal
-from mock import patch
-from formencode.validators import Invalid
-from BeautifulSoup import BeautifulSoup
-from IPython.testing.decorators import skipif, module_not_available
-
-from allura.tests import decorators as td
-from forgeimporters.google import GoogleCodeProjectNameValidator, GoogleCodeProjectExtractor
-from forgeimporters.google import _as_markdown
-
-
-class TestGoogleCodeProjectNameValidator(object):
-
- def setUp(self):
- self.readable_patcher = patch.object(GoogleCodeProjectExtractor, 'check_readable')
- self.readable_mock = self.readable_patcher.start()
- self.readable_mock.return_value = True
-
- def tearDown(self):
- self.readable_patcher.stop()
-
- def test_simple(self):
- assert_equal(
- GoogleCodeProjectNameValidator()._to_python('gmapcatcher'),
- 'gmapcatcher'
- )
-
- def test_code_dot_google(self):
- assert_equal(
- GoogleCodeProjectNameValidator()._to_python('http://code.google.com/p/gmapcatcher/'),
- 'gmapcatcher'
- )
- assert_equal(
- GoogleCodeProjectNameValidator()._to_python('https://code.google.com/p/gmapcatcher/'),
- 'gmapcatcher'
- )
-
- def test_googlecode_com(self):
- assert_equal(
- GoogleCodeProjectNameValidator()._to_python('http://gmapcatcher.googlecode.com/'),
- 'gmapcatcher'
- )
- assert_equal(
- GoogleCodeProjectNameValidator()._to_python('https://gmapcatcher.googlecode.com/'),
- 'gmapcatcher'
- )
-
- def test_not_readable(self):
- self.readable_mock.return_value = False
- with td.raises(Invalid):
- GoogleCodeProjectNameValidator()._to_python('gmapcatcher')
-
- def test_invalid(self):
- with td.raises(Invalid):
- GoogleCodeProjectNameValidator()._to_python('http://code.google.com/')
- with td.raises(Invalid):
- GoogleCodeProjectNameValidator()._to_python('http://foobar.com/p/gmapcatcher')
- with td.raises(Invalid):
- GoogleCodeProjectNameValidator()._to_python('http://code.google.com/p/asdf_asdf')
- with td.raises(Invalid):
- GoogleCodeProjectNameValidator()._to_python('http://code.google.com/x/y/z')
-
- def test_hosted_domain(self):
- assert_equal(
- GoogleCodeProjectNameValidator()._to_python('https://code.google.com/a/eclipselabs.org/p/restclient-tool'),
- 'a/eclipselabs.org/p/restclient-tool'
- )
- with td.raises(Invalid):
- GoogleCodeProjectNameValidator()._to_python('http://code.google.com/a/eclipselabs.org/bogus')
-
-
-class Test_as_markdown(object):
-
- # this is covered by functional tests (useing test-issue.html)
- # but adding some unit tests for easier verification of hosted domain link rewriting
-
- def test_link_within_proj(self):
- html = BeautifulSoup('''<pre>Foo: <a href="/p/myproj/issues/detail?id=1">issue 1</a></pre>''')
- assert_equal(
- _as_markdown(html.first(), 'myproj'),
- 'Foo: [issue 1](#1)'
- )
-
- @skipif(module_not_available('html2text'))
- def test_link_other_proj_has_html2text(self):
- html = BeautifulSoup('''<pre>Foo: <a href="/p/other-project/issues/detail?id=1">issue other-project:1</a></pre>''')
- assert_equal(
- _as_markdown(html.first(), 'myproj'),
- 'Foo: [issue other-project:1](https://code.google.com/p/other-project/issues/detail?id=1)'
- )
-
- @td.without_module('html2text')
- def test_link_other_proj_no_html2text(self):
- # without html2text, the dash in other-project doesn't get escaped right
- html = BeautifulSoup('''<pre>Foo: <a href="/p/other-project/issues/detail?id=1">issue other-project:1</a></pre>''')
- assert_equal(
- _as_markdown(html.first(), 'myproj'),
- 'Foo: [issue other\\-project:1](https://code.google.com/p/other-project/issues/detail?id=1)'
- )
-
- def test_link_hosted_domain_within_proj(self):
- html = BeautifulSoup('''<pre>Foo: <a href="/a/eclipselabs.org/p/myproj/issues/detail?id=1">issue 1</a></pre>''')
- assert_equal(
- _as_markdown(html.first(), 'a/eclipselabs.org/p/myproj'),
- 'Foo: [issue 1](#1)'
- )
-
- def test_link_hosted_domain_other_proj(self):
- html = BeautifulSoup('''<pre>Foo: <a href="/a/eclipselabs.org/p/other-proj/issues/detail?id=1">issue 1</a></pre>''')
- assert_equal(
- _as_markdown(html.first(), 'a/eclipselabs.org/p/myproj'),
- 'Foo: [issue 1](https://code.google.com/a/eclipselabs.org/p/other-proj/issues/detail?id=1)'
- )
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
deleted file mode 100644
index 7873aa6..0000000
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from collections import defaultdict
-
-from pylons import tmpl_context as c
-from pylons import app_globals as g
-from ming.orm import session, ThreadLocalORMSession
-import dateutil.parser
-
-from tg import (
- expose,
- flash,
- redirect,
-)
-from tg.decorators import (
- with_trailing_slash,
- without_trailing_slash,
-)
-
-from allura.lib import helpers as h
-from allura.lib.plugin import ImportIdConverter
-from allura.lib.decorators import require_post
-from allura import model as M
-
-from forgetracker import model as TM
-from forgeimporters.google import GoogleCodeProjectExtractor
-from forgeimporters.google import GoogleCodeProjectNameValidator
-from forgeimporters.base import (
- ToolImporter,
- ToolImportForm,
- ToolImportController,
-)
-
-
-class GoogleCodeTrackerImportForm(ToolImportForm):
- gc_project_name = GoogleCodeProjectNameValidator()
-
-
-class GoogleCodeTrackerImportController(ToolImportController):
- import_form = GoogleCodeTrackerImportForm
-
- @with_trailing_slash
- @expose('jinja:forgeimporters.google:templates/tracker/index.html')
- def index(self, **kw):
- return dict(importer=self.importer,
- target_app=self.target_app)
-
- @without_trailing_slash
- @expose()
- @require_post()
- def create(self, gc_project_name, mount_point, mount_label, **kw):
- if self.importer.enforce_limit(c.project):
- self.importer.post(
- project_name=gc_project_name,
- mount_point=mount_point,
- mount_label=mount_label,
- )
- flash('Ticket import has begun. Your new tracker will be available '
- 'when the import is complete.')
- else:
- flash(
- 'There are too many imports pending at this time. Please wait and try again.', 'error')
- redirect(c.project.url() + 'admin/')
-
-
-class GoogleCodeTrackerImporter(ToolImporter):
- source = 'Google Code'
- target_app_ep_names = 'tickets'
- controller = GoogleCodeTrackerImportController
- tool_label = 'Issues'
- tool_description = 'Import your public tickets from Google Code'
-
- field_types = defaultdict(lambda: 'string',
- milestone='milestone',
- priority='select',
- type='select',
- )
-
- def __init__(self, *args, **kwargs):
- super(GoogleCodeTrackerImporter, self).__init__(*args, **kwargs)
- self.open_milestones = set()
- self.custom_fields = {}
- self.max_ticket_num = 0
-
- def import_tool(self, project, user, project_name, mount_point=None,
- mount_label=None, **kw):
- import_id_converter = ImportIdConverter.get()
- app = project.install_app('tickets', mount_point, mount_label,
- EnableVoting=True,
- open_status_names='New Accepted Started',
- closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
- import_id={
- 'source': self.source,
- 'project_name': project_name,
- },
- )
- ThreadLocalORMSession.flush_all()
- try:
- M.session.artifact_orm_session._get().skip_mod_date = True
- with h.push_config(c, user=M.User.anonymous(), app=app):
- for ticket_num, issue in GoogleCodeProjectExtractor.iter_issues(project_name):
- self.max_ticket_num = max(ticket_num, self.max_ticket_num)
- ticket = TM.Ticket(
- app_config_id=app.config._id,
- custom_fields=dict(),
- ticket_num=ticket_num,
- import_id=import_id_converter.expand(ticket_num, app))
- self.process_fields(ticket, issue)
- self.process_labels(ticket, issue)
- self.process_comments(ticket, issue)
- session(ticket).flush(ticket)
- session(ticket).expunge(ticket)
- app.globals.custom_fields = self.postprocess_custom_fields()
- app.globals.last_ticket_num = self.max_ticket_num
- ThreadLocalORMSession.flush_all()
- M.AuditLog.log(
- 'import tool %s from %s on %s' % (
- app.config.options.mount_point,
- project_name, self.source,
- ),
- project=project,
- user=user,
- url=app.url,
- )
- g.post_event('project_updated')
- app.globals.invalidate_bin_counts()
- return app
- except Exception:
- h.make_app_admin_only(app)
- raise
- finally:
- M.session.artifact_orm_session._get().skip_mod_date = False
-
- def custom_field(self, name):
- if name not in self.custom_fields:
- self.custom_fields[name] = {
- 'type': self.field_types[name.lower()],
- 'label': name,
- 'name': u'_%s' % name.lower(),
- 'options': set(),
- }
- return self.custom_fields[name]
-
- def process_fields(self, ticket, issue):
- ticket.summary = issue.get_issue_summary()
- ticket.status = issue.get_issue_status()
- ticket.created_date = dateutil.parser.parse(
- issue.get_issue_created_date())
- ticket.mod_date = dateutil.parser.parse(issue.get_issue_mod_date())
- ticket.votes_up = issue.get_issue_stars()
- ticket.votes = issue.get_issue_stars()
- owner = issue.get_issue_owner()
- if owner:
- owner_line = '*Originally owned by:* {owner}\n'.format(owner=owner)
- else:
- owner_line = ''
- ticket.description = (
- u'*Originally created by:* {creator}\n'
- u'{owner}'
- u'\n'
- u'{body}').format(
- creator=issue.get_issue_creator(),
- owner=owner_line,
- body=issue.get_issue_description(),
- )
- ticket.add_multiple_attachments(issue.get_issue_attachments())
-
- def process_labels(self, ticket, issue):
- labels = set()
- custom_fields = defaultdict(set)
- for label in issue.get_issue_labels():
- if u'-' in label:
- name, value = label.split(u'-', 1)
- cf = self.custom_field(name)
- cf['options'].add(value)
- custom_fields[cf['name']].add(value)
- if cf['name'] == '_milestone' and ticket.status in c.app.globals.open_status_names:
- self.open_milestones.add(value)
- else:
- labels.add(label)
- ticket.labels = list(labels)
- ticket.custom_fields = {n: u', '.join(sorted(v))
- for n, v in custom_fields.iteritems()}
-
- def process_comments(self, ticket, issue):
- for comment in issue.iter_comments():
- p = ticket.discussion_thread.add_post(
- text=comment.annotated_text,
- ignore_security=True,
- timestamp=dateutil.parser.parse(comment.created_date),
- )
- p.add_multiple_attachments(comment.attachments)
-
- def postprocess_custom_fields(self):
- custom_fields = []
- for name, field in self.custom_fields.iteritems():
- if field['name'] == '_milestone':
- field['milestones'] = [{
- 'name': milestone,
- 'due_date': None,
- 'complete': milestone not in self.open_milestones,
- } for milestone in sorted(field['options'])]
- field['options'] = ''
- elif field['type'] == 'select':
- field['options'] = ' '.join(field['options'])
- else:
- field['options'] = ''
- custom_fields.append(field)
- return custom_fields
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/data/google/empty-issue.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/empty-issue.html b/ForgeImporters/forgeimporters/tests/data/google/empty-issue.html
deleted file mode 100644
index b2eef20..0000000
--- a/ForgeImporters/forgeimporters/tests/data/google/empty-issue.html
+++ /dev/null
@@ -1,306 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-<meta name="ROBOTS" content="NOARCHIVE" />
-<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico" />
-<script type="text/javascript">
-
-
-
-
- var codesite_token = null;
-
-
- var CS_env = {"assetHostPath":"http://www.gstatic.com/codesite/ph","projectHomeUrl":"/p/allura-google-importer","relativeBaseUrl":"","domainName":null,"projectName":"allura-google-importer","loggedInUserEmail":null,"profileUrl":null,"token":null,"assetVersionPath":"http://www.gstatic.com/codesite/ph/3783617020303179221"};
- var _gaq = _gaq || [];
- _gaq.push(
- ['siteTracker._setAccount', 'UA-18071-1'],
- ['siteTracker._trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
- })();
-
- </script>
-<title>Issue 5 -
- allura-google-importer -
-
- Empty Issue -
- Import Google Code projects to an Allura forge - Google Project Hosting
- </title>
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/core.css" />
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/ph_detail.css" />
-<!--[if IE]>
- <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/d_ie.css" >
-<![endif]-->
-<style type="text/css">
- .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
- .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
- .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
-
-
- .attachments { width:33%; border-top:2px solid #999; padding-top: 3px; margin-left: .7em;}
- .attachments table { margin-bottom: 0.75em; }
- .attachments table tr td { padding: 0; margin: 0; font-size: 95%; }
- .preview { border: 2px solid #c3d9ff; padding: 1px; }
- .preview:hover { border: 2px solid blue; }
- .label { white-space: nowrap; }
- .derived { font-style:italic }
- .cursor_on .author {
- background: url(http://www.gstatic.com/codesite/ph/images/show-arrow.gif) no-repeat 2px;
- }
- .hiddenform {
- display: none;
- }
-
-
- </style>
-</head>
-<body class="t3">
-<script type="text/javascript">
- window.___gcfg = {lang: 'en'};
- (function()
- {var po = document.createElement("script");
- po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
- var s = document.getElementsByTagName("script")[0];
- s.parentNode.insertBefore(po, s);
- })();
-</script>
-<div class="headbg">
-<div id="gaia">
-<span>
-<a href="#" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small>▼</small></a>
- | <a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5" onclick="_CS_click('/gb/ph/signin');"><u>Sign in</u></a>
-</span>
-</div>
-<div class="gbh" style="left: 0pt;"></div>
-<div class="gbh" style="right: 0pt;"></div>
-<div style="height: 1px"></div>
-<!--[if lte IE 7]>
-<div style="text-align:center;">
-Your version of Internet Explorer is not supported. Try a browser that
-contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
-<a href="http://www.google.com/chrome">Google Chrome</a>, or
-<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
-</div>
-<![endif]-->
-<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="itemscope" itemtype="http://schema.org/CreativeWork">
-<tr style="height: 58px;">
-<td id="plogo">
-<link itemprop="url" href="/p/allura-google-importer" />
-<a href="/p/allura-google-importer/">
-<img src="/p/allura-google-importer/logo?cct=1374769571" alt="Logo" itemprop="image" />
-</a>
-</td>
-<td style="padding-left: 0.5em">
-<div id="pname">
-<a href="/p/allura-google-importer/"><span itemprop="name">allura-google-importer</span></a>
-</div>
-<div id="psum">
-<a id="project_summary_link" href="/p/allura-google-importer/"><span itemprop="description">Import Google Code projects to an Allura forge</span></a>
-</div>
-</td>
-<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
-<form action="/hosting/search">
-<input size="30" name="q" value="" type="text" />
-<input type="submit" name="projectsearch" value="Search projects" />
-</form>
-</td></tr>
-</table>
-</div>
-<div id="mt" class="gtb">
-<a href="/p/allura-google-importer/" class="tab ">Project Home</a>
-<a href="/p/allura-google-importer/wiki/TestPage?tm=6" class="tab ">Wiki</a>
-<a href="/p/allura-google-importer/issues/list" class="tab active">Issues</a>
-<a href="/p/allura-google-importer/source/checkout" class="tab ">Source</a>
-<div class="gtbc"></div>
-</div>
-<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
-<tr>
-<td class="subt">
-<div class="issueDetail">
-<div class="isf">
-<span class="inIssueEntry">
-<a class="buttonify" href="entry" onclick="return _newIssuePrompt();">New issue</a>
-</span>
-
- <span class="inIssueList">
-<span>Search</span>
-</span><form action="list" method="GET" style="display:inline">
-<select id="can" name="can">
-<option disabled="disabled">Search within:</option>
-<option value="1"> All issues</option>
-<option value="2" selected="selected"> Open issues</option>
-<option value="6"> New issues</option>
-<option value="7"> Issues to verify</option>
-</select>
-<span>for</span>
-<span id="qq"><input type="text" size="38" id="searchq" name="q" value="" autocomplete="off" onkeydown="_blurOnEsc(event)" /></span>
-<span id="search_colspec"><input type="hidden" name="colspec" value="ID Type Status Priority Milestone Owner Summary" /></span>
-<input type="hidden" name="cells" value="tiles" />
-<input type="submit" value="Search" />
-</form>
-
- <span class="inIssueAdvSearch">
-<a href="advsearch">Advanced search</a>
-</span>
- <span class="inIssueSearchTips">
-<a href="searchtips">Search tips</a>
-</span>
- <span class="inIssueSubscriptions">
-<a href="/p/allura-google-importer/issues/subscriptions">Subscriptions</a>
-</span>
-</div>
-</div>
-</td>
-<td align="right" valign="top" class="bevel-right"></td>
-</tr>
-</table>
-<script type="text/javascript">
- var cancelBubble = false;
- function _go(url) { document.location = url; }
-</script>
-<div id="maincol">
-<div id="color_control" class="">
-<div id="issueheader">
-<table cellpadding="0" cellspacing="0" width="100%"><tbody>
-<tr>
-<td class="vt h3" nowrap="nowrap" style="padding:0 5px">
-
-
- Issue <a href="detail?id=5">5</a>:
- </td>
-<td width="90%" class="vt">
-<span class="h3">Empty Issue</span>
-</td>
-<td>
-<div class="pagination">
-<a href="../../allura-google-importer/issues/detail?id=4" title="Prev">‹ Prev</a>
- 5 of 5
-
- </div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td nowrap="nowrap">
-
-
- 1 person starred this issue and may be notified of changes.
-
-
-
- </td>
-<td align="center" nowrap="nowrap">
-<a href="http://code.google.com/p/allura-google-importer/issues/list?cursor=allura-google-importer%3A5">Back to list</a>
-</td>
-</tr>
-</tbody></table>
-</div>
-<table width="100%" cellpadding="0" cellspacing="0" border="0" class="issuepage" id="meta-container">
-<tbody class="collapse">
-<tr>
-<td id="issuemeta">
-<div id="meta-float">
-<table cellspacing="0" cellpadding="0">
-<tr><th align="left">Status: </th>
-<td width="100%">
-
-
- ----
-
-
- </td>
-</tr>
-<tr><th align="left">Owner: </th><td>
-
-
- ----
-
-
- </td>
-</tr>
-<tr><td colspan="2">
-</td></tr>
-</table>
-<div class="rel_issues">
-</div>
-<br /><br />
-<div style="white-space:nowrap"><a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5">Sign in</a> to add a comment</div>
-</div>
- </td>
-<td class="vt issuedescription" width="100%" id="cursorarea">
-<div class="cursor_off vt issuedescription" id="hc0">
-<div class="author">
-<span class="role_label">Project Member</span>
- Reported by
-
-
- <span class="userlink">john...@gmail.com</span>,
- <span class="date" title="Thu Aug 8 14:56:23 2013">Today (15 minutes ago)</span>
-</div>
-<pre>
-Empty
-</pre>
-</div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td class="vt issuecomment">
-<span class="indicator">►</span> <a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5">Sign in</a> to add a comment
- </td>
-</tr>
-</tbody>
-</table>
-<br />
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/dit_scripts.js"></script>
-</div>
-<form name="delcom" action="delComment.do?q=&can=2&groupby=&sort=&colspec=ID+Type+Status+Priority+Milestone+Owner+Summary" method="POST">
-<input type="hidden" name="sequence_num" value="" />
-<input type="hidden" name="mode" value="" />
-<input type="hidden" name="id" value="5" />
-<input type="hidden" name="token" value="" />
-</form>
-<div id="helparea"></div>
-<script type="text/javascript">
- _onload();
- function delComment(sequence_num, delete_mode) {
- var f = document.forms["delcom"];
- f.sequence_num.value = sequence_num;
- f.mode.value = delete_mode;
-
- f.submit();
- return false;
- }
-
- _floatMetadata();
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/kibbles.js"></script>
-<script type="text/javascript">
- _setupKibblesOnDetailPage(
- 'http://code.google.com/p/allura-google-importer/issues/list?cursor\x3dallura-google-importer%3A5',
- '/p/allura-google-importer/issues/entry',
- '../../allura-google-importer/issues/detail?id\x3d4',
- '',
- '', 'allura-google-importer', 5,
- false, false, codesite_token);
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/ph_core.js"></script>
-</div>
-<div id="footer" dir="ltr">
-<div class="text">
-<a href="/projecthosting/terms.html">Terms</a> -
- <a href="http://www.google.com/privacy.html">Privacy</a> -
- <a href="/p/support/">Project Hosting Help</a>
-</div>
-</div>
-<div class="hostedBy" style="margin-top: -20px;">
-<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
-</div>
-</body>
-</html>
[2/5] allura git commit: [#8054] edit few files for Google Code
importer removal
Posted by he...@apache.org.
[#8054] edit few files for Google Code importer removal
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d4dda577
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d4dda577
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d4dda577
Branch: refs/heads/master
Commit: d4dda57713baa3525ef6efb089688a1597a4c78f
Parents: b956fe3
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jan 26 13:59:03 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 13:42:50 2016 -0500
----------------------------------------------------------------------
Allura/development.ini | 6 +++---
Allura/docs/development/extending.rst | 6 +++---
ForgeImporters/setup.py | 3 ---
rat-excludes.txt | 4 ----
4 files changed, 6 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/d4dda577/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 930f7f3..e890cd7 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -357,8 +357,8 @@ importer_upload_path = /tmp/importer_upload/{nbhd}/{project}
; To disable any plugin, tool, importer, etc from being available, you can use the disable_entry_points config option.
; Specify the keys and values as they are declared in the tool's "setup.py" file.
; Examples:
-;disable_entry_points.importers = google-code-tracker, google-code-repo
-;disable_entry_points.allura.project_importers = google-code
+;disable_entry_points.allura.importers = github-tracker, github-wiki, github-repo
+;disable_entry_points.allura.project_importers = github
; Importers specifically, can be left enabled but not linked to. You have to know the URL to use it. Example:
;hidden_importers = trac-tickets
@@ -371,7 +371,7 @@ importer_upload_path = /tmp/importer_upload/{nbhd}/{project}
; If your site has docs about specific importers, you can add them here and
; they'll appear on the import forms
-;doc.url.importers.Google Code = http://...
+;doc.url.importers.GitHub = http://...
; List of oauth API keys permitted to use special forum import API
; (should be converted to newer importer system)
http://git-wip-us.apache.org/repos/asf/allura/blob/d4dda577/Allura/docs/development/extending.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/development/extending.rst b/Allura/docs/development/extending.rst
index e45b1c2..3132838 100644
--- a/Allura/docs/development/extending.rst
+++ b/Allura/docs/development/extending.rst
@@ -50,12 +50,12 @@ A listing of available 3rd-party extensions is at https://forge-allura.apache.or
To disable any Allura entry point, simply add an entry in your ``.ini`` config file
with names and values corresponding to entry points defined in any ``setup.py`` file.
-For example if you have ForgeImporter set up, but want to disable the google code importers:
+For example if you have ForgeImporter set up, but want to disable the GitHub importers:
.. code-block:: ini
- disable_entry_points.allura.project_importers = google-code
- disable_entry_points.allura.importers = google-code-tracker, google-code-repo
+ disable_entry_points.allura.project_importers = github
+ disable_entry_points.allura.importers = github-tracker, github-wiki, github-repo
Other entry points are used to provide ``paster`` commands and ``easy_widget`` configuration,
which are not part of Allura but are used by Allura.
http://git-wip-us.apache.org/repos/asf/allura/blob/d4dda577/ForgeImporters/setup.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/setup.py b/ForgeImporters/setup.py
index 4d5f866..2ad2726 100644
--- a/ForgeImporters/setup.py
+++ b/ForgeImporters/setup.py
@@ -34,14 +34,11 @@ setup(name='ForgeImporters',
entry_points="""
# -*- Entry points: -*-
[allura.project_importers]
- google-code = forgeimporters.google.project:GoogleCodeProjectImporter
trac = forgeimporters.trac.project:TracProjectImporter
github = forgeimporters.github.project:GitHubProjectImporter
[allura.importers]
github-tracker = forgeimporters.github.tracker:GitHubTrackerImporter
- google-code-tracker = forgeimporters.google.tracker:GoogleCodeTrackerImporter
- google-code-repo = forgeimporters.google.code:GoogleRepoImporter
github-wiki = forgeimporters.github.wiki:GitHubWikiImporter
github-repo = forgeimporters.github.code:GitHubRepoImporter
trac-tickets = forgeimporters.trac.tickets:TracTicketImporter
http://git-wip-us.apache.org/repos/asf/allura/blob/d4dda577/rat-excludes.txt
----------------------------------------------------------------------
diff --git a/rat-excludes.txt b/rat-excludes.txt
index 2771188..2e0d026 100644
--- a/rat-excludes.txt
+++ b/rat-excludes.txt
@@ -58,10 +58,6 @@ CHANGES
ForgeGit/forgegit/data/post-receive_tmpl
ForgeImporters/docs/make.bat
ForgeImporters/docs/Makefile
-ForgeImporters/forgeimporters/tests/data/google/empty-issue.html
-ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html
-ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html
-ForgeImporters/forgeimporters/tests/data/google/test-issue.html
ForgeImporters/forgeimporters/trac/tests/data/test-list.csv
ForgeImporters/forgeimporters/trac/tests/data/test-list.html
ForgeSVN/forgesvn/tests/data/
[3/5] allura git commit: [#8054] delete Google Code importers and
tests
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/test_extractor.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_extractor.py b/ForgeImporters/forgeimporters/tests/google/test_extractor.py
deleted file mode 100644
index 72a7d6c..0000000
--- a/ForgeImporters/forgeimporters/tests/google/test_extractor.py
+++ /dev/null
@@ -1,607 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from unittest import TestCase
-import pkg_resources
-from urllib2 import HTTPError
-
-import mock
-from datadiff.tools import assert_equal
-from IPython.testing.decorators import skipif, module_not_available
-from BeautifulSoup import BeautifulSoup
-
-from allura.tests.decorators import without_module
-from forgeimporters import google
-from forgeimporters import base
-
-
-class TestGoogleCodeProjectExtractor(TestCase):
-
- def setUp(self):
- self._p_urlopen = mock.patch.object(base.ProjectExtractor, 'urlopen')
- self._p_soup = mock.patch.object(base, 'BeautifulSoup')
- self.urlopen = self._p_urlopen.start()
- self.soup = self._p_soup.start()
- self.project = mock.Mock(name='project')
- self.project.get_tool_data.return_value = 'my-project'
-
- def tearDown(self):
- for patcher in ('_p_urlopen', '_p_soup'):
- try:
- getattr(self, patcher).stop()
- except RuntimeError as e:
- if 'unstarted patcher' in str(e):
- pass # test case might stop them early
- else:
- raise
-
- def test_init(self):
- extractor = google.GoogleCodeProjectExtractor(
- 'my-project', 'project_info')
-
- self.urlopen.assert_called_once_with(
- 'http://code.google.com/p/my-project/')
- self.soup.assert_called_once_with(self.urlopen.return_value, convertEntities=self.soup.HTML_ENTITIES)
- self.assertEqual(extractor.page, self.soup.return_value)
-
- def test_get_page(self):
- extractor = google.GoogleCodeProjectExtractor(
- 'my-project', 'project_info')
- self.assertEqual(1, self.urlopen.call_count)
- page = extractor.get_page('project_info')
- self.assertEqual(1, self.urlopen.call_count)
- self.assertEqual(
- page, extractor._page_cache['http://code.google.com/p/my-project/'])
- page = extractor.get_page('project_info')
- self.assertEqual(1, self.urlopen.call_count)
- self.assertEqual(
- page, extractor._page_cache['http://code.google.com/p/my-project/'])
- page = extractor.get_page('source_browse')
- self.assertEqual(2, self.urlopen.call_count)
- self.assertEqual(
- page, extractor._page_cache['http://code.google.com/p/my-project/source/browse/'])
- parser = mock.Mock(return_value='parsed')
- page = extractor.get_page('url', parser=parser)
- self.assertEqual(page, 'parsed')
- self.assertEqual(page, extractor._page_cache['url'])
-
- def test_get_page_url(self):
- extractor = google.GoogleCodeProjectExtractor('my-project')
- self.assertEqual(extractor.get_page_url('project_info'),
- 'http://code.google.com/p/my-project/')
-
- def test_get_page_url_hosted(self):
- extractor = google.GoogleCodeProjectExtractor('a/eclipselabs.org/p/restclient-tool')
- self.assertEqual(extractor.get_page_url('project_info'),
- 'http://code.google.com/a/eclipselabs.org/p/restclient-tool/')
-
- def test_get_short_description(self):
- extractor = google.GoogleCodeProjectExtractor(
- 'my-project', 'project_info')
- extractor.page.find.return_value.text = 'My Super Project'
-
- extractor.get_short_description(self.project)
-
- extractor.page.find.assert_called_once_with(itemprop='description')
- self.assertEqual(self.project.short_description, 'My Super Project')
-
- @mock.patch.object(google, 'File')
- @mock.patch.object(google, 'M')
- def test_get_icon(self, M, File):
- File.return_value.type = 'image/png'
- File.return_value.file = 'data'
- extractor = google.GoogleCodeProjectExtractor(
- 'my-project', 'project_info')
- extractor.page.find.return_value.get.return_value = 'http://example.com/foo/bar/my-logo.png'
-
- extractor.get_icon(self.project)
-
- extractor.page.find.assert_called_once_with(itemprop='image')
- File.assert_called_once_with(
- 'http://example.com/foo/bar/my-logo.png', 'my-logo.png')
- M.ProjectFile.save_image.assert_called_once_with(
- 'my-logo.png', 'data', 'image/png', square=True,
- thumbnail_size=(48, 48), thumbnail_meta={
- 'project_id': self.project._id, 'category': 'icon'})
-
- @mock.patch.object(google, 'M')
- def test_get_license(self, M):
- self.project.trove_license = []
- extractor = google.GoogleCodeProjectExtractor(
- 'my-project', 'project_info')
- extractor.page.find.return_value.findNext.return_value.find.return_value.text = ' New BSD License '
- trove = M.TroveCategory.query.get.return_value
-
- extractor.get_license(self.project)
-
- extractor.page.find.assert_called_once_with(text='Code license')
- extractor.page.find.return_value.findNext.assert_called_once_with()
- extractor.page.find.return_value.findNext.return_value.find.assert_called_once_with(
- 'a')
- self.assertEqual(self.project.trove_license, [trove._id])
- M.TroveCategory.query.get.assert_called_once_with(
- fullname='BSD License')
-
- M.TroveCategory.query.get.reset_mock()
- extractor.page.find.return_value.findNext.return_value.find.return_value.text = 'non-existant license'
- extractor.get_license(self.project)
- M.TroveCategory.query.get.assert_called_once_with(
- fullname='Other/Proprietary License')
-
- def _make_extractor(self, html):
- with mock.patch.object(base.ProjectExtractor, 'urlopen'):
- extractor = google.GoogleCodeProjectExtractor('allura-google-importer')
- extractor.page = BeautifulSoup(html)
- extractor.get_page = lambda pagename: extractor.page
- extractor.url = "http://test/source/browse"
- return extractor
-
- def test_get_repo_type_happy_path(self):
- extractor = self._make_extractor(
- '<span id="crumb_root">\nsvn/ </span>')
- self.assertEqual('svn', extractor.get_repo_type())
-
- def test_get_repo_type_no_crumb_root(self):
- extractor = self._make_extractor('')
- with self.assertRaises(Exception) as cm:
- extractor.get_repo_type()
- self.assertEqual(str(cm.exception),
- "Couldn't detect repo type: no #crumb_root in "
- "http://test/source/browse")
-
- def test_get_repo_type_unknown_repo_type(self):
- extractor = self._make_extractor(
- '<span id="crumb_root">cvs</span>')
- with self.assertRaises(Exception) as cm:
- extractor.get_repo_type()
- self.assertEqual(str(cm.exception), "Unknown repo type: cvs")
-
- def test_empty_issue(self):
- empty_issue = open(pkg_resources.resource_filename(
- 'forgeimporters', 'tests/data/google/empty-issue.html')).read()
- gpe = self._make_extractor(empty_issue)
- self.assertIsNone(gpe.get_issue_owner())
- self.assertEqual(gpe.get_issue_status(), '')
- self.assertEqual(gpe.get_issue_attachments(), [])
- self.assertEqual(list(gpe.iter_comments()), [])
- self.assertEqual(gpe.get_issue_mod_date(), 'Thu Aug 8 14:56:23 2013')
-
- @without_module('html2text')
- def test_get_issue_basic_fields(self):
- test_issue = open(pkg_resources.resource_filename(
- 'forgeimporters', 'tests/data/google/test-issue.html')).read()
- gpe = self._make_extractor(test_issue)
-
- self.assertEqual(gpe.get_issue_creator().name, 'john...@gmail.com')
- self.assertEqual(gpe.get_issue_creator().url,
- 'http://code.google.com/u/101557263855536553789/')
- self.assertEqual(gpe.get_issue_owner().name, 'john...@gmail.com')
- self.assertEqual(gpe.get_issue_owner().url,
- 'http://code.google.com/u/101557263855536553789/')
- self.assertEqual(gpe.get_issue_status(), 'Started')
- self._p_soup.stop()
- self.assertEqual(gpe.get_issue_summary(), 'Test "Issue"')
- assert_equal(gpe.get_issue_description(),
- 'Test \\*Issue\\* for testing\n'
- '\n'
- ' 1\\. Test List\n'
- ' 2\\. Item\n'
- '\n'
- '\\*\\*Testing\\*\\*\n'
- '\n'
- ' \\* Test list 2\n'
- ' \\* Item\n'
- '\n'
- '\\# Test Section\n'
- '\n'
- ' p = source\\.test\\_issue\\.post\\(\\)\n'
- ' p\\.count = p\\.count \\*5 \\#\\* 6\n'
- ' if p\\.count > 5:\n'
- ' print "Not < 5 & \\!= 5"\n'
- '\n'
- 'References: [issue 1](#1), [r2]\n'
- '\n'
- 'That\'s all'
- )
- self.assertEqual(gpe.get_issue_created_date(),
- 'Thu Aug 8 15:33:52 2013')
- self.assertEqual(gpe.get_issue_stars(), 1)
-
- @skipif(module_not_available('html2text'))
- def test_get_issue_basic_fields_html2text(self):
- test_issue = open(pkg_resources.resource_filename(
- 'forgeimporters', 'tests/data/google/test-issue.html')).read()
- gpe = self._make_extractor(test_issue)
- self.assertEqual(gpe.get_issue_creator().name, 'john...@gmail.com')
- self.assertEqual(gpe.get_issue_creator().url,
- 'http://code.google.com/u/101557263855536553789/')
- self.assertEqual(gpe.get_issue_owner().name, 'john...@gmail.com')
- self.assertEqual(gpe.get_issue_owner().url,
- 'http://code.google.com/u/101557263855536553789/')
- self.assertEqual(gpe.get_issue_status(), 'Started')
- self._p_soup.stop()
- self.assertEqual(gpe.get_issue_summary(), 'Test "Issue"')
- assert_equal(gpe.get_issue_description(),
- 'Test \\*Issue\\* for testing\n'
- '\n'
- ' 1. Test List\n'
- ' 2. Item\n'
- '\n'
- '\\*\\*Testing\\*\\*\n'
- '\n'
- ' \\* Test list 2\n'
- ' \\* Item\n'
- '\n'
- '\\# Test Section\n'
- '\n'
- ' p = source.test\\_issue.post\\(\\)\n'
- ' p.count = p.count \\*5 \\#\\* 6\n'
- ' if p.count > 5:\n'
- ' print "Not < 5 & \\!= 5"\n'
- '\n'
- 'References: [issue 1](#1), [r2]\n'
- '\n'
- 'That\'s all'
- )
- self.assertEqual(gpe.get_issue_created_date(),
- 'Thu Aug 8 15:33:52 2013')
- self.assertEqual(gpe.get_issue_stars(), 1)
-
- def test_get_issue_summary(self):
- html = u"""
- <div id="issueheader">
- <table>
- <tbody>
- <tr>
- <td></td>
- <td><span>%s</span></td>
- </tr>
- </tbody>
- </table>
- </div>
- """
- gpe = self._make_extractor(html % u'')
- self.assertEqual(gpe.get_issue_summary(), u'')
- gpe = self._make_extractor(html % u'My Summary')
- self.assertEqual(gpe.get_issue_summary(), u'My Summary')
-
- def test_get_issue_labels(self):
- test_issue = open(pkg_resources.resource_filename(
- 'forgeimporters', 'tests/data/google/test-issue.html')).read()
- gpe = self._make_extractor(test_issue)
- self.assertEqual(gpe.get_issue_labels(), [
- 'Type-Defect',
- 'Priority-Medium',
- 'Milestone-Release1.0',
- 'OpSys-All',
- 'Component-Logic',
- 'Performance',
- 'Security',
- 'OpSys-Windows',
- 'OpSys-OSX',
- ])
-
- @mock.patch.object(base, 'StringIO')
- def test_get_issue_attachments(self, StringIO):
- self.urlopen.return_value.info.return_value = {
- 'content-type': 'text/plain; foo'}
- test_issue = open(pkg_resources.resource_filename(
- 'forgeimporters', 'tests/data/google/test-issue.html')).read()
- gpe = self._make_extractor(test_issue)
- attachments = gpe.get_issue_attachments()
- self.assertEqual(len(attachments), 1)
- self.assertEqual(attachments[0].filename, 'at1.txt')
- self.assertEqual(attachments[0].url,
- 'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt'
- '&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255')
- self.assertEqual(attachments[0].type, 'text/plain')
-
- def test_get_issue_ids(self):
- extractor = google.GoogleCodeProjectExtractor(None)
- extractor.get_page = mock.Mock(side_effect=((1, 2, 3), (2, 3, 4), ()))
- self.assertItemsEqual(extractor.get_issue_ids(start=10), (1, 2, 3, 4))
- self.assertEqual(extractor.get_page.call_count, 3)
- extractor.get_page.assert_has_calls([
- mock.call('issues_csv', parser=google.csv_parser, start=10),
- mock.call('issues_csv', parser=google.csv_parser, start=110),
- mock.call('issues_csv', parser=google.csv_parser, start=210),
- ])
-
- @mock.patch.object(google.GoogleCodeProjectExtractor, 'get_page')
- @mock.patch.object(google.GoogleCodeProjectExtractor, 'get_issue_ids')
- def test_iter_issue_ids(self, get_issue_ids, get_page):
- get_issue_ids.side_effect = [set([1, 2]), set([2, 3, 4])]
- issue_ids = [i for i,
- e in list(google.GoogleCodeProjectExtractor.iter_issues('foo'))]
- self.assertEqual(issue_ids, [1, 2, 3, 4])
- get_issue_ids.assert_has_calls([
- mock.call(start=0),
- mock.call(start=-8),
- ])
-
- @mock.patch.object(google.GoogleCodeProjectExtractor, '__init__')
- @mock.patch.object(google.GoogleCodeProjectExtractor, 'get_issue_ids')
- def test_iter_issue_ids_raises(self, get_issue_ids, __init__):
- get_issue_ids.side_effect = [set([1, 2, 3, 4, 5])]
- __init__.side_effect = [
- None,
- None,
- # should skip but keep going
- HTTPError('fourohfour', 404, 'fourohfour', {}, mock.Mock()),
- None,
- # should be re-raised
- HTTPError('fubar', 500, 'fubar', {}, mock.Mock()),
- None,
- ]
- issue_ids = []
- try:
- for issue_id, extractor in google.GoogleCodeProjectExtractor.iter_issues('foo'):
- issue_ids.append(issue_id)
- except HTTPError as e:
- self.assertEqual(e.code, 500)
- else:
- assert False, 'Missing expected raised exception'
- self.assertEqual(issue_ids, [1, 3])
-
- @mock.patch.object(google.requests, 'head')
- def test_check_readable(self, head):
- head.return_value.status_code = 200
- assert google.GoogleCodeProjectExtractor('my-project').check_readable()
- head.return_value.status_code = 404
- assert not google.GoogleCodeProjectExtractor('my-project').check_readable()
-
-
-class TestWithSetupForComments(TestCase):
- # The main test suite did too much patching for how we want these tests to work
- # These tests use iter_comments and 2 HTML pages of comments.
-
- def _create_extractor(self):
- test_issue = open(pkg_resources.resource_filename(
- 'forgeimporters', 'tests/data/google/test-issue-first-page.html')).read()
- test_issue_older = open(pkg_resources.resource_filename(
- 'forgeimporters', 'tests/data/google/test-issue-prev-page.html')).read()
-
- class LocalTestExtractor(google.GoogleCodeProjectExtractor):
- def urlopen(self, url, **kw):
- return self.urlopen_results.pop(0)
-
- def setup_urlopen_results(self, results):
- self.urlopen_results = results
-
- gpe = LocalTestExtractor('allura-google-importer')
- gpe.setup_urlopen_results([test_issue, test_issue_older])
-
- return gpe
-
- def test_get_issue_mod_date(self):
- gpe = self._create_extractor()
- gpe.get_page('detail?id=6')
- self.assertEqual(gpe.get_issue_mod_date(), 'Thu Aug 8 15:36:57 2013')
-
- @without_module('html2text')
- @mock.patch.object(base, 'StringIO')
- def test_iter_comments(self, StringIO):
- gpe = self._create_extractor()
- gpe.get_page('detail?id=6')
-
- with mock.patch.object(base.ProjectExtractor, 'urlopen'): # for attachments, which end up using a different Extractor urlopen
- comments = list(gpe.iter_comments())
-
- self.assertEqual(len(comments), 6)
- expected = [
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:34:01 2013',
- 'body': 'Simple comment',
- 'updates': {},
- 'attachments': [],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:34:09 2013',
- 'body': 'Boring comment',
- 'updates': {},
- 'attachments': [],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:35:15 2013',
- 'body': 'Test \\*comment\\* is a comment',
- 'updates': {'Status:': 'Started', 'Labels:': '-OpSys-Linux OpSys-Windows'},
- 'attachments': ['at2.txt'],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:35:34 2013',
- 'body': 'Another comment with references: [issue 2](#2), [r1]',
- 'updates': {},
- 'attachments': [],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:36:39 2013',
- 'body': 'Last comment',
- 'updates': {},
- 'attachments': ['at4.txt', 'at1.txt'],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:36:57 2013',
- 'body': 'Oh, I forgot one \\(with an inter\\-project reference to '
- '[issue other\\-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)',
- 'updates': {'Labels:': 'OpSys-OSX'},
- 'attachments': [],
- },
- ]
- for actual, expected in zip(comments, expected):
- self.assertEqual(actual.author.name, expected['author.name'])
- self.assertEqual(actual.author.url, expected['author.url'])
- self.assertEqual(actual.created_date, expected['created_date'])
- self.assertEqual(actual.body, expected['body'])
- self.assertEqual(actual.updates, expected['updates'])
- self.assertEqual(
- [a.filename for a in actual.attachments], expected['attachments'])
-
- @skipif(module_not_available('html2text'))
- @mock.patch.object(base, 'StringIO')
- def test_iter_comments_html2text(self, StringIO):
- gpe = self._create_extractor()
- gpe.get_page('detail?id=6')
-
- with mock.patch.object(base.ProjectExtractor, 'urlopen'): # for attachments, which end up using a different Extractor urlopen
- comments = list(gpe.iter_comments())
-
- self.assertEqual(len(comments), 6)
- expected = [
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:34:01 2013',
- 'body': 'Simple comment',
- 'updates': {},
- 'attachments': [],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:34:09 2013',
- 'body': 'Boring comment',
- 'updates': {},
- 'attachments': [],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:35:15 2013',
- 'body': 'Test \\*comment\\* is a comment',
- 'updates': {'Status:': 'Started', 'Labels:': '-OpSys-Linux OpSys-Windows'},
- 'attachments': ['at2.txt'],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:35:34 2013',
- 'body': 'Another comment with references: [issue 2](#2), [r1]',
- 'updates': {},
- 'attachments': [],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:36:39 2013',
- 'body': 'Last comment',
- 'updates': {},
- 'attachments': ['at4.txt', 'at1.txt'],
- },
- {
- 'author.name': 'john...@gmail.com',
- 'author.url': 'http://code.google.com/u/101557263855536553789/',
- 'created_date': 'Thu Aug 8 15:36:57 2013',
- 'body': 'Oh, I forgot one \\(with an inter-project reference to '
- '[issue other-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)',
- 'updates': {'Labels:': 'OpSys-OSX'},
- 'attachments': [],
- },
- ]
- for actual, expected in zip(comments, expected):
- self.assertEqual(actual.author.name, expected['author.name'])
- self.assertEqual(actual.author.url, expected['author.url'])
- self.assertEqual(actual.created_date, expected['created_date'])
- self.assertEqual(actual.body, expected['body'])
- self.assertEqual(actual.updates, expected['updates'])
- self.assertEqual(
- [a.filename for a in actual.attachments], expected['attachments'])
-
-
-class TestUserLink(TestCase):
-
- def test_plain(self):
- tag = mock.Mock()
- tag.text.strip.return_value = 'name'
- tag.get.return_value = None
- link = google.UserLink(tag)
- self.assertEqual(str(link), 'name')
-
- def test_linked(self):
- tag = mock.Mock()
- tag.text.strip.return_value = 'name'
- tag.get.return_value = '/p/project'
- link = google.UserLink(tag)
- self.assertEqual(str(link), '[name](http://code.google.com/p/project)')
-
-
-class TestComment(TestCase):
- html = """
- <div class="cursor_off vt issuecomment" id="hc2">
- <div style="float:right; margin-right:.3em; text-align:right">
- <span class="date" title="Tue Jun 25 03:20:09 2013">
- Jun 25, 2013
- </span>
- </div>
- <span class="author">
- <span class="role_label">Project Member</span>
- <a name="c2" href="/p/pychess/issues/detail?id=267#c2">#2</a>
- <a class="userlink" href="/u/gbtami/">gbtami</a></span>
- <pre><i>(No comment was entered for this change.)</i>
- </pre>
- <div class="updates">
- <div class="round4"></div>
- <div class="round2"></div>
- <div class="round1"></div>
- <div class="box-inner">
- <b>Summary:</b>
- Make PyChess keyboard accessible
- <span class="oldvalue">
- (was: Make PyChess keyboard accecible)
- </span>
- <br>
- <b>Status:</b>
- Accepted
- <br>
- </div>
- <div class="round1"></div>
- <div class="round2"></div>
- <div class="round4"></div>
- </div>
- </div>
- """
-
- def test_init(self):
- from BeautifulSoup import BeautifulSoup
- html = BeautifulSoup(self.html)
- comment = google.Comment(html.find('div', 'issuecomment'), 'pychess')
- self.assertEqual(comment.updates, {
- u'Summary:': u'Make PyChess keyboard accessible',
- u'Status:': u'Accepted',
- })
-
-
-class TestAsMarkdown(TestCase):
-
- def soup(self, tag):
- return BeautifulSoup(u'<pre>%s</pre>' % tag).first()
-
- def test_unicode(self):
- tag = self.soup(u'\ua000 foo <a href="http://example.com/">bar</a>')
- res = google._as_markdown(tag, 'pn')
- self.assertEqual(res, u'\ua000 foo [bar](http://example.com/)')
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/test_tasks.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tasks.py b/ForgeImporters/forgeimporters/tests/google/test_tasks.py
deleted file mode 100644
index 01bab68..0000000
--- a/ForgeImporters/forgeimporters/tests/google/test_tasks.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import mock
-
-from ...google import tasks
-
-
-@mock.patch.object(tasks, 'GoogleCodeProjectExtractor')
-@mock.patch.object(tasks, 'ThreadLocalORMSession')
-@mock.patch.object(tasks, 'c')
-def test_import_project_info(c, session, gpe):
- c.project = mock.Mock(name='project')
- tasks.import_project_info('my-project')
- gpe.assert_called_once_with('my-project', 'project_info')
- gpe.return_value.get_short_description.assert_called_once_with(c.project)
- gpe.return_value.get_icon.assert_called_once_with(c.project)
- gpe.return_value.get_license.assert_called_once_with(c.project)
- session.flush_all.assert_called_once_with()
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
deleted file mode 100644
index e8f12bb..0000000
--- a/ForgeImporters/forgeimporters/tests/google/test_tracker.py
+++ /dev/null
@@ -1,336 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from datetime import datetime
-from unittest import TestCase
-
-import mock
-from mock import patch
-from ming.odm import ThreadLocalORMSession
-
-from allura.tests import TestController
-from allura.tests.decorators import with_tracker
-
-from allura import model as M
-from forgeimporters.google import tracker
-
-
-class TestTrackerImporter(TestCase):
-
- @mock.patch.object(tracker, 'g')
- @mock.patch.object(tracker, 'c')
- @mock.patch.object(tracker, 'ThreadLocalORMSession')
- @mock.patch.object(tracker, 'session')
- @mock.patch.object(tracker, 'M')
- @mock.patch.object(tracker, 'TM')
- @mock.patch.object(tracker, 'GoogleCodeProjectExtractor')
- def test_import_tool(self, gpe, TM, M, session, tlos, c, g):
- importer = tracker.GoogleCodeTrackerImporter()
- importer.process_fields = mock.Mock()
- importer.process_labels = mock.Mock()
- importer.process_comments = mock.Mock()
- importer.postprocess_custom_fields = mock.Mock()
- project, user = mock.Mock(), mock.Mock()
- app = project.install_app.return_value
- app.config.options.mount_point = 'mount_point'
- app.config.options.import_id = {
- 'source': 'Google Code',
- 'project_name': 'project_name',
- }
- app.config.options.get = lambda *a: getattr(app.config.options, *a)
- app.url = 'foo'
- issues = gpe.iter_issues.return_value = [
- (50, mock.Mock()), (100, mock.Mock())]
- tickets = TM.Ticket.side_effect = [mock.Mock(), mock.Mock()]
-
- importer.import_tool(project, user, project_name='project_name',
- mount_point='mount_point', mount_label='mount_label')
-
- project.install_app.assert_called_once_with(
- 'tickets', 'mount_point', 'mount_label',
- EnableVoting=True,
- open_status_names='New Accepted Started',
- closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
- import_id={
- 'source': 'Google Code',
- 'project_name': 'project_name',
- }
- )
- gpe.iter_issues.assert_called_once_with('project_name')
- self.assertEqual(importer.process_fields.call_args_list, [
- mock.call(tickets[0], issues[0][1]),
- mock.call(tickets[1], issues[1][1]),
- ])
- self.assertEqual(importer.process_labels.call_args_list, [
- mock.call(tickets[0], issues[0][1]),
- mock.call(tickets[1], issues[1][1]),
- ])
- self.assertEqual(importer.process_comments.call_args_list, [
- mock.call(tickets[0], issues[0][1]),
- mock.call(tickets[1], issues[1][1]),
- ])
- self.assertEqual(tlos.flush_all.call_args_list, [
- mock.call(),
- mock.call(),
- ])
- self.assertEqual(session.return_value.flush.call_args_list, [
- mock.call(tickets[0]),
- mock.call(tickets[1]),
- ])
- self.assertEqual(session.return_value.expunge.call_args_list, [
- mock.call(tickets[0]),
- mock.call(tickets[1]),
- ])
- self.assertEqual(app.globals.last_ticket_num, 100)
- M.AuditLog.log.assert_called_once_with(
- 'import tool mount_point from project_name on Google Code',
- project=project, user=user, url='foo')
- g.post_event.assert_called_once_with('project_updated')
- app.globals.invalidate_bin_counts.assert_called_once_with()
-
- @mock.patch.object(tracker, 'ThreadLocalORMSession')
- @mock.patch.object(tracker, 'M')
- @mock.patch.object(tracker, 'h')
- def test_import_tool_failure(self, h, M, ThreadLocalORMSession):
- h.push_config.side_effect = ValueError
- project = mock.Mock()
- user = mock.Mock()
-
- importer = tracker.GoogleCodeTrackerImporter()
- self.assertRaises(
- ValueError, importer.import_tool, project, user, project_name='project_name',
- mount_point='mount_point', mount_label='mount_label')
-
- h.make_app_admin_only.assert_called_once_with(
- project.install_app.return_value)
-
- def test_custom_fields(self):
- importer = tracker.GoogleCodeTrackerImporter()
- importer.custom_fields = {}
- importer.custom_field('Foo')
- importer.custom_field('Milestone')
- importer.custom_field('Priority')
- importer.custom_field('Type')
- self.assertEqual(importer.custom_fields, {
- 'Foo': {
- 'type': 'string',
- 'label': 'Foo',
- 'name': '_foo',
- 'options': set(),
- },
- 'Milestone': {
- 'type': 'milestone',
- 'label': 'Milestone',
- 'name': '_milestone',
- 'options': set(),
- },
- 'Priority': {
- 'type': 'select',
- 'label': 'Priority',
- 'name': '_priority',
- 'options': set(),
- },
- 'Type': {
- 'type': 'select',
- 'label': 'Type',
- 'name': '_type',
- 'options': set(),
- },
- })
- importer.custom_fields = {'Foo': {}}
- importer.custom_field('Foo')
- self.assertEqual(importer.custom_fields, {'Foo': {}})
-
- def test_process_fields(self):
- ticket = mock.Mock()
- issue = mock.Mock(
- get_issue_summary=lambda: 'summary',
- get_issue_description=lambda: 'my *description* fool',
- get_issue_status=lambda: 'status',
- get_issue_created_date=lambda: 'created_date',
- get_issue_mod_date=lambda: 'mod_date',
- get_issue_creator=lambda: 'creator',
- get_issue_owner=lambda: 'owner',
- )
- importer = tracker.GoogleCodeTrackerImporter()
- with mock.patch.object(tracker, 'dateutil') as dt:
- dt.parser.parse.side_effect = lambda s: s
- importer.process_fields(ticket, issue)
- self.assertEqual(ticket.summary, 'summary')
- self.assertEqual(ticket.description,
- '*Originally created by:* creator\n*Originally owned by:* owner\n\nmy *description* fool')
- self.assertEqual(ticket.status, 'status')
- self.assertEqual(ticket.created_date, 'created_date')
- self.assertEqual(ticket.mod_date, 'mod_date')
- self.assertEqual(dt.parser.parse.call_args_list, [
- mock.call('created_date'),
- mock.call('mod_date'),
- ])
-
- def test_process_labels(self):
- ticket = mock.Mock(custom_fields={}, labels=[])
- issue = mock.Mock(get_issue_labels=lambda:
- ['Foo-Bar', 'Baz', 'Foo-Qux'])
- importer = tracker.GoogleCodeTrackerImporter()
- importer.custom_field = mock.Mock(
- side_effect=lambda n: {'name': '_%s' % n.lower(), 'options': set()})
- importer.process_labels(ticket, issue)
- self.assertEqual(ticket.labels, ['Baz'])
- self.assertEqual(ticket.custom_fields, {'_foo': 'Bar, Qux'})
-
- def test_process_comments(self):
- def _author(n):
- a = mock.Mock()
- a.name = 'author%s' % n
- a.link = 'author%s_link' % n
- return a
- ticket = mock.Mock()
- issue = mock.Mock()
- comments = issue.iter_comments.return_value = [
- mock.Mock(
- author=_author(1),
- body='text1',
- annotated_text='annotated1',
- attachments='attachments1',
- created_date='Mon Jul 15 00:00:00 2013',
- ),
- mock.Mock(
- author=_author(2),
- body='text2',
- annotated_text='annotated2',
- attachments='attachments2',
- created_date='Mon Jul 16 00:00:00 2013',
- ),
- ]
- comments[0].updates.items.return_value = [
- ('Foo:', 'Bar'), ('Baz:', 'Qux')]
- comments[1].updates.items.return_value = []
- posts = ticket.discussion_thread.add_post.side_effect = [
- mock.Mock(),
- mock.Mock(),
- ]
- importer = tracker.GoogleCodeTrackerImporter()
- importer.process_comments(ticket, issue)
- self.assertEqual(ticket.discussion_thread.add_post.call_args_list[0], mock.call(
- text='annotated1',
- timestamp=datetime(2013, 7, 15),
- ignore_security=True,
- ))
- posts[0].add_multiple_attachments.assert_called_once_with(
- 'attachments1')
- self.assertEqual(ticket.discussion_thread.add_post.call_args_list[1], mock.call(
- text='annotated2',
- timestamp=datetime(2013, 7, 16),
- ignore_security=True,
- ))
- posts[1].add_multiple_attachments.assert_called_once_with(
- 'attachments2')
-
- @mock.patch.object(tracker, 'c')
- def test_postprocess_custom_fields(self, c):
- importer = tracker.GoogleCodeTrackerImporter()
- importer.open_milestones = set(['m2', 'm3'])
- importer.custom_fields = {
- 'Foo': {
- 'name': '_foo',
- 'type': 'string',
- 'options': set(['foo', 'bar']),
- },
- 'Milestone': {
- 'name': '_milestone',
- 'type': 'milestone',
- 'options': set(['m3', 'm1', 'm2']),
- },
- 'Priority': {
- 'name': '_priority',
- 'type': 'select',
- 'options': set(['foo', 'bar']),
- },
- }
- custom_fields = importer.postprocess_custom_fields()
- self.assertItemsEqual(custom_fields, [
- {
- 'name': '_foo',
- 'type': 'string',
- 'options': '',
- },
- {
- 'name': '_milestone',
- 'type': 'milestone',
- 'options': '',
- 'milestones': [
- {'name': 'm1', 'due_date': None, 'complete': True},
- {'name': 'm2', 'due_date': None, 'complete': False},
- {'name': 'm3', 'due_date': None, 'complete': False},
- ],
- },
- {
- 'name': '_priority',
- 'type': 'select',
- 'options': 'foo bar',
- },
- ])
-
-
-class TestGoogleCodeTrackerImportController(TestController, TestCase):
-
- def setUp(self):
- """Mount Google Code importer on the Tracker admin controller"""
- super(TestGoogleCodeTrackerImportController, self).setUp()
- from forgetracker.tracker_main import TrackerAdminController
- TrackerAdminController._importer = \
- tracker.GoogleCodeTrackerImportController(
- tracker.GoogleCodeTrackerImporter())
-
- @with_tracker
- def test_index(self):
- r = self.app.get('/p/test/admin/bugs/_importer/')
- self.assertIsNotNone(r.html.find(attrs=dict(name="gc_project_name")))
- self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
- self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
-
- @with_tracker
- @patch('forgeimporters.base.import_tool')
- def test_create(self, import_tool):
- params = dict(gc_project_name='test',
- mount_label='mylabel',
- mount_point='mymount',
- )
- r = self.app.post('/p/test/admin/bugs/_importer/create', params,
- status=302)
- self.assertEqual(r.location, 'http://localhost/p/test/admin/')
- self.assertEqual(
- u'mymount', import_tool.post.call_args[1]['mount_point'])
- self.assertEqual(
- u'mylabel', import_tool.post.call_args[1]['mount_label'])
- self.assertEqual(
- u'test', import_tool.post.call_args[1]['project_name'])
-
- @with_tracker
- @patch('forgeimporters.base.import_tool')
- def test_create_limit(self, import_tool):
- project = M.Project.query.get(shortname='test')
- project.set_tool_data('GoogleCodeTrackerImporter', pending=1)
- ThreadLocalORMSession.flush_all()
- params = dict(gc_project_name='test',
- mount_label='mylabel',
- mount_point='mymount',
- )
- r = self.app.post('/p/test/admin/bugs/_importer/create', params,
- status=302).follow()
- self.assertIn('Please wait and try again', r)
- self.assertEqual(import_tool.post.call_count, 0)
[4/5] allura git commit: [#8054] delete Google Code importers and
tests
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html b/ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html
deleted file mode 100644
index 4fc25eb..0000000
--- a/ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html
+++ /dev/null
@@ -1,548 +0,0 @@
-<!DOCTYPE html>
-<!--
-
-An issue with a link to another page of comments (google paginates after 500 comments, we simulate with less)
-test-issue-prev-page.html is the test file for that other page of comments
-
--->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-<meta name="ROBOTS" content="NOARCHIVE" />
-<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico" />
-<script type="text/javascript">
-
-
-
-
- var codesite_token = null;
-
-
- var CS_env = {"loggedInUserEmail":null,"relativeBaseUrl":"","projectHomeUrl":"/p/allura-google-importer","assetVersionPath":"http://www.gstatic.com/codesite/ph/3783617020303179221","assetHostPath":"http://www.gstatic.com/codesite/ph","domainName":null,"projectName":"allura-google-importer","token":null,"profileUrl":null};
- var _gaq = _gaq || [];
- _gaq.push(
- ['siteTracker._setAccount', 'UA-18071-1'],
- ['siteTracker._trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
- })();
-
- </script>
-<title>Issue 6 -
- allura-google-importer -
-
- Test Issue -
- Import Google Code projects to an Allura forge - Google Project Hosting
- </title>
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/core.css" />
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/ph_detail.css" />
-<!--[if IE]>
- <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/d_ie.css" >
-<![endif]-->
-<style type="text/css">
- .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
- .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
- .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
-
-
- .attachments { width:33%; border-top:2px solid #999; padding-top: 3px; margin-left: .7em;}
- .attachments table { margin-bottom: 0.75em; }
- .attachments table tr td { padding: 0; margin: 0; font-size: 95%; }
- .preview { border: 2px solid #c3d9ff; padding: 1px; }
- .preview:hover { border: 2px solid blue; }
- .label { white-space: nowrap; }
- .derived { font-style:italic }
- .cursor_on .author {
- background: url(http://www.gstatic.com/codesite/ph/images/show-arrow.gif) no-repeat 2px;
- }
- .hiddenform {
- display: none;
- }
-
-
- </style>
-</head>
-<body class="t3">
-<script type="text/javascript">
- window.___gcfg = {lang: 'en'};
- (function()
- {var po = document.createElement("script");
- po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
- var s = document.getElementsByTagName("script")[0];
- s.parentNode.insertBefore(po, s);
- })();
-</script>
-<div class="headbg">
-<div id="gaia">
-<span>
-<a href="#" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small>▼</small></a>
- | <a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6" onclick="_CS_click('/gb/ph/signin');"><u>Sign in</u></a>
-</span>
-</div>
-<div class="gbh" style="left: 0pt;"></div>
-<div class="gbh" style="right: 0pt;"></div>
-<div style="height: 1px"></div>
-<!--[if lte IE 7]>
-<div style="text-align:center;">
-Your version of Internet Explorer is not supported. Try a browser that
-contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
-<a href="http://www.google.com/chrome">Google Chrome</a>, or
-<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
-</div>
-<![endif]-->
-<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="itemscope" itemtype="http://schema.org/CreativeWork">
-<tr style="height: 58px;">
-<td id="plogo">
-<link itemprop="url" href="/p/allura-google-importer" />
-<a href="/p/allura-google-importer/">
-<img src="/p/allura-google-importer/logo?cct=1374769571" alt="Logo" itemprop="image" />
-</a>
-</td>
-<td style="padding-left: 0.5em">
-<div id="pname">
-<a href="/p/allura-google-importer/"><span itemprop="name">allura-google-importer</span></a>
-</div>
-<div id="psum">
-<a id="project_summary_link" href="/p/allura-google-importer/"><span itemprop="description">Import Google Code projects to an Allura forge</span></a>
-</div>
-</td>
-<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
-<form action="/hosting/search">
-<input size="30" name="q" value="" type="text" />
-<input type="submit" name="projectsearch" value="Search projects" />
-</form>
-</td></tr>
-</table>
-</div>
-<div id="mt" class="gtb">
-<a href="/p/allura-google-importer/" class="tab ">Project Home</a>
-<a href="/p/allura-google-importer/wiki/TestPage?tm=6" class="tab ">Wiki</a>
-<a href="/p/allura-google-importer/issues/list" class="tab active">Issues</a>
-<a href="/p/allura-google-importer/source/checkout" class="tab ">Source</a>
-<div class="gtbc"></div>
-</div>
-<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
-<tr>
-<td class="subt">
-<div class="issueDetail">
-<div class="isf">
-<span class="inIssueEntry">
-<a class="buttonify" href="entry" onclick="return _newIssuePrompt();">New issue</a>
-</span>
-
- <span class="inIssueList">
-<span>Search</span>
-</span><form action="list" method="GET" style="display:inline">
-<select id="can" name="can">
-<option disabled="disabled">Search within:</option>
-<option value="1"> All issues</option>
-<option value="2" selected="selected"> Open issues</option>
-<option value="6"> New issues</option>
-<option value="7"> Issues to verify</option>
-</select>
-<span>for</span>
-<span id="qq"><input type="text" size="38" id="searchq" name="q" value="" autocomplete="off" onkeydown="_blurOnEsc(event)" /></span>
-<span id="search_colspec"><input type="hidden" name="colspec" value="ID Type Status Priority Milestone Owner Summary" /></span>
-<input type="hidden" name="cells" value="tiles" />
-<input type="submit" value="Search" />
-</form>
-
- <span class="inIssueAdvSearch">
-<a href="advsearch">Advanced search</a>
-</span>
- <span class="inIssueSearchTips">
-<a href="searchtips">Search tips</a>
-</span>
- <span class="inIssueSubscriptions">
-<a href="/p/allura-google-importer/issues/subscriptions">Subscriptions</a>
-</span>
-</div>
-</div>
-</td>
-<td align="right" valign="top" class="bevel-right"></td>
-</tr>
-</table>
-<script type="text/javascript">
- var cancelBubble = false;
- function _go(url) { document.location = url; }
-</script>
-<div id="maincol">
-<div id="color_control" class="">
-<div id="issueheader">
-<table cellpadding="0" cellspacing="0" width="100%"><tbody>
-<tr>
-<td class="vt h3" nowrap="nowrap" style="padding:0 5px">
-
-
- Issue <a href="detail?id=6">6</a>:
- </td>
-<td width="90%" class="vt">
-<span class="h3">Test "Issue"</span>
-</td>
-<td>
-<div class="pagination">
-<a href="../../allura-google-importer/issues/detail?id=5" title="Prev">‹ Prev</a>
- 6 of 6
-
- </div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td nowrap="nowrap">
-
-
- 1 person starred this issue and may be notified of changes.
-
-
-
- </td>
-<td align="center" nowrap="nowrap">
-<a href="http://code.google.com/p/allura-google-importer/issues/list?cursor=allura-google-importer%3A6">Back to list</a>
-</td>
-</tr>
-</tbody></table>
-</div>
-<table width="100%" cellpadding="0" cellspacing="0" border="0" class="issuepage" id="meta-container">
-<tbody class="collapse">
-<tr>
-<td id="issuemeta">
-<div id="meta-float">
-<table cellspacing="0" cellpadding="0">
-<tr><th align="left">Status: </th>
-<td width="100%">
-<span title="Work on this issue has begun">Started</span>
-</td>
-</tr>
-<tr><th align="left">Owner: </th><td>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>
-</td>
-</tr>
-<tr><td colspan="2">
-<div style="padding-top:2px">
-<a href="list?q=label:Type-Defect" title="Report of a software defect" class="label"><b>Type-</b>Defect</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Priority-Medium" title="Normal priority" class="label"><b>Priority-</b>Medium</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Milestone-Release1.0" title="All essential functionality working" class="label"><b>Milestone-</b>Release1.0</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-All" title="Affects all operating systems" class="label"><b>OpSys-</b>All</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Component-Logic" title="Issue relates to application logic" class="label"><b>Component-</b>Logic</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Performance" title="Performance issue" class="label">Performance</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Security" title="Security risk to users" class="label">Security</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-Windows" title="Affects Windows users" class="label"><b>OpSys-</b>Windows</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-OSX" title="Affects Mac OS X users" class="label"><b>OpSys-</b>OSX</a>
-</div>
-</td></tr>
-</table>
-<div class="rel_issues">
-</div>
-<br /><br />
-<div style="white-space:nowrap"><a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment</div>
-</div>
- </td>
-<td class="vt issuedescription" width="100%" id="cursorarea">
-<div class="cursor_off vt issuedescription" id="hc0">
-<div class="author">
-<span class="role_label">Project Member</span>
- Reported by
-
-
- <a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>,
- <span class="date" title="Thu Aug 8 15:33:52 2013">Today (3 minutes ago)</span>
-</div>
-<pre>
-Test *Issue* for testing
-
- 1. Test List
- 2. Item
-
-**Testing**
-
- * Test list 2
- * Item
-
-# Test Section
-
- p = source.test_issue.post()
- p.count = p.count *5 #* 6
- if p.count > 5:
- print "Not < 5 & != 5"
-
-References: <a href="/p/allura-google-importer/issues/detail?id=1">issue 1</a>, <a href="/p/allura-google-importer/source/detail?r=2">r2</a>
-
-That's all
-
-
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=7&aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&name=&token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b></b>
-<br />
- 0 bytes
-
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&name=&token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-
- <div class="vt issuecomment" width="100%" style="background:#e5ecf9; padding:2px .7em; margin:0; border:0">
-Showing comments 3 - 6
-of 6
- <a href="detail?id=1769&cnum=500&cstart=2">Older <b>›</b></a>
- </div>
-
-<div class="cursor_off vt issuecomment" id="hc1">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:35:15 2013">
- Today (2 minutes ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c1" href="/p/allura-google-importer/issues/detail?id=6#c1">#1</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Test *comment* is a comment
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&name=&token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at2.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=6&aid=60001000&name=at2.txt&token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&name=at2.txt&token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-</div>
-<div class="updates">
-<div class="round4"></div>
-<div class="round2"></div>
-<div class="round1"></div>
-<div class="box-inner">
-<b>Status:</b>
- Started
-
- <br />
-<b>Labels:</b>
- -OpSys-Linux OpSys-Windows
-
- <br />
-</div>
-<div class="round1"></div>
-<div class="round2"></div>
-<div class="round4"></div>
-</div>
-</div>
-<div class="cursor_off vt issuecomment" id="hc2">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:35:34 2013">
- Today (1 minute ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c2" href="/p/allura-google-importer/issues/detail?id=6#c2">#2</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Another comment with references: <a href="/p/allura-google-importer/issues/detail?id=2">issue 2</a>, <a href="/p/allura-google-importer/source/detail?r=1">r1</a>
-</pre>
-</div>
-<div class="cursor_off vt issuecomment" id="hc3">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:36:39 2013">
- Today (moments ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c3" href="/p/allura-google-importer/issues/detail?id=6#c3">#3</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Last comment
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003000&name=at4.txt&token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at4.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=6&aid=60003000&name=at4.txt&token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003000&name=at4.txt&token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003001&name=at1.txt&token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=6&aid=60003001&name=at1.txt&token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003001&name=at1.txt&token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-<div class="cursor_off vt issuecomment" id="hc4">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:36:57 2013">
- Today (moments ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c4" href="/p/allura-google-importer/issues/detail?id=6#c4">#4</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Oh, I forgot one (with an inter-project reference to <a href="/p/other-project/issues/detail?id=1">issue other-project:1</a>)
-</pre>
-<div class="updates">
-<div class="round4"></div>
-<div class="round2"></div>
-<div class="round1"></div>
-<div class="box-inner">
-<b>Labels:</b>
- OpSys-OSX
-
- <br />
-</div>
-<div class="round1"></div>
-<div class="round2"></div>
-<div class="round4"></div>
-</div>
-</div>
-
-<div class="vt issuecomment" width="100%" style="background:#e5ecf9; padding:2px .7em; margin:0">
-Showing comments 3 - 6
-of 6
- <a href="detail?id=1769&cnum=500&cstart=2">Older <b>›</b></a>
-</div>
-
-</td>
-</tr>
-<tr>
-<td></td>
-<td class="vt issuecomment">
-<span class="indicator">►</span> <a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment
- </td>
-</tr>
-</tbody>
-</table>
-<br />
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/dit_scripts.js"></script>
-</div>
-<form name="delcom" action="delComment.do?q=&can=2&groupby=&sort=&colspec=ID+Type+Status+Priority+Milestone+Owner+Summary" method="POST">
-<input type="hidden" name="sequence_num" value="" />
-<input type="hidden" name="mode" value="" />
-<input type="hidden" name="id" value="6" />
-<input type="hidden" name="token" value="" />
-</form>
-<div id="helparea"></div>
-<script type="text/javascript">
- _onload();
- function delComment(sequence_num, delete_mode) {
- var f = document.forms["delcom"];
- f.sequence_num.value = sequence_num;
- f.mode.value = delete_mode;
-
- f.submit();
- return false;
- }
-
- _floatMetadata();
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/kibbles.js"></script>
-<script type="text/javascript">
- _setupKibblesOnDetailPage(
- 'http://code.google.com/p/allura-google-importer/issues/list?cursor\x3dallura-google-importer%3A6',
- '/p/allura-google-importer/issues/entry',
- '../../allura-google-importer/issues/detail?id\x3d5',
- '',
- '', 'allura-google-importer', 6,
- false, false, codesite_token);
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/ph_core.js"></script>
-</div>
-<div id="footer" dir="ltr">
-<div class="text">
-<a href="/projecthosting/terms.html">Terms</a> -
- <a href="http://www.google.com/privacy.html">Privacy</a> -
- <a href="/p/support/">Project Hosting Help</a>
-</div>
-</div>
-<div class="hostedBy" style="margin-top: -20px;">
-<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
-</div>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html b/ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html
deleted file mode 100644
index 62a3b23..0000000
--- a/ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html
+++ /dev/null
@@ -1,431 +0,0 @@
-<!DOCTYPE html>
-<!--
-
-This is the second page of previous comments, that goes with test-issue-first-page.html
-
--->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-<meta name="ROBOTS" content="NOARCHIVE" />
-<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico" />
-<script type="text/javascript">
-
-
-
-
- var codesite_token = null;
-
-
- var CS_env = {"loggedInUserEmail":null,"relativeBaseUrl":"","projectHomeUrl":"/p/allura-google-importer","assetVersionPath":"http://www.gstatic.com/codesite/ph/3783617020303179221","assetHostPath":"http://www.gstatic.com/codesite/ph","domainName":null,"projectName":"allura-google-importer","token":null,"profileUrl":null};
- var _gaq = _gaq || [];
- _gaq.push(
- ['siteTracker._setAccount', 'UA-18071-1'],
- ['siteTracker._trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
- })();
-
- </script>
-<title>Issue 6 -
- allura-google-importer -
-
- Test Issue -
- Import Google Code projects to an Allura forge - Google Project Hosting
- </title>
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/core.css" />
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/ph_detail.css" />
-<!--[if IE]>
- <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/d_ie.css" >
-<![endif]-->
-<style type="text/css">
- .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
- .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
- .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
-
-
- .attachments { width:33%; border-top:2px solid #999; padding-top: 3px; margin-left: .7em;}
- .attachments table { margin-bottom: 0.75em; }
- .attachments table tr td { padding: 0; margin: 0; font-size: 95%; }
- .preview { border: 2px solid #c3d9ff; padding: 1px; }
- .preview:hover { border: 2px solid blue; }
- .label { white-space: nowrap; }
- .derived { font-style:italic }
- .cursor_on .author {
- background: url(http://www.gstatic.com/codesite/ph/images/show-arrow.gif) no-repeat 2px;
- }
- .hiddenform {
- display: none;
- }
-
-
- </style>
-</head>
-<body class="t3">
-<script type="text/javascript">
- window.___gcfg = {lang: 'en'};
- (function()
- {var po = document.createElement("script");
- po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
- var s = document.getElementsByTagName("script")[0];
- s.parentNode.insertBefore(po, s);
- })();
-</script>
-<div class="headbg">
-<div id="gaia">
-<span>
-<a href="#" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small>▼</small></a>
- | <a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6" onclick="_CS_click('/gb/ph/signin');"><u>Sign in</u></a>
-</span>
-</div>
-<div class="gbh" style="left: 0pt;"></div>
-<div class="gbh" style="right: 0pt;"></div>
-<div style="height: 1px"></div>
-<!--[if lte IE 7]>
-<div style="text-align:center;">
-Your version of Internet Explorer is not supported. Try a browser that
-contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
-<a href="http://www.google.com/chrome">Google Chrome</a>, or
-<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
-</div>
-<![endif]-->
-<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="itemscope" itemtype="http://schema.org/CreativeWork">
-<tr style="height: 58px;">
-<td id="plogo">
-<link itemprop="url" href="/p/allura-google-importer" />
-<a href="/p/allura-google-importer/">
-<img src="/p/allura-google-importer/logo?cct=1374769571" alt="Logo" itemprop="image" />
-</a>
-</td>
-<td style="padding-left: 0.5em">
-<div id="pname">
-<a href="/p/allura-google-importer/"><span itemprop="name">allura-google-importer</span></a>
-</div>
-<div id="psum">
-<a id="project_summary_link" href="/p/allura-google-importer/"><span itemprop="description">Import Google Code projects to an Allura forge</span></a>
-</div>
-</td>
-<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
-<form action="/hosting/search">
-<input size="30" name="q" value="" type="text" />
-<input type="submit" name="projectsearch" value="Search projects" />
-</form>
-</td></tr>
-</table>
-</div>
-<div id="mt" class="gtb">
-<a href="/p/allura-google-importer/" class="tab ">Project Home</a>
-<a href="/p/allura-google-importer/wiki/TestPage?tm=6" class="tab ">Wiki</a>
-<a href="/p/allura-google-importer/issues/list" class="tab active">Issues</a>
-<a href="/p/allura-google-importer/source/checkout" class="tab ">Source</a>
-<div class="gtbc"></div>
-</div>
-<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
-<tr>
-<td class="subt">
-<div class="issueDetail">
-<div class="isf">
-<span class="inIssueEntry">
-<a class="buttonify" href="entry" onclick="return _newIssuePrompt();">New issue</a>
-</span>
-
- <span class="inIssueList">
-<span>Search</span>
-</span><form action="list" method="GET" style="display:inline">
-<select id="can" name="can">
-<option disabled="disabled">Search within:</option>
-<option value="1"> All issues</option>
-<option value="2" selected="selected"> Open issues</option>
-<option value="6"> New issues</option>
-<option value="7"> Issues to verify</option>
-</select>
-<span>for</span>
-<span id="qq"><input type="text" size="38" id="searchq" name="q" value="" autocomplete="off" onkeydown="_blurOnEsc(event)" /></span>
-<span id="search_colspec"><input type="hidden" name="colspec" value="ID Type Status Priority Milestone Owner Summary" /></span>
-<input type="hidden" name="cells" value="tiles" />
-<input type="submit" value="Search" />
-</form>
-
- <span class="inIssueAdvSearch">
-<a href="advsearch">Advanced search</a>
-</span>
- <span class="inIssueSearchTips">
-<a href="searchtips">Search tips</a>
-</span>
- <span class="inIssueSubscriptions">
-<a href="/p/allura-google-importer/issues/subscriptions">Subscriptions</a>
-</span>
-</div>
-</div>
-</td>
-<td align="right" valign="top" class="bevel-right"></td>
-</tr>
-</table>
-<script type="text/javascript">
- var cancelBubble = false;
- function _go(url) { document.location = url; }
-</script>
-<div id="maincol">
-<div id="color_control" class="">
-<div id="issueheader">
-<table cellpadding="0" cellspacing="0" width="100%"><tbody>
-<tr>
-<td class="vt h3" nowrap="nowrap" style="padding:0 5px">
-
-
- Issue <a href="detail?id=6">6</a>:
- </td>
-<td width="90%" class="vt">
-<span class="h3">Test "Issue"</span>
-</td>
-<td>
-<div class="pagination">
-<a href="../../allura-google-importer/issues/detail?id=5" title="Prev">‹ Prev</a>
- 6 of 6
-
- </div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td nowrap="nowrap">
-
-
- 1 person starred this issue and may be notified of changes.
-
-
-
- </td>
-<td align="center" nowrap="nowrap">
-<a href="http://code.google.com/p/allura-google-importer/issues/list?cursor=allura-google-importer%3A6">Back to list</a>
-</td>
-</tr>
-</tbody></table>
-</div>
-<table width="100%" cellpadding="0" cellspacing="0" border="0" class="issuepage" id="meta-container">
-<tbody class="collapse">
-<tr>
-<td id="issuemeta">
-<div id="meta-float">
-<table cellspacing="0" cellpadding="0">
-<tr><th align="left">Status: </th>
-<td width="100%">
-<span title="Work on this issue has begun">Started</span>
-</td>
-</tr>
-<tr><th align="left">Owner: </th><td>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>
-</td>
-</tr>
-<tr><td colspan="2">
-<div style="padding-top:2px">
-<a href="list?q=label:Type-Defect" title="Report of a software defect" class="label"><b>Type-</b>Defect</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Priority-Medium" title="Normal priority" class="label"><b>Priority-</b>Medium</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Milestone-Release1.0" title="All essential functionality working" class="label"><b>Milestone-</b>Release1.0</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-All" title="Affects all operating systems" class="label"><b>OpSys-</b>All</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Component-Logic" title="Issue relates to application logic" class="label"><b>Component-</b>Logic</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Performance" title="Performance issue" class="label">Performance</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Security" title="Security risk to users" class="label">Security</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-Windows" title="Affects Windows users" class="label"><b>OpSys-</b>Windows</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-OSX" title="Affects Mac OS X users" class="label"><b>OpSys-</b>OSX</a>
-</div>
-</td></tr>
-</table>
-<div class="rel_issues">
-</div>
-<br /><br />
-<div style="white-space:nowrap"><a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment</div>
-</div>
- </td>
-<td class="vt issuedescription" width="100%" id="cursorarea">
-<div class="cursor_off vt issuedescription" id="hc0">
-<div class="author">
-<span class="role_label">Project Member</span>
- Reported by
-
-
- <a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>,
- <span class="date" title="Thu Aug 8 15:33:52 2013">Today (3 minutes ago)</span>
-</div>
-<pre>
-Test *Issue* for testing
-
- 1. Test List
- 2. Item
-
-**Testing**
-
- * Test list 2
- * Item
-
-# Test Section
-
- p = source.test_issue.post()
- p.count = p.count *5 #* 6
- if p.count > 5:
- print "Not < 5 & != 5"
-
-References: <a href="/p/allura-google-importer/issues/detail?id=1">issue 1</a>, <a href="/p/allura-google-importer/source/detail?r=2">r2</a>
-
-That's all
-
-
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=7&aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&name=&token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b></b>
-<br />
- 0 bytes
-
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&name=&token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-
- <div class="vt issuecomment" width="100%" style="background:#e5ecf9; padding:2px .7em; margin:0; border:0">
- <a href="detail?id=1769&cnum=500&cstart=502">Newer <b>›</b></a>
-
-Showing comments 1 - 2
-of 6
- </div>
-
-<div class="cursor_off vt issuecomment" id="hc1">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:34:01 2013">
- Today (3 minutes ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c1" href="/p/allura-google-importer/issues/detail?id=6#c1">#1</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Simple comment
-</pre>
-</div>
-<div class="cursor_off vt issuecomment" id="hc2">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:34:09 2013">
- Today (3 minutes ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c2" href="/p/allura-google-importer/issues/detail?id=6#c2">#2</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Boring comment
-</pre>
-</div>
-
-<div class="vt issuecomment" width="100%" style="background:#e5ecf9; padding:2px .7em; margin:0">
- <a href="detail?id=1769&cnum=500&cstart=502">Newer <b>›</b></a>
-
-Showing comments 1 - 2
-of 6
-</div>
-
-</td>
-</tr>
-<tr>
-<td></td>
-<td class="vt issuecomment">
-<span class="indicator">►</span> <a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment
- </td>
-</tr>
-</tbody>
-</table>
-<br />
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/dit_scripts.js"></script>
-</div>
-<form name="delcom" action="delComment.do?q=&can=2&groupby=&sort=&colspec=ID+Type+Status+Priority+Milestone+Owner+Summary" method="POST">
-<input type="hidden" name="sequence_num" value="" />
-<input type="hidden" name="mode" value="" />
-<input type="hidden" name="id" value="6" />
-<input type="hidden" name="token" value="" />
-</form>
-<div id="helparea"></div>
-<script type="text/javascript">
- _onload();
- function delComment(sequence_num, delete_mode) {
- var f = document.forms["delcom"];
- f.sequence_num.value = sequence_num;
- f.mode.value = delete_mode;
-
- f.submit();
- return false;
- }
-
- _floatMetadata();
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/kibbles.js"></script>
-<script type="text/javascript">
- _setupKibblesOnDetailPage(
- 'http://code.google.com/p/allura-google-importer/issues/list?cursor\x3dallura-google-importer%3A6',
- '/p/allura-google-importer/issues/entry',
- '../../allura-google-importer/issues/detail?id\x3d5',
- '',
- '', 'allura-google-importer', 6,
- false, false, codesite_token);
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/ph_core.js"></script>
-</div>
-<div id="footer" dir="ltr">
-<div class="text">
-<a href="/projecthosting/terms.html">Terms</a> -
- <a href="http://www.google.com/privacy.html">Privacy</a> -
- <a href="/p/support/">Project Hosting Help</a>
-</div>
-</div>
-<div class="hostedBy" style="margin-top: -20px;">
-<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
-</div>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/test-issue.html b/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
deleted file mode 100644
index 59507a9..0000000
--- a/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
+++ /dev/null
@@ -1,535 +0,0 @@
-<!DOCTYPE html>
-<!--
-
-Just a regular single-page issue
-
--->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-<meta name="ROBOTS" content="NOARCHIVE" />
-<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico" />
-<script type="text/javascript">
-
-
-
-
- var codesite_token = null;
-
-
- var CS_env = {"loggedInUserEmail":null,"relativeBaseUrl":"","projectHomeUrl":"/p/allura-google-importer","assetVersionPath":"http://www.gstatic.com/codesite/ph/3783617020303179221","assetHostPath":"http://www.gstatic.com/codesite/ph","domainName":null,"projectName":"allura-google-importer","token":null,"profileUrl":null};
- var _gaq = _gaq || [];
- _gaq.push(
- ['siteTracker._setAccount', 'UA-18071-1'],
- ['siteTracker._trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
- })();
-
- </script>
-<title>Issue 6 -
- allura-google-importer -
-
- Test Issue -
- Import Google Code projects to an Allura forge - Google Project Hosting
- </title>
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/core.css" />
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/ph_detail.css" />
-<!--[if IE]>
- <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/d_ie.css" >
-<![endif]-->
-<style type="text/css">
- .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
- .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
- .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
-
-
- .attachments { width:33%; border-top:2px solid #999; padding-top: 3px; margin-left: .7em;}
- .attachments table { margin-bottom: 0.75em; }
- .attachments table tr td { padding: 0; margin: 0; font-size: 95%; }
- .preview { border: 2px solid #c3d9ff; padding: 1px; }
- .preview:hover { border: 2px solid blue; }
- .label { white-space: nowrap; }
- .derived { font-style:italic }
- .cursor_on .author {
- background: url(http://www.gstatic.com/codesite/ph/images/show-arrow.gif) no-repeat 2px;
- }
- .hiddenform {
- display: none;
- }
-
-
- </style>
-</head>
-<body class="t3">
-<script type="text/javascript">
- window.___gcfg = {lang: 'en'};
- (function()
- {var po = document.createElement("script");
- po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
- var s = document.getElementsByTagName("script")[0];
- s.parentNode.insertBefore(po, s);
- })();
-</script>
-<div class="headbg">
-<div id="gaia">
-<span>
-<a href="#" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small>▼</small></a>
- | <a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6" onclick="_CS_click('/gb/ph/signin');"><u>Sign in</u></a>
-</span>
-</div>
-<div class="gbh" style="left: 0pt;"></div>
-<div class="gbh" style="right: 0pt;"></div>
-<div style="height: 1px"></div>
-<!--[if lte IE 7]>
-<div style="text-align:center;">
-Your version of Internet Explorer is not supported. Try a browser that
-contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
-<a href="http://www.google.com/chrome">Google Chrome</a>, or
-<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
-</div>
-<![endif]-->
-<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="itemscope" itemtype="http://schema.org/CreativeWork">
-<tr style="height: 58px;">
-<td id="plogo">
-<link itemprop="url" href="/p/allura-google-importer" />
-<a href="/p/allura-google-importer/">
-<img src="/p/allura-google-importer/logo?cct=1374769571" alt="Logo" itemprop="image" />
-</a>
-</td>
-<td style="padding-left: 0.5em">
-<div id="pname">
-<a href="/p/allura-google-importer/"><span itemprop="name">allura-google-importer</span></a>
-</div>
-<div id="psum">
-<a id="project_summary_link" href="/p/allura-google-importer/"><span itemprop="description">Import Google Code projects to an Allura forge</span></a>
-</div>
-</td>
-<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
-<form action="/hosting/search">
-<input size="30" name="q" value="" type="text" />
-<input type="submit" name="projectsearch" value="Search projects" />
-</form>
-</td></tr>
-</table>
-</div>
-<div id="mt" class="gtb">
-<a href="/p/allura-google-importer/" class="tab ">Project Home</a>
-<a href="/p/allura-google-importer/wiki/TestPage?tm=6" class="tab ">Wiki</a>
-<a href="/p/allura-google-importer/issues/list" class="tab active">Issues</a>
-<a href="/p/allura-google-importer/source/checkout" class="tab ">Source</a>
-<div class="gtbc"></div>
-</div>
-<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
-<tr>
-<td class="subt">
-<div class="issueDetail">
-<div class="isf">
-<span class="inIssueEntry">
-<a class="buttonify" href="entry" onclick="return _newIssuePrompt();">New issue</a>
-</span>
-
- <span class="inIssueList">
-<span>Search</span>
-</span><form action="list" method="GET" style="display:inline">
-<select id="can" name="can">
-<option disabled="disabled">Search within:</option>
-<option value="1"> All issues</option>
-<option value="2" selected="selected"> Open issues</option>
-<option value="6"> New issues</option>
-<option value="7"> Issues to verify</option>
-</select>
-<span>for</span>
-<span id="qq"><input type="text" size="38" id="searchq" name="q" value="" autocomplete="off" onkeydown="_blurOnEsc(event)" /></span>
-<span id="search_colspec"><input type="hidden" name="colspec" value="ID Type Status Priority Milestone Owner Summary" /></span>
-<input type="hidden" name="cells" value="tiles" />
-<input type="submit" value="Search" />
-</form>
-
- <span class="inIssueAdvSearch">
-<a href="advsearch">Advanced search</a>
-</span>
- <span class="inIssueSearchTips">
-<a href="searchtips">Search tips</a>
-</span>
- <span class="inIssueSubscriptions">
-<a href="/p/allura-google-importer/issues/subscriptions">Subscriptions</a>
-</span>
-</div>
-</div>
-</td>
-<td align="right" valign="top" class="bevel-right"></td>
-</tr>
-</table>
-<script type="text/javascript">
- var cancelBubble = false;
- function _go(url) { document.location = url; }
-</script>
-<div id="maincol">
-<div id="color_control" class="">
-<div id="issueheader">
-<table cellpadding="0" cellspacing="0" width="100%"><tbody>
-<tr>
-<td class="vt h3" nowrap="nowrap" style="padding:0 5px">
-
-
- Issue <a href="detail?id=6">6</a>:
- </td>
-<td width="90%" class="vt">
-<span class="h3">Test "Issue"</span>
-</td>
-<td>
-<div class="pagination">
-<a href="../../allura-google-importer/issues/detail?id=5" title="Prev">‹ Prev</a>
- 6 of 6
-
- </div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td nowrap="nowrap">
-
-
- 1 person starred this issue and may be notified of changes.
-
-
-
- </td>
-<td align="center" nowrap="nowrap">
-<a href="http://code.google.com/p/allura-google-importer/issues/list?cursor=allura-google-importer%3A6">Back to list</a>
-</td>
-</tr>
-</tbody></table>
-</div>
-<table width="100%" cellpadding="0" cellspacing="0" border="0" class="issuepage" id="meta-container">
-<tbody class="collapse">
-<tr>
-<td id="issuemeta">
-<div id="meta-float">
-<table cellspacing="0" cellpadding="0">
-<tr><th align="left">Status: </th>
-<td width="100%">
-<span title="Work on this issue has begun">Started</span>
-</td>
-</tr>
-<tr><th align="left">Owner: </th><td>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>
-</td>
-</tr>
-<tr><td colspan="2">
-<div style="padding-top:2px">
-<a href="list?q=label:Type-Defect" title="Report of a software defect" class="label"><b>Type-</b>Defect</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Priority-Medium" title="Normal priority" class="label"><b>Priority-</b>Medium</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Milestone-Release1.0" title="All essential functionality working" class="label"><b>Milestone-</b>Release1.0</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-All" title="Affects all operating systems" class="label"><b>OpSys-</b>All</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Component-Logic" title="Issue relates to application logic" class="label"><b>Component-</b>Logic</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Performance" title="Performance issue" class="label">Performance</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Security" title="Security risk to users" class="label">Security</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-Windows" title="Affects Windows users" class="label"><b>OpSys-</b>Windows</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-OSX" title="Affects Mac OS X users" class="label"><b>OpSys-</b>OSX</a>
-</div>
-</td></tr>
-</table>
-<div class="rel_issues">
-</div>
-<br /><br />
-<div style="white-space:nowrap"><a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment</div>
-</div>
- </td>
-<td class="vt issuedescription" width="100%" id="cursorarea">
-<div class="cursor_off vt issuedescription" id="hc0">
-<div class="author">
-<span class="role_label">Project Member</span>
- Reported by
-
-
- <a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>,
- <span class="date" title="Thu Aug 8 15:33:52 2013">Today (3 minutes ago)</span>
-</div>
-<pre>
-Test *Issue* for testing
-
- 1. Test List
- 2. Item
-
-**Testing**
-
- * Test list 2
- * Item
-
-# Test Section
-
- p = source.test_issue.post()
- p.count = p.count *5 #* 6
- if p.count > 5:
- print "Not < 5 & != 5"
-
-References: <a href="/p/allura-google-importer/issues/detail?id=1">issue 1</a>, <a href="/p/allura-google-importer/source/detail?r=2">r2</a>
-
-That's all
-
-
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=7&aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&name=&token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b></b>
-<br />
- 0 bytes
-
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&name=&token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-
-<div class="cursor_off vt issuecomment" id="hc1">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:35:15 2013">
- Today (2 minutes ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c1" href="/p/allura-google-importer/issues/detail?id=6#c1">#1</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Test *comment* is a comment
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&name=&token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at2.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=6&aid=60001000&name=at2.txt&token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&name=at2.txt&token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-</div>
-<div class="updates">
-<div class="round4"></div>
-<div class="round2"></div>
-<div class="round1"></div>
-<div class="box-inner">
-<b>Status:</b>
- Started
-
- <br />
-<b>Labels:</b>
- -OpSys-Linux OpSys-Windows
-
- <br />
-</div>
-<div class="round1"></div>
-<div class="round2"></div>
-<div class="round4"></div>
-</div>
-</div>
-<div class="cursor_off vt issuecomment" id="hc2">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:35:34 2013">
- Today (1 minute ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c2" href="/p/allura-google-importer/issues/detail?id=6#c2">#2</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Another comment with references: <a href="/p/allura-google-importer/issues/detail?id=2">issue 2</a>, <a href="/p/allura-google-importer/source/detail?r=1">r1</a>
-</pre>
-</div>
-<div class="cursor_off vt issuecomment" id="hc3">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:36:39 2013">
- Today (moments ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c3" href="/p/allura-google-importer/issues/detail?id=6#c3">#3</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Last comment
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003000&name=at4.txt&token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at4.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=6&aid=60003000&name=at4.txt&token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003000&name=at4.txt&token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003001&name=at1.txt&token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- <a href="../../allura-google-importer/issues/attachmentText?id=6&aid=60003001&name=at1.txt&token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667" target="_blank">View</a>
-
- <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003001&name=at1.txt&token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-<div class="cursor_off vt issuecomment" id="hc4">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug 8 15:36:57 2013">
- Today (moments ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c4" href="/p/allura-google-importer/issues/detail?id=6#c4">#4</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Oh, I forgot one (with an inter-project reference to <a href="/p/other-project/issues/detail?id=1">issue other-project:1</a>)
-</pre>
-<div class="updates">
-<div class="round4"></div>
-<div class="round2"></div>
-<div class="round1"></div>
-<div class="box-inner">
-<b>Labels:</b>
- OpSys-OSX
-
- <br />
-</div>
-<div class="round1"></div>
-<div class="round2"></div>
-<div class="round4"></div>
-</div>
-</div>
-
-</td>
-</tr>
-<tr>
-<td></td>
-<td class="vt issuecomment">
-<span class="indicator">►</span> <a href="https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment
- </td>
-</tr>
-</tbody>
-</table>
-<br />
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/dit_scripts.js"></script>
-</div>
-<form name="delcom" action="delComment.do?q=&can=2&groupby=&sort=&colspec=ID+Type+Status+Priority+Milestone+Owner+Summary" method="POST">
-<input type="hidden" name="sequence_num" value="" />
-<input type="hidden" name="mode" value="" />
-<input type="hidden" name="id" value="6" />
-<input type="hidden" name="token" value="" />
-</form>
-<div id="helparea"></div>
-<script type="text/javascript">
- _onload();
- function delComment(sequence_num, delete_mode) {
- var f = document.forms["delcom"];
- f.sequence_num.value = sequence_num;
- f.mode.value = delete_mode;
-
- f.submit();
- return false;
- }
-
- _floatMetadata();
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/kibbles.js"></script>
-<script type="text/javascript">
- _setupKibblesOnDetailPage(
- 'http://code.google.com/p/allura-google-importer/issues/list?cursor\x3dallura-google-importer%3A6',
- '/p/allura-google-importer/issues/entry',
- '../../allura-google-importer/issues/detail?id\x3d5',
- '',
- '', 'allura-google-importer', 6,
- false, false, codesite_token);
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/ph_core.js"></script>
-</div>
-<div id="footer" dir="ltr">
-<div class="text">
-<a href="/projecthosting/terms.html">Terms</a> -
- <a href="http://www.google.com/privacy.html">Privacy</a> -
- <a href="/p/support/">Project Hosting Help</a>
-</div>
-</div>
-<div class="hostedBy" style="margin-top: -20px;">
-<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
-</div>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/__init__.py b/ForgeImporters/forgeimporters/tests/google/__init__.py
deleted file mode 100644
index 144e298..0000000
--- a/ForgeImporters/forgeimporters/tests/google/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/functional/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/__init__.py b/ForgeImporters/forgeimporters/tests/google/functional/__init__.py
deleted file mode 100644
index 144e298..0000000
--- a/ForgeImporters/forgeimporters/tests/google/functional/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
deleted file mode 100644
index 938d1c7..0000000
--- a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
+++ /dev/null
@@ -1,316 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from unittest import TestCase
-import pkg_resources
-from datetime import datetime
-
-from BeautifulSoup import BeautifulSoup
-import mock
-from pylons import tmpl_context as c
-from IPython.testing.decorators import module_not_available, skipif
-from datadiff.tools import assert_equal
-
-from alluratest.controller import setup_basic_test
-from allura.tests.decorators import without_module
-from allura import model as M
-from forgetracker import model as TM
-from forgeimporters import base
-from forgeimporters import google
-import forgeimporters.google.tracker
-
-
-class TestGCTrackerImporter(TestCase):
-
- def _make_extractor(self, html):
- with mock.patch.object(base.h, 'urlopen') as urlopen:
- urlopen.return_value = ''
- extractor = google.GoogleCodeProjectExtractor(
- 'allura-google-importer', 'project_info')
- extractor.page = BeautifulSoup(html)
- extractor.url = "http://test/issue/?id=1"
- # iter_comments will make more get_page() calls but we don't want the real thing to run an mess up the .page
- # and .url attributes, make it a no-op which works with these tests (since its just the same page being
- # fetched really)
- extractor.get_page = lambda *a, **kw: ''
- return extractor
-
- def _make_ticket(self, issue, issue_id=1):
- self.assertIsNone(self.project.app_instance('test-issue'))
- with mock.patch.object(base.h, 'urlopen') as urlopen,\
- mock.patch.object(google.tracker, 'GoogleCodeProjectExtractor') as GPE,\
- mock.patch.object(google.tracker.M, 'AuditLog') as AL,\
- mock.patch('forgetracker.tasks.update_bin_counts') as ubc:
- urlopen.side_effect = lambda req, **kw: mock.Mock(
- read=req.get_full_url,
- info=lambda: {'content-type': 'text/plain'})
- GPE.iter_issues.return_value = [(issue_id, issue)]
- gti = google.tracker.GoogleCodeTrackerImporter()
- gti.import_tool(self.project, self.user,
- 'test-issue-project', mount_point='test-issue')
- c.app = self.project.app_instance('test-issue')
- query = TM.Ticket.query.find({'app_config_id': c.app.config._id})
- self.assertEqual(query.count(), 1)
- ticket = query.all()[0]
- return ticket
-
- def setUp(self, *a, **kw):
- super(TestGCTrackerImporter, self).setUp(*a, **kw)
- setup_basic_test()
- self.empty_issue = self._make_extractor(
- open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/empty-issue.html')).read())
- self.test_issue = self._make_extractor(
- open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read())
- c.project = self.project = M.Project.query.get(shortname='test')
- c.user = self.user = M.User.query.get(username='test-admin')
-
- def test_empty_issue(self):
- ticket = self._make_ticket(self.empty_issue)
- self.assertEqual(ticket.summary, 'Empty Issue')
- self.assertEqual(ticket.description,
- '*Originally created by:* john...@gmail.com\n\nEmpty')
- self.assertEqual(ticket.status, '')
- self.assertEqual(ticket.milestone, '')
- self.assertEqual(ticket.custom_fields, {})
- assert c.app.config.options.get('EnableVoting')
- open_bin = TM.Bin.query.get(
- summary='Open Tickets', app_config_id=c.app.config._id)
- self.assertItemsEqual(open_bin.terms.split(' && '), [
- '!status:Fixed',
- '!status:Verified',
- '!status:Invalid',
- '!status:Duplicate',
- '!status:WontFix',
- '!status:Done',
- ])
- closed_bin = TM.Bin.query.get(
- summary='Closed Tickets', app_config_id=c.app.config._id)
- self.assertItemsEqual(closed_bin.terms.split(' or '), [
- 'status:Fixed',
- 'status:Verified',
- 'status:Invalid',
- 'status:Duplicate',
- 'status:WontFix',
- 'status:Done',
- ])
-
- @without_module('html2text')
- def test_issue_basic_fields(self):
- anon = M.User.anonymous()
- ticket = self._make_ticket(self.test_issue)
- self.assertEqual(ticket.reported_by, anon)
- self.assertIsNone(ticket.assigned_to_id)
- self.assertEqual(ticket.summary, 'Test "Issue"')
- assert_equal(ticket.description,
- '*Originally created by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
- '*Originally owned by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
- '\n'
- 'Test \\*Issue\\* for testing\n'
- '\n'
- ' 1\\. Test List\n'
- ' 2\\. Item\n'
- '\n'
- '\\*\\*Testing\\*\\*\n'
- '\n'
- ' \\* Test list 2\n'
- ' \\* Item\n'
- '\n'
- '\\# Test Section\n'
- '\n'
- ' p = source\\.test\\_issue\\.post\\(\\)\n'
- ' p\\.count = p\\.count \\*5 \\#\\* 6\n'
- ' if p\\.count > 5:\n'
- ' print "Not < 5 & \\!= 5"\n'
- '\n'
- 'References: [issue 1](#1), [r2]\n'
- '\n'
- 'That\'s all'
- )
- self.assertEqual(ticket.status, 'Started')
- self.assertEqual(ticket.created_date, datetime(2013, 8, 8, 15, 33, 52))
- self.assertEqual(ticket.mod_date, datetime(2013, 8, 8, 15, 36, 57))
- self.assertEqual(ticket.custom_fields, {
- '_priority': 'Medium',
- '_opsys': 'All, OSX, Windows',
- '_component': 'Logic',
- '_type': 'Defect',
- '_milestone': 'Release1.0'
- })
- self.assertEqual(ticket.labels, ['Performance', 'Security'])
- self.assertEqual(ticket.votes_up, 1)
- self.assertEqual(ticket.votes, 1)
-
- def test_import_id(self):
- ticket = self._make_ticket(self.test_issue, issue_id=6)
- self.assertEqual(ticket.app.config.options.import_id, {
- 'source': 'Google Code',
- 'project_name': 'test-issue-project',
- })
- self.assertEqual(ticket.ticket_num, 6)
- self.assertEqual(ticket.import_id, {
- 'source': 'Google Code',
- 'project_name': 'test-issue-project',
- 'source_id': 6,
- })
-
- @skipif(module_not_available('html2text'))
- def test_html2text_escaping(self):
- ticket = self._make_ticket(self.test_issue)
- assert_equal(ticket.description,
- '*Originally created by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
- '*Originally owned by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
- '\n'
- 'Test \\*Issue\\* for testing\n'
- '\n'
- ' 1. Test List\n'
- ' 2. Item\n'
- '\n'
- '\\*\\*Testing\\*\\*\n'
- '\n'
- ' \\* Test list 2\n'
- ' \\* Item\n'
- '\n'
- '\\# Test Section\n'
- '\n'
- ' p = source.test\\_issue.post\\(\\)\n'
- ' p.count = p.count \\*5 \\#\\* 6\n'
- ' if p.count > 5:\n'
- ' print "Not < 5 & \\!= 5"\n'
- '\n'
- 'References: [issue 1](#1), [r2]\n'
- '\n'
- 'That\'s all'
- )
-
- def _assert_attachments(self, actual, *expected):
- self.assertEqual(len(actual), len(expected))
- atts = set((a.filename, a.content_type, a.rfile().read())
- for a in actual)
- self.assertEqual(atts, set(expected))
-
- def test_attachments(self):
- ticket = self._make_ticket(self.test_issue)
- self._assert_attachments(ticket.attachments,
- ('at1.txt', 'text/plain',
- 'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255'),
- )
-
- @without_module('html2text')
- def test_comments(self):
- anon = M.User.anonymous()
- ticket = self._make_ticket(self.test_issue)
- actual_comments = ticket.discussion_thread.find_posts()
- expected_comments = [
- {
- 'timestamp': datetime(2013, 8, 8, 15, 35, 15),
- 'text': (
- '*Originally posted by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
- '\n'
- 'Test \\*comment\\* is a comment\n'
- '\n'
- '**Labels:** -OpSys-Linux OpSys-Windows\n'
- '**Status:** Started'
- ),
- 'attachments': [
- ('at2.txt', 'text/plain',
- 'http://allura-google-importer.googlecode.com/issues/attachment?aid=60001000&name=at2.txt&token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667'),
- ],
- },
- {
- 'timestamp': datetime(2013, 8, 8, 15, 35, 34),
- 'text': (
- '*Originally posted by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
- '\n'
- 'Another comment with references: [issue 2](#2), [r1]\n\n'
- ),
- },
- {
- 'timestamp': datetime(2013, 8, 8, 15, 36, 39),
- 'text': (
- '*Originally posted by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
- '\n'
- 'Last comment\n\n'
- ),
- 'attachments': [
- ('at4.txt', 'text/plain',
- 'http://allura-google-importer.googlecode.com/issues/attachment?aid=60003000&name=at4.txt&token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667'),
- ('at1.txt', 'text/plain',
- 'http://allura-google-importer.googlecode.com/issues/attachment?aid=60003001&name=at1.txt&token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667'),
- ],
- },
- {
- 'timestamp': datetime(2013, 8, 8, 15, 36, 57),
- 'text': (
- '*Originally posted by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
- '\n'
- 'Oh, I forgot one \\(with an inter\\-project reference to [issue other\\-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)\n'
- '\n'
- '**Labels:** OpSys-OSX'
- ),
- },
- ]
- self.assertEqual(len(actual_comments), len(expected_comments))
- for actual, expected in zip(actual_comments, expected_comments):
- self.assertEqual(actual.author(), anon)
- self.assertEqual(actual.timestamp, expected['timestamp'])
- self.assertEqual(actual.text, expected['text'])
- if 'attachments' in expected:
- self._assert_attachments(
- actual.attachments, *expected['attachments'])
-
- def test_globals(self):
- globals = self._make_ticket(self.test_issue, issue_id=6).globals
- self.assertEqual(globals.open_status_names, 'New Accepted Started')
- self.assertEqual(globals.closed_status_names,
- 'Fixed Verified Invalid Duplicate WontFix Done')
- self.assertEqual(globals.last_ticket_num, 6)
- self.assertItemsEqual(globals.custom_fields, [
- {
- 'label': 'Milestone',
- 'name': '_milestone',
- 'type': 'milestone',
- 'options': '',
- 'milestones': [
- {'name': 'Release1.0', 'due_date':
- None, 'complete': False},
- ],
- },
- {
- 'label': 'Type',
- 'name': '_type',
- 'type': 'select',
- 'options': 'Defect',
- },
- {
- 'label': 'Priority',
- 'name': '_priority',
- 'type': 'select',
- 'options': 'Medium',
- },
- {
- 'label': 'OpSys',
- 'name': '_opsys',
- 'type': 'string',
- 'options': '',
- },
- {
- 'label': 'Component',
- 'name': '_component',
- 'type': 'string',
- 'options': '',
- },
- ])