Repository: mgmonteleone/python-atlasapi (language: python)

Issue:
Re-Implement Projects Endpoints
- [x]  test_00_get_projects_all_for_org_key
- [x] test_01_get_projects_all_for_proj_key
- [x] test_02_get_project_by_id
- [x] test_03_get_project_by_name
- [x] test_05_get_project_teams_basic
- [x] test_06_get_project_teams_pass_id
- [x] test_08_get_project_users
- [x] test_09_get_project_user_count
- [x] test_10_get_project_settings
- [x] Check test coverage and create issues for any missing tests.
Re-Implement Projects Endpoints
- [x]  test_00_get_projects_all_for_org_key
- [x] test_01_get_projects_all_for_proj_key
- [x] test_02_get_project_by_id
- [x] test_03_get_project_by_name
- [x] test_05_get_project_teams_basic
- [x] test_06_get_project_teams_pass_id
- [x] test_08_get_project_users
- [x] test_09_get_project_user_count
- [x] test_10_get_project_settings
- [x] Check test coverage and create issues for any missing tests.


Discussion / hints:

Fix patch:
diff --git a/atlasapi/atlas.py b/atlasapi/atlas.py
index 18b90e5..ff89b5d 100644
--- a/atlasapi/atlas.py
+++ b/atlasapi/atlas.py
@@ -1699,6 +1699,8 @@ class _Projects:
 
         The groups resource provides access to retrieve or create Atlas projects.
 
+        groups is a synonym for projects throughout Atlas.
+
         Args:
             atlas (Atlas): Atlas instance
         """
@@ -1722,10 +1724,10 @@ def projects(self) -> Iterable[Project]:
                 response = self.atlas.network.get(uri=Settings.BASE_URL + uri)
             except Exception as e:
                 raise e
-            result_list = response["results"]
 
-            for each in result_list:
-                yield Project.from_dict(each)
+            for each_page in response:
+                for each_project in each_page.get('results'):
+                    yield Project.from_dict(each_project)
 
         def _get_project(self, group_id: str = None, group_name: str = None) -> Project:
             """Returns a single Project
@@ -1755,8 +1757,10 @@ def _get_project(self, group_id: str = None, group_name: str = None) -> Project:
                 response = self.atlas.network.get(uri=Settings.BASE_URL + uri)
             except Exception as e:
                 raise e
-
-            return Project.from_dict(response)
+            return_list = list()
+            for each_page in response:
+                return_list.append(Project.from_dict(each_page))
+            return return_list[0]
 
         def project_by_name(self, project_name: str) -> Project:
             """Return project by name
@@ -1820,10 +1824,10 @@ def get_project_teams(self, group_id: str = None) -> Iterable[TeamRoles]:
                 response = self.atlas.network.get(uri=Settings.BASE_URL + uri)
             except Exception as e:
                 raise e
-            result_list = response["results"]
 
-            for each in result_list:
-                yield TeamRoles(each.get("teamId"), each.get("roleNames"))
+            for each_page in response:
+                for each in each_page.get('results'):
+                    yield TeamRoles(each.get("teamId"), each.get("roleNames"))
 
         @staticmethod
         def _process_user_options(uri: str, flatten_teams: bool, include_org_users: bool) -> str:
@@ -1849,9 +1853,13 @@ def get_project_users(self, group_id: str = None, flatten_teams: Optional[bool]
             """Yields all users (AtlasUser objects) associated with the group_id.
 
             Args:
