You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2013/09/24 19:08:00 UTC

[21/50] git commit: [#6535] ticket:417 tests for github tracker import

[#6535] ticket:417 tests for github tracker import


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/30d40210
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/30d40210
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/30d40210

Branch: refs/heads/cj/6422
Commit: 30d40210d89a8434cf628b89c7edd8d6e925c193
Parents: fedf201
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Wed Aug 28 15:41:33 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Sep 19 14:46:50 2013 +0000

----------------------------------------------------------------------
 ForgeImporters/forgeimporters/github/tracker.py |   4 +-
 .../tests/github/test_extractor.py              |  50 ++++++-
 .../forgeimporters/tests/github/test_tracker.py | 133 +++++++++++++++++++
 3 files changed, 179 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/30d40210/ForgeImporters/forgeimporters/github/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/github/tracker.py b/ForgeImporters/forgeimporters/github/tracker.py
index 8c402d0..fea18ed 100644
--- a/ForgeImporters/forgeimporters/github/tracker.py
+++ b/ForgeImporters/forgeimporters/github/tracker.py
@@ -31,8 +31,8 @@ class GitHubTrackerImporter(ToolImporter):
             mount_label=None, **kw):
         app = project.install_app('tickets', mount_point, mount_label,
                 EnableVoting=True,
-                open_status_names='New Accepted',
-                closed_status_names='Done',
+                open_status_names='New Accepted Started',
+                closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
             )
         ThreadLocalORMSession.flush_all()
         extractor = GitHubProjectExtractor(

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/30d40210/ForgeImporters/forgeimporters/tests/github/test_extractor.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/github/test_extractor.py b/ForgeImporters/forgeimporters/tests/github/test_extractor.py
index cffbf81..8eb5811 100644
--- a/ForgeImporters/forgeimporters/tests/github/test_extractor.py
+++ b/ForgeImporters/forgeimporters/tests/github/test_extractor.py
@@ -15,22 +15,60 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import json
 from unittest import TestCase
 
 from ... import github
 
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from StringIO import StringIO
+
+
+
 
 class TestGitHubProjectExtractor(TestCase):
+    PROJECT_INFO = {
+        'description': 'project description',
+        'homepage': 'http://example.com',
+    }
+    CLOSED_ISSUES_LIST = [
+        {u'number': 1},
+        {u'number': 2},
+    ]
+    OPENED_ISSUES_LIST = [
+        {u'number': 3},
+    ]
+    ISSUE_COMMENTS = [u'hello', u'mocked_comment']
+
+    def mocked_urlopen(self, url):
+        if url.endswith('/test_project'):
+            return StringIO(json.dumps(self.PROJECT_INFO))
+        elif url.endswith('/issues?state=closed'):
+            return StringIO(json.dumps(self.CLOSED_ISSUES_LIST))
+        elif url.endswith('/issues?state=opened'):
+            return StringIO(json.dumps(self.OPENED_ISSUES_LIST))
+        elif url.endswith('/comments'):
+            return StringIO(json.dumps(self.ISSUE_COMMENTS))
+
     def setUp(self):
-        import json
-        from StringIO import StringIO
-        self.extractor = github.GitHubProjectExtractor('testproject')
-        d = dict(description='project description',
-                homepage='http://example.com')
-        self.extractor.urlopen = lambda url: StringIO(json.dumps(d))
+        self.extractor = github.GitHubProjectExtractor('test_project')
+        self.extractor.urlopen = self.mocked_urlopen
 
     def test_get_summary(self):
         self.assertEqual(self.extractor.get_summary(), 'project description')
 
     def test_get_homepage(self):
         self.assertEqual(self.extractor.get_homepage(), 'http://example.com')
+
+    def test_iter_issues(self):
+        issues = list(self.extractor.iter_issues())
+        all_issues = zip((1,2), self.CLOSED_ISSUES_LIST)
+        all_issues.append((3, self.OPENED_ISSUES_LIST[0]))
+        self.assertEqual(issues, all_issues)
+
+    def test_iter_comments(self):
+        mock_issue = {'comments_url': '/issues/1/comments'}
+        comments = list(self.extractor.iter_comments(mock_issue))
+        self.assertEqual(comments, self.ISSUE_COMMENTS)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/30d40210/ForgeImporters/forgeimporters/tests/github/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/github/test_tracker.py b/ForgeImporters/forgeimporters/tests/github/test_tracker.py
new file mode 100644
index 0000000..382be2b
--- /dev/null
+++ b/ForgeImporters/forgeimporters/tests/github/test_tracker.py
@@ -0,0 +1,133 @@
+#       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 operator import itemgetter
+from unittest import TestCase
+import mock
+
+from ...github 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, 'GitHubProjectExtractor')
+    def test_import_tool(self, gpe, TM, M, session, tlos, c, g):
+        importer = tracker.GitHubTrackerImporter()
+        importer.process_fields = mock.Mock()
+        importer.process_milestones = mock.Mock()
+        importer.process_comments = mock.Mock()
+        importer.postprocess_milestones= mock.Mock()
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        gpe.iter_issues.return_value = [(50, mock.Mock()), (100, mock.Mock())]
+
+        importer.import_tool(project, user, project_name='project_name',
+                mount_point='mount_point', mount_label='mount_label', user_name='me')
+
+        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',
+            )
+        gpe.iter_issues.assert_called_once()
+        self.assertEqual(tlos.flush_all.call_args_list, [
+                mock.call(),
+                mock.call(),
+            ])
+        g.post_event.assert_called_once_with('project_updated')
+        app.globals.invalidate_bin_counts.assert_called_once_with()
+
+    def test_process_fields(self):
+        ticket = mock.Mock()
+        issue = {
+            'title': 'title',
+            'state': 'New',
+            'created_at': 'created_at',
+            'updated_at': 'updated_at',
+            'assignee': {'login': 'owner'},
+            'user': {'login': 'creator'},
+            'body': 'hello',
+            'labels': [{'name': 'first'}, {'name': 'second'}],
+        }
+        importer = tracker.GitHubTrackerImporter()
+        with mock.patch.object(tracker, 'datetime') as dt:
+            dt.strptime.side_effect = lambda s,f: s
+            importer.process_fields(ticket, issue)
+            self.assertEqual(ticket.summary, 'title')
+            self.assertEqual(ticket.description, '*Originally created by:* creator\n*Originally owned by:* owner\n\nhello')
+            self.assertEqual(ticket.status, 'New')
+            self.assertEqual(ticket.created_date, 'created_at')
+            self.assertEqual(ticket.mod_date, 'updated_at')
+            self.assertEqual(dt.strptime.call_args_list, [
+                    mock.call('created_at', '%Y-%m-%dT%H:%M:%SZ'),
+                    mock.call('updated_at', '%Y-%m-%dT%H:%M:%SZ'),
+                ])
+            self.assertEqual(ticket.labels, ['first', 'second'])
+
+    @mock.patch.object(tracker, 'c')
+    def test_postprocess_milestones(self, c):
+        importer = tracker.GitHubTrackerImporter()
+        importer.open_milestones = set([
+            ('first', datetime(day=23, month=4, year=2015)),
+            ('second',datetime(day=25, month=4, year=2015))
+        ])
+        milestones = importer.postprocess_milestones()
+        self.assertItemsEqual(milestones, [
+                {
+                    'name': '_milestone',
+                    'type': 'milestone',
+                    'label': 'Milestone',
+                    'milestones': [
+                        {'name': 'first', 'due_date': u'2015-04-23', 'complete': False},
+                        {'name': 'second', 'due_date': u'2015-04-25', 'complete': False},
+                    ],
+                },
+            ])
+
+    def test_get_attachments(self):
+        importer = tracker.GitHubTrackerImporter()
+        body = 'hello\n' \
+        '![cdbpzjc5ex4](https://f.cloud.github.com/assets/979771/1027411/a393ab5e-0e70-11e3-8a38-b93a3df904cf.jpg)\r\n'
+        new_body, attachments = importer._get_attachments(body)
+        self.assertEqual(new_body, 'hello\n')
+        self.assertEqual(len(attachments), 1)
+        self.assertEqual(attachments[0].url, 'https://f.cloud.github.com/assets/979771/1027411/a393ab5e-0e70-11e3-8a38-b93a3df904cf.jpg')
+
+    def test_process_comments(self):
+        ticket = mock.Mock()
+        extractor = mock.Mock()
+        issue = {'comments_url': '/comments'}
+        extractor.iter_comments.return_value = [
+                {
+                    'body': 'hello',
+                    'created_at': '2013-08-26T16:57:53Z',
+                    'user': {'login': 'me'},
+                }
+            ]
+        importer = tracker.GitHubTrackerImporter()
+        importer.process_comments(extractor, ticket, issue)
+        self.assertEqual(ticket.discussion_thread.add_post.call_args_list[0], mock.call(
+                text='hello\n*Originally posted by: me*',
+                timestamp=datetime(2013, 8, 26, 16, 57, 53),
+                ignore_security=True,
+            ))
\ No newline at end of file