diff --git a/changes/169.bugfix b/changes/169.bugfix new file mode 100644 index 0000000..4642b44 --- /dev/null +++ b/changes/169.bugfix @@ -0,0 +1 @@ +Fix parser when entries is None diff --git a/taiga/models/base.py b/taiga/models/base.py index 7e08297..3ec60b1 100644 --- a/taiga/models/base.py +++ b/taiga/models/base.py @@ -104,15 +104,17 @@ def _new_resource(self, **attrs): def parse(cls, requester, entries): """Parse a JSON array into a list of model instances.""" result_entries = SearchableList() - for entry in entries: - result_entries.append(cls.instance.parse(requester, entry)) + if entries: + for entry in entries: + result_entries.append(cls.instance.parse(requester, entry)) return result_entries def parse_list(self, entries): """Parse a JSON array into a list of model instances.""" result_entries = SearchableList() - for entry in entries: - result_entries.append(self.instance.parse(self.requester, entry)) + if entries: + for entry in entries: + result_entries.append(self.instance.parse(self.requester, entry)) return result_entries diff --git a/tests/resources/project_details_success_no_swimlanes.json b/tests/resources/project_details_success_no_swimlanes.json new file mode 100644 index 0000000..e0591c1 --- /dev/null +++ b/tests/resources/project_details_success_no_swimlanes.json @@ -0,0 +1,823 @@ +{ + "likes": 1, + "is_liked": true, + "is_watched": true, + "watchers": [ + 5, + 4, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14 + ], + "tags": [], + "anon_permissions": [], + "public_permissions": [], + "my_permissions": [ + "add_wiki_page", + "add_member", + "view_project", + "admin_project_values", + "view_wiki_pages", + "view_wiki_links", + "admin_roles", + "add_task", + "remove_member", + "delete_task", + "add_comments_to_issue", + "add_milestone", + "view_tasks", + "add_us", + "delete_us", + "modify_task", + "add_comments_to_task", + "add_us_to_project", + "view_us", + "add_issue", + "modify_us", + "view_issues", + "modify_project", + "view_milestones", + "request_membership", + "modify_issue", + "modify_wiki_link", + "delete_project", + "delete_milestone", + "delete_wiki_page", + "delete_wiki_link", + "add_comments_to_us", + "modify_milestone", + "delete_issue", + "add_wiki_link", + "modify_wiki_page" + ], + "i_am_owner": true, + "tags_colors": { + "voluptatem": "#00d60c", + "vero": "#74e191", + "nam": "#ce4004", + "velit": "#790ea4", + "libero": "#5b20bf", + "exercitationem": "#ac7c74", + "odio": "#ad7fa8", + "sit": "#abdcde", + "tempore": "#ae2670", + "quo": "#857670", + "commodi": "#edd400", + "necessitatibus": "#84e3b6", + "ipsa": "#ffa8ed", + "illo": "#3531fd", + "dolorum": "#db7ec2", + "natus": "#e610c1", + "eaque": "#3e7c66", + "omnis": "#fc9548", + "laboriosam": "#b2966d", + "harum": "#b42d3c", + "inventore": "#2fbc07", + "animi": "#d93411", + "excepturi": "#5c3c96", + "at": "#27e90d", + "voluptatum": "#02d22f", + "saepe": "#b87b67", + "provident": "#7fdcf2", + "repudiandae": "#3a2b71", + "vitae": "#d9fe5e", + "et": "#729fcf", + "fuga": "#e86797", + "voluptates": "#2e3436", + "quaerat": "#0b4425", + "consectetur": "#97176f", + "obcaecati": "#9ccd46", + "eos": "#5c3566", + "non": "#37031f", + "quis": "#223610", + "reprehenderit": "#6c82c6", + "recusandae": "#4e9a06", + "doloribus": "#fb1b00", + "esse": "#d77661", + "quod": "#0e5b24", + "iusto": "#3a10e8", + "illum": "#898c66", + "ullam": "#98ad13", + "eligendi": "#5d8273", + "aspernatur": "#82854c", + "aut": "#fcaf3e", + "dolorem": "#604860", + "odit": "#e2b537", + "magnam": "#d1fac1", + "iste": "#491b3a", + "quisquam": "#ebca0b", + "fugit": "#9345df", + "nostrum": "#f57900", + "voluptatibus": "#681ad4", + "molestiae": "#1415dc", + "expedita": "#c4a000", + "reiciendis": "#560ff6", + "itaque": "#090d7d", + "consequatur": "#fce94f", + "deserunt": "#e7b695", + "mollitia": "#002e7f", + "impedit": "#cde1f0", + "possimus": "#a40000", + "repellendus": "#13f068", + "quae": "#d91a8b", + "labore": "#6fdf52", + "nobis": "#91c2a9", + "iure": "#019320", + "amet": "#cc0000", + "incidunt": "#3099ec", + "ducimus": "#ea6bb9", + "aperiam": "#a2b100", + "modi": "#494e30", + "rem": "#688119", + "praesentium": "#0cd131", + "quam": "#0149d1", + "est": "#665de1", + "aliquid": "#f01df5", + "sint": "#3b2404", + "in": "#af10ef", + "ea": "#2c80b2", + "fugiat": "#1c563a", + "neque": "#150607", + "temporibus": "#a2c51a", + "sed": "#d3d7cf", + "nihil": "#98a352", + "voluptate": "#b0eff0", + "molestias": "#92db0b", + "dignissimos": "#79b3c9", + "quasi": "#73d216", + "a": "#86f7e4", + "asperiores": "#a69134", + "totam": "#560a5d", + "placeat": "#75507b", + "veniam": "#4661cf", + "id": "#87ea5d", + "minus": "#59b653", + "earum": "#24bec9", + "blanditiis": "#65026b", + "assumenda": "#52b91a", + "optio": "#7617d3", + "facilis": "#0f6b6b", + "porro": "#05175b", + "maxime": "#1acc29", + "nisi": "#ef7fdc", + "ut": "#e74669", + "ipsam": "#fa74af", + "rerum": "#b1c629", + "adipisci": "#257dec", + "dolore": "#61b076", + "soluta": "#1398ab", + "facere": "#113f4a", + "quidem": "#3465a4", + "aliquam": "#631249", + "corrupti": "#432493", + "dicta": "#939b44", + "accusantium": "#b36f86", + "nemo": "#e81498", + "debitis": "#9631e4", + "similique": "#204a87", + "maiores": "#cbb2b3", + "deleniti": "#6188db", + "ex": "#e06613", + "voluptas": "#729359", + "perferendis": "#888a85", + "doloremque": "#61405d", + "ratione": "#570ce3", + "repellat": "#807389", + "cupiditate": "#144bba", + "ab": "#da2361", + "veritatis": "#768459", + "laborum": "#67eac4", + "magni": "#429e6f", + "officia": "#c4f027", + "cum": "#ab14d9", + "sequi": "#9f6274", + "architecto": "#9d1e93", + "error": "#11f957", + "tenetur": "#351c86", + "atque": "#713547", + "nulla": "#894727", + "qui": "#61f611", + "perspiciatis": "#afb825", + "nesciunt": "#4c8404", + "beatae": "#b844bd", + "dolores": "#7fea8e", + "ipsum": "#ce5c00", + "unde": "#8ae234", + "cumque": "#ad75ec", + "tempora": "#b55d30", + "officiis": "#964862", + "autem": "#5e8c91", + "distinctio": "#1f8960", + "consequuntur": "#ce24ec", + "enim": "#ef2929" + }, + "total_closed_milestones": 0, + "notify_level": 1, + "us_statuses": [ + { + "id": 1, + "name": "New", + "slug": "new", + "order": 1, + "is_closed": false, + "is_archived": false, + "color": "#999999", + "wip_limit": null, + "project": 1 + }, + { + "id": 2, + "name": "Ready", + "slug": "ready", + "order": 2, + "is_closed": false, + "is_archived": false, + "color": "#ff8a84", + "wip_limit": null, + "project": 1 + }, + { + "id": 3, + "name": "In progress", + "slug": "in-progress", + "order": 3, + "is_closed": false, + "is_archived": false, + "color": "#ff9900", + "wip_limit": null, + "project": 1 + }, + { + "id": 4, + "name": "Ready for test", + "slug": "ready-for-test", + "order": 4, + "is_closed": false, + "is_archived": false, + "color": "#fcc000", + "wip_limit": null, + "project": 1 + }, + { + "id": 5, + "name": "Done", + "slug": "done", + "order": 5, + "is_closed": true, + "is_archived": false, + "color": "#669900", + "wip_limit": null, + "project": 1 + }, + { + "id": 6, + "name": "Archived", + "slug": "archived", + "order": 6, + "is_closed": true, + "is_archived": true, + "color": "#5c3566", + "wip_limit": null, + "project": 1 + }, + { + "id": 241, + "name": "lol", + "slug": "lol", + "order": 7, + "is_closed": false, + "is_archived": false, + "color": "#999999", + "wip_limit": null, + "project": 1 + }, + { + "id": 242, + "name": "asd", + "slug": "asd", + "order": 8, + "is_closed": false, + "is_archived": false, + "color": "#999999", + "wip_limit": null, + "project": 1 + } + ], + "points": [ + { + "id": 1, + "name": "?", + "order": 1, + "value": null, + "project": 1 + }, + { + "id": 2, + "name": "0", + "order": 2, + "value": 0.0, + "project": 1 + }, + { + "id": 3, + "name": "1/2", + "order": 3, + "value": 0.5, + "project": 1 + }, + { + "id": 4, + "name": "1", + "order": 4, + "value": 1.0, + "project": 1 + }, + { + "id": 5, + "name": "2", + "order": 5, + "value": 2.0, + "project": 1 + }, + { + "id": 6, + "name": "3", + "order": 6, + "value": 3.0, + "project": 1 + }, + { + "id": 7, + "name": "5", + "order": 7, + "value": 5.0, + "project": 1 + }, + { + "id": 8, + "name": "8", + "order": 8, + "value": 8.0, + "project": 1 + }, + { + "id": 9, + "name": "10", + "order": 9, + "value": 10.0, + "project": 1 + }, + { + "id": 10, + "name": "15", + "order": 10, + "value": 15.0, + "project": 1 + }, + { + "id": 11, + "name": "20", + "order": 11, + "value": 20.0, + "project": 1 + }, + { + "id": 12, + "name": "40", + "order": 12, + "value": 40.0, + "project": 1 + } + ], + "task_statuses": [ + { + "id": 1, + "name": "New", + "slug": "new", + "order": 1, + "is_closed": false, + "color": "#999999", + "project": 1 + }, + { + "id": 2, + "name": "In progress", + "slug": "in-progress", + "order": 2, + "is_closed": false, + "color": "#ff9900", + "project": 1 + }, + { + "id": 3, + "name": "Ready for test", + "slug": "ready-for-test", + "order": 3, + "is_closed": true, + "color": "#ffcc00", + "project": 1 + }, + { + "id": 4, + "name": "Closed", + "slug": "closed", + "order": 4, + "is_closed": true, + "color": "#669900", + "project": 1 + }, + { + "id": 5, + "name": "Needs Info", + "slug": "needs-info", + "order": 5, + "is_closed": false, + "color": "#999999", + "project": 1 + } + ], + "issue_statuses": [ + { + "id": 2, + "name": "In progress", + "slug": "in-progress", + "order": 1, + "is_closed": false, + "color": "#5E8C6A", + "project": 1 + }, + { + "id": 4, + "name": "Closed", + "slug": "closed", + "order": 3, + "is_closed": true, + "color": "#BFB35A", + "project": 1 + }, + { + "id": 5, + "name": "Needs Info", + "slug": "needs-info", + "order": 4, + "is_closed": false, + "color": "#89BAB4", + "project": 1 + }, + { + "id": 6, + "name": "Rejected", + "slug": "rejected", + "order": 5, + "is_closed": true, + "color": "#CC0000", + "project": 1 + }, + { + "id": 7, + "name": "Postponed", + "slug": "postponed", + "order": 6, + "is_closed": false, + "color": "#666666", + "project": 1 + }, + { + "id": 428, + "name": "Workinon", + "slug": "workinon", + "order": 7, + "is_closed": false, + "color": "#999999", + "project": 1 + }, + { + "id": 429, + "name": "Rambleon", + "slug": "rambleon", + "order": 8, + "is_closed": false, + "color": "#999999", + "project": 1 + }, + { + "id": 430, + "name": "ClosedUp", + "slug": "closedup", + "order": 10, + "is_closed": true, + "color": "#999999", + "project": 1 + } + ], + "issue_types": [ + { + "id": 1, + "name": "Bug", + "order": 1, + "color": "#89BAB4", + "project": 1 + }, + { + "id": 2, + "name": "Question", + "order": 2, + "color": "#ba89a8", + "project": 1 + }, + { + "id": 3, + "name": "Enhancement", + "order": 3, + "color": "#89a8ba", + "project": 1 + } + ], + "priorities": [ + { + "id": 1, + "name": "Low", + "order": 1, + "color": "#666666", + "project": 1 + }, + { + "id": 2, + "name": "Normal", + "order": 3, + "color": "#669933", + "project": 1 + }, + { + "id": 3, + "name": "High", + "order": 5, + "color": "#CC0000", + "project": 1 + } + ], + "severities": [ + { + "id": 1, + "name": "Wishlist", + "order": 1, + "color": "#666666", + "project": 1 + }, + { + "id": 2, + "name": "Minor", + "order": 2, + "color": "#669933", + "project": 1 + }, + { + "id": 3, + "name": "Normal", + "order": 3, + "color": "#0000FF", + "project": 1 + }, + { + "id": 4, + "name": "Important", + "order": 4, + "color": "#FFA500", + "project": 1 + }, + { + "id": 5, + "name": "Critical", + "order": 5, + "color": "#CC0000", + "project": 1 + } + ], + "userstory_custom_attributes": [], + "task_custom_attributes": [], + "issue_custom_attributes": [], + "roles": [ + { + "id": 1, + "name": "UX", + "slug": "ux", + "order": 10, + "computable": true + }, + { + "id": 2, + "name": "Design", + "slug": "design", + "order": 20, + "computable": true + }, + { + "id": 3, + "name": "Front", + "slug": "front", + "order": 30, + "computable": true + }, + { + "id": 4, + "name": "Back", + "slug": "back", + "order": 40, + "computable": true + }, + { + "id": 5, + "name": "Product Owner", + "slug": "product-owner", + "order": 50, + "computable": true + }, + { + "id": 6, + "name": "Stakeholder", + "slug": "stakeholder", + "order": 60, + "computable": false + } + ], + "swimlanes": null, + "members": [ + { + "id": 10, + "username": "user5", + "full_name": "Alicia Diaz", + "full_name_display": "Alicia Diaz", + "color": "#C0FF33", + "photo": "//www.gravatar.com/avatar/e2cc11c9138524224f87aa72c1a343db?size=80", + "is_active": true, + "role_name": "Front", + "user": 10, + "role": 3, + "is_owner": true + }, + { + "id": 9, + "username": "user4", + "full_name": "Alicia Flores", + "full_name_display": "Alicia Flores", + "color": "#FFF8E7", + "photo": "//www.gravatar.com/avatar/555b9a0deff8123ed6e7672f7dbaed75?size=80", + "is_active": true, + "role_name": "Back", + "user": 9, + "role": 4, + "is_owner": true + }, + { + "id": 4, + "username": "admin", + "full_name": "Andre Stagi", + "full_name_display": "Andre Stagi", + "color": "", + "photo": "//www.gravatar.com/avatar/d44459efd0fcf29bab2e6b7c1e98c8a0?size=80", + "is_active": true, + "role_name": "Design", + "user": 4, + "role": 2, + "is_owner": true + }, + { + "id": 6, + "username": "user1", + "full_name": "Josefa Serrano", + "full_name_display": "Josefa Serrano", + "color": "#FFCC00", + "photo": "//www.gravatar.com/avatar/0163263aeacdbb0a723152ee0d7225b2?size=80", + "is_active": true, + "role_name": "Product Owner", + "user": 6, + "role": 5, + "is_owner": true + }, + { + "id": 12, + "username": "user7", + "full_name": "Josefina Reyes", + "full_name_display": "Josefina Reyes", + "color": "#FFFF00", + "photo": "//www.gravatar.com/avatar/66ceeab4ce04e47a95f64cb2be785376?size=80", + "is_active": true, + "role_name": "UX", + "user": 12, + "role": 1, + "is_owner": true + }, + { + "id": 11, + "username": "user6", + "full_name": "Mar Serrano", + "full_name_display": "Mar Serrano", + "color": "#FC8EAC", + "photo": "//www.gravatar.com/avatar/ba0e3558f431a5372cf5e225eec0992f?size=80", + "is_active": true, + "role_name": "Stakeholder", + "user": 11, + "role": 6, + "is_owner": true + }, + { + "id": 8, + "username": "user3", + "full_name": "Margarita Rubio", + "full_name_display": "Margarita Rubio", + "color": "#40826D", + "photo": "//www.gravatar.com/avatar/fba51849dd340c3bc8571c3667b25861?size=80", + "is_active": true, + "role_name": "Back", + "user": 8, + "role": 4, + "is_owner": false + }, + { + "id": 7, + "username": "user2", + "full_name": "Rafael Herrero", + "full_name_display": "Rafael Herrero", + "color": "#0F0F0F", + "photo": "//www.gravatar.com/avatar/e3118e4dc62fd3a8821725a73a94ced1?size=80", + "is_active": true, + "role_name": "Design", + "user": 7, + "role": 2, + "is_owner": true + }, + { + "id": 5, + "username": "user6532909695705815086", + "full_name": "Silvia Soto", + "full_name_display": "Silvia Soto", + "color": "#2099DB", + "photo": "//www.gravatar.com/avatar/f64db24896b923753d440e23faa856aa?size=80", + "is_active": true, + "role_name": "Product Owner", + "user": 5, + "role": 5, + "is_owner": true + }, + { + "id": 14, + "username": "user9", + "full_name": "Teresa Gallardo", + "full_name_display": "Teresa Gallardo", + "color": "#FFCC00", + "photo": "//www.gravatar.com/avatar/7c5a4c10628c2a203b24e2d10e3e28e1?size=80", + "is_active": true, + "role_name": "Design", + "user": 14, + "role": 2, + "is_owner": true + }, + { + "id": 13, + "username": "user8", + "full_name": "Victoria Nu\u00f1ez", + "full_name_display": "Victoria Nu\u00f1ez", + "color": "#FFF8E7", + "photo": "//www.gravatar.com/avatar/8c83c46614d8d46c0cb3096c9deb6e1f?size=80", + "is_active": true, + "role_name": "Design", + "user": 13, + "role": 2, + "is_owner": true + } + ], + "id": 1, + "default_points": 1, + "default_us_status": 1, + "default_task_status": 1, + "default_priority": 2, + "default_severity": 3, + "default_swimlane": null, + "default_issue_status": 429, + "default_issue_type": 1, + "name": "Project Example 0", + "slug": "user6532909695705815086-project-example-0", + "description": "Project example 0 description", + "created_date": "2015-02-17T18:14:14+0000", + "modified_date": "2015-09-10T10:56:22+0000", + "owner": 5, + "total_milestones": 5, + "total_story_points": 1572.0, + "is_backlog_activated": true, + "is_kanban_activated": true, + "is_wiki_activated": true, + "is_issues_activated": true, + "videoconferences": null, + "videoconferences_extra_data": null, + "creation_template": 1, + "is_private": true, + "userstories_csv_uuid": null, + "tasks_csv_uuid": null, + "issues_csv_uuid": null +} diff --git a/tests/test_projects.py b/tests/test_projects.py index 2777ec1..edd3342 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -48,6 +48,19 @@ def test_get_project_by_slug(self, mock_requestmaker_get): "/{endpoint}/by_slug?slug={slug}", endpoint="projects", slug="my_slug" ) + @patch("taiga.requestmaker.RequestMaker.get") + def test_get_project_by_slug_no_swimlanes(self, mock_requestmaker_get): + mock_requestmaker_get.return_value = MockResponse( + 200, create_mock_json("tests/resources/project_details_success_no_swimlanes.json") + ) + api = TaigaAPI(token="f4k3") + project = api.projects.get_by_slug("my_slug") + self.assertTrue(isinstance(project, Project)) + self.assertEqual(project.name, "Project Example 0") + mock_requestmaker_get.assert_called_with( + "/{endpoint}/by_slug?slug={slug}", 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(