-                group_id (str): The group id to search, will use the configured group for the Atlas instance if instantiated in this way.
-                flatten_teams (bool): Flag that indicates whether the returned list should include users who belong to a team that is assigned a role in this project. You might not have assigned the individual users a role in this project.
-                include_org_users (bool): Flag that indicates whether the returned list should include users with implicit access to the project through the Organization Owner or Organization Read Only role. You might not have assigned the individual users a role in this project.
+                group_id (str): The group id to search, will use the configured group for the Atlas instance if
+                 instantiated in this way. flatten_teams (bool): Flag that indicates whether the returned list should
+                 include users who belong to a team that is assigned a role in this project. You might not have
+                 assigned the individual users a role in this project.
+                include_org_users (bool): Flag that indicates whether the returned list should include users with
+                 implicit access to the project through the Organization Owner or Organization Read Only role.
+                 You might not have assigned the individual users a role in this project.
 
 
             Returns (Iterable[AtlasUser]: An iterable of AtlasUser objects.
@@ -1864,11 +1872,9 @@ def get_project_users(self, group_id: str = None, flatten_teams: Optional[bool]
                 response = self.atlas.network.get(uri=Settings.BASE_URL + uri)
             except Exception as e:
                 raise e
-            user_count: int = response["totalCount"]
-            logger.error(f"The user count is {user_count}")
-            result_list: List[dict] = response["results"]
-            for each in result_list:
-                yield AtlasUser.from_dict(each)
+            for each_page in response:
+                for each in each_page.get('results'):
+                    yield AtlasUser.from_dict(each)
 
         def user_count(self, group_id: str = None, flatten_teams: Optional[bool] = None,
                        include_org_users: Optional[bool] = None,
@@ -1897,7 +1903,10 @@ def user_count(self, group_id: str = None, flatten_teams: Optional[bool] = None,
                 response = self.atlas.network.get(uri=Settings.BASE_URL + uri)
             except Exception as e:
                 raise e
-            user_count: int = response["totalCount"]
+            user_count = 0
+            for each_page in response:
+                for _ in each_page.get('results'):
+                    user_count += 1
             logger.info(f"The user count is {user_count}")
             return user_count
 
@@ -1910,7 +1919,11 @@ def settings(self) -> ProjectSettings:
                 response = self.atlas.network.get(uri=Settings.BASE_URL + uri)
             except Exception as e:
                 raise e
-            return ProjectSettings.from_dict(response)
+
+            return_list = list()
+            for each_page in response:
+                return_list.append(ProjectSettings.from_dict(each_page))
+            return return_list[0]
 
     class _Organizations:
         """Atlas Organizations


Test patch:
diff --git a/tests/test_projects.py b/tests/test_projects.py
index d98f2ca..ae657ad 100644
--- a/tests/test_projects.py
+++ b/tests/test_projects.py
@@ -25,7 +25,8 @@ def test_00_get_projects_all_for_org_key(self):
             # pprint(each.__dict__)
             self.assertIsInstance(each, Project, "An Atlas <Project should be returned>")
             count += 1
-        self.assertEqual(count, 3, "There should be exactly 3 projects returned when for this test Organization")
+        self.assertEqual(count, 4, "There should be exactly 4 projects returned when for this test Organization")
+        print(f"✅ Found the expected 4 projects.")
 
     test_00_get_projects_all_for_org_key.basic = True
 
@@ -36,7 +37,7 @@ def test_01_get_projects_all_for_proj_key(self):
             self.assertIsInstance(each, Project, "An Atlas <Project should be returned>")
             count += 1
         self.assertEqual(count, 1, "There should be exactly 1 projects returned when for this test Project")
-
+        print(f"✅ Found the expected 1 project.")
     test_01_get_projects_all_for_proj_key.basic = True
 
     def test_02_get_project_by_id(self):
@@ -47,9 +48,8 @@ def test_02_get_project_by_id(self):
             self.assertIsInstance(each.org_id, str, "OrgID should be an str")
 
         out = self.a.Projects.project_by_id(group_id)
-        # pprint(out.__dict__)
         self.assertIsInstance(out, Project, "An Atlas <Project> should be returned")
-
+        print(f"✅ Found the expected 1 Project by id.")
     test_02_get_project_by_id.basic = True
 
     def test_03_get_project_by_name(self):
@@ -62,7 +62,7 @@ def test_03_get_project_by_name(self):
         out = self.a.Projects.project_by_name(group_name)
         # pprint(out.__dict__)
         self.assertIsInstance(out, Project, "An Atlas <Project> should be returned")
-
+        print(f"✅ Found the expected 1 project by name.")
     test_03_get_project_by_name.basic = True
 
     def test_04_get_project_by_both_fail(self):
@@ -77,10 +77,10 @@ def test_05_get_project_teams_basic(self):
         out = self.a.Projects.get_project_teams()
         for each in out:
             self.assertIsInstance(each, TeamRoles)
-            self.assertIsInstance(each.roles,list,"Roles should be a list of strings")
+            self.assertIsInstance(each.roles,list,"❌Roles should be a list of strings")
             for each_role in each.roles:
-                self.assertIsInstance(each_role,str, "Each listed role should be a string.")
-            #pprint(each.__dict__)
+                self.assertIsInstance(each_role,str, "❌Each listed role should be a string.")
+        pprint(f"👍Successfully validated project getting project teams")
 
     test_05_get_project_teams_basic.basic = True
 
@@ -88,9 +88,9 @@ def test_06_get_project_teams_pass_id(self):
         out = self.a_owner.Projects.get_project_teams(group_id=self.a.group)
         for each in out:
             self.assertIsInstance(each, TeamRoles)
-            self.assertIsInstance(each.roles,list,"Roles should be a list of strings")
+            self.assertIsInstance(each.roles,list,"❌Roles should be a list of strings")
             for each_role in each.roles:
-                self.assertIsInstance(each_role,str, "Each listed role should be a string.")
+                self.assertIsInstance(each_role,str, "❌Each listed role should be a string.")
             #pprint(each.__dict__)
 
     test_06_get_project_teams_pass_id.basic = True
@@ -116,15 +116,15 @@ def test_08_get_project_users(self):
 
     def test_09_get_project_user_count(self):
         out = self.a.Projects.user_count()
+        self.assertIsInstance(out, int, "❌The count should be a in integer!")
+        self.assertGreaterEqual(out, 1, "❌Should have more than one user!")
         pprint(f"👍 The count is {out}")
-        self.assertIsInstance(out, int, "The count should be a in integer!")
-        self.assertGreaterEqual(out, 1, "Should have more than one user!")
 
     test_09_get_project_user_count.basic = True
 
     def test_10_get_project_settings(self):
         out = self.a.Projects.settings
         #pprint(f"👍 The settings are {out.__dict__}")
-        self.assertIsInstance(out, ProjectSettings, "The response must be a ProjectSettings obj")
+        self.assertIsInstance(out, ProjectSettings, "❌The response must be a ProjectSettings obj")
 
     test_10_get_project_settings.basic = True