Repository: nephila/python-taiga
Pull request #73 (2018-05-27 01:52:05)

Merge #51
Merge #51 with tests
Fix #51 


Patch:
diff --git a/taiga/models/base.py b/taiga/models/base.py
index 64a56b5..cd6b4eb 100644
--- a/taiga/models/base.py
+++ b/taiga/models/base.py
@@ -142,7 +142,7 @@ class InstanceResource(Resource):
         self.requester = requester
         for key, value in six.iteritems(params):
             if key in ['created_date', 'modified_date']:
-                if re.compile('\d+-\d+-\d+T\d+:\d+:\d+\+0000').match(value):
+                if re.compile(r'\d+-\d+-\d+T\d+:\d+:\d+\+0000').match(value):
                     d = dateutil.parser.parse(value)
                     value = d.astimezone(dateutil.tz.tzlocal())
             if six.PY2:
diff --git a/taiga/models/models.py b/taiga/models/models.py
index e826564..ae296ae 100644
--- a/taiga/models/models.py
+++ b/taiga/models/models.py
@@ -294,6 +294,8 @@ class UserStory(CustomAttributeResource, CommentableResource):
     endpoint = 'userstories'
 
     repr_attribute = 'subject'
+    element_type = 'User Story'
+    element_shortcut = 'us'
 
     allowed_params = [
         'assigned_to', 'assigned_users', 'backlog_order', 'blocked_note', 'version',
@@ -596,6 +598,8 @@ class Task(CustomAttributeResource, CommentableResource):
     endpoint = 'tasks'
 
     repr_attribute = 'subject'
+    element_type = 'Task'
+    element_shortcut = 'task'
 
     allowed_params = [
         'assigned_to', 'blocked_note', 'description', 'version',
@@ -748,6 +752,8 @@ class Issue(CustomAttributeResource, CommentableResource):
     endpoint = 'issues'
 
     repr_attribute = 'subject'
+    element_type = 'Issue'
+    element_shortcut = 'issue'
 
     allowed_params = [
         'assigned_to', 'blocked_note', 'description', 'version',
@@ -984,6 +990,23 @@ class Project(InstanceResource):
         'us_statuses': UserStoryStatuses
     }
 
+    def get_item_by_ref(self, ref):
+        response = self.requester.get(
+            '/resolver?project={project_id}&ref={task_ref}',
+            task_ref=ref,
+            project_id=self.slug
+        )
+        response_json = response.json()
+
+        if response_json and 'task' in response_json:
+            return self.get_task_by_ref(ref)
+        elif response_json and 'us' in response_json:
+            return self.get_userstory_by_ref(ref)
+        elif response_json and 'issue' in response_json:
+            return self.get_issue_by_ref(ref)
+        else:
+            return None
+
     def get_task_by_ref(self, ref):
         """
         Get a :class:`Task` by ref.


Test patch:
diff --git a/tests/resources/projects_resolve_issue.json b/tests/resources/projects_resolve_issue.json
new file mode 100644
index 0000000..2e330d9
--- /dev/null
+++ b/tests/resources/projects_resolve_issue.json
@@ -0,0 +1,4 @@
+{
+    "issue": 1,
+    "project": 1
+}
diff --git a/tests/resources/projects_resolve_task.json b/tests/resources/projects_resolve_task.json
new file mode 100644
index 0000000..0db2bc7
--- /dev/null
+++ b/tests/resources/projects_resolve_task.json
@@ -0,0 +1,4 @@
+{
+    "task": 1,
+    "project": 1
+}
diff --git a/tests/resources/projects_resolve_us.json b/tests/resources/projects_resolve_us.json
new file mode 100644
index 0000000..4f5ba20
--- /dev/null
+++ b/tests/resources/projects_resolve_us.json
@@ -0,0 +1,4 @@
+{
+    "us": 1,
+    "project": 1
+}
diff --git a/tests/test_projects.py b/tests/test_projects.py
index a19daf1..29dbbdb 100644
--- a/tests/test_projects.py
+++ b/tests/test_projects.py
@@ -48,6 +48,43 @@ class TestProjects(unittest.TestCase):
             endpoint='projects', slug='my_slug'
         )
 
+    @patch('taiga.requestmaker.RequestMaker.get')
+    def test_get_item_by_ref(self, mock_requestmaker_get):
+        mock_requestmaker_get.return_value = MockResponse(
+            200, create_mock_json('tests/resources/project_details_success.json')
+        )
+        api = TaigaAPI(token='f4k3')
+        project = api.projects.get_by_slug('my_slug')
+        mock_requestmaker_get.return_value = MockResponse(
+            200, create_mock_json('tests/resources/projects_resolve_us.json')
+        )
+        with patch.object(project, 'get_userstory_by_ref') as mock_get_userstory_by_ref:
+            mock_get_userstory_by_ref.return_value = MockResponse(
+                200, create_mock_json('tests/resources/userstory_details_success.json')
+            )
+            project.get_item_by_ref(1)
+            mock_get_userstory_by_ref.assert_called_with(1)
+
+        mock_requestmaker_get.return_value = MockResponse(
+            200, create_mock_json('tests/resources/projects_resolve_issue.json')
+        )
+        with patch.object(project, 'get_issue_by_ref') as mock_get_issue_by_ref:
+            mock_get_issue_by_ref.return_value = MockResponse(
+                200, create_mock_json('tests/resources/issue_details_success.json')
+            )
+            project.get_item_by_ref(1)
+            mock_get_issue_by_ref.assert_called_with(1)
+
+        mock_requestmaker_get.return_value = MockResponse(
+            200, create_mock_json('tests/resources/projects_resolve_task.json')
+        )
+        with patch.object(project, 'get_task_by_ref') as mock_get_task_by_ref:
+            mock_get_task_by_ref.return_value = MockResponse(
+                200, create_mock_json('tests/resources/task_details_success.json')
+            )
+            project.get_item_by_ref(1)
+            mock_get_task_by_ref.assert_called_with(1)
+
     @patch('taiga.requestmaker.RequestMaker.get')
     def test_get_userstories_by_ref(self, mock_requestmaker_get):
         mock_requestmaker_get.return_value = MockResponse(