Repository: cubewise-code/tm1py (language: python)

Issue:
Chore search methods
Added two functions for searching for chores based on process name or defined parameter value(not parameter name and not the parameter default set in the TI process) in the chore configuration. I took a stab at some test cases as well.


Discussion / hints:
Nice one @adscheevel 

Thanks!

Fix patch:
diff --git a/TM1py/Services/ChoreService.py b/TM1py/Services/ChoreService.py
index 3cea622d..17a1e36e 100644
--- a/TM1py/Services/ChoreService.py
+++ b/TM1py/Services/ChoreService.py
@@ -129,13 +129,13 @@ def exists(self, chore_name: str, **kwargs) -> bool:
         url = format_url("/api/v1/Chores('{}')", chore_name)
         return self._exists(url, **kwargs)
 
-     def search_for_process_name(self, process_name: str, **kwargs) -> List[Chore]:
+    def search_for_process_name(self, process_name: str, **kwargs) -> List[Chore]:
         """ Return chore details for any/all chores that contain specified process name in tasks
 
         :param process_name: string, a valid ti process name; spaces will be elimniated
         """
         url = format_url(
-            "/api/v1/Chores?$filter=Tasks/any(t: replace(tolower(t/Process/Name), ' ', '') eq '{}')" \
+            "/api/v1/Chores?$filter=Tasks/any(t: replace(tolower(t/Process/Name), ' ', '') eq '{}')"
             "&$expand=Tasks($expand=*,Chore($select=Name),Process($select=Name))",
             process_name.lower().replace(' ', '')
         )
@@ -149,7 +149,8 @@ def search_for_parameter_value(self, parameter_value: str, **kwargs) -> List[Cho
         :param parameter_value: string, will search wildcard for string in parameter value using Contains(string)
         """
         url = format_url(
-            "/api/v1/Chores?$filter=Tasks/any(t: t/Parameters/any(p: contains(tolower(p/Value), '{}')))" \
+            "/api/v1/Chores?"
+            "$filter=Tasks/any(t: t/Parameters/any(p: isof(p/Value, Edm.String) and contains(tolower(p/Value), '{}')))"
             "&$expand=Tasks($expand=*,Process($select=Name),Chore($select=Name))",
             parameter_value.lower()
         )
diff --git a/Tests/__init__.py b/Tests/__init__.py
index 134aecde..e69de29b 100644
--- a/Tests/__init__.py
+++ b/Tests/__init__.py
@@ -1,6 +0,0 @@
-""" Notes on TM1py Tests
-- specify your instance coordinates in the config.ini file as `tm1srv01`
-- `EnableSandboxDimension` config parameter must be set to `F` for the target TM1 instance
-- use PyCharm to run the pytests in this folder or run `pytest` in the cmd
-
-"""
diff --git a/Tests/_readme.md b/Tests/_readme.md
new file mode 100644
index 00000000..589cacce
--- /dev/null
+++ b/Tests/_readme.md
@@ -0,0 +1,18 @@
+# Setup TM1py Tests
+
+- `pip install pytest`
+
+- Use a TM1 development environment
+
+- Specify your instance coordinates in the config.ini file as `tm1srv01`
+
+- `EnableSandboxDimension` config parameter must be set to `F` for the target TM1 instance
+
+# Run TM1py Tests
+
+## To run all tests with PyCharm:
+
+rightclick `Tests` folder -> run 'pytest in Tests'
+
+## To run tests in a given file in the `Tests` folder:
+rightclick file (e.g., `ChoreService_test.py`) -> run 'pytest in ChoreService_test.py'


Test patch:
diff --git a/Tests/ChoreService_test.py b/Tests/ChoreService_test.py
index 0ace7f93..2095d379 100644
--- a/Tests/ChoreService_test.py
+++ b/Tests/ChoreService_test.py
@@ -201,7 +201,7 @@ def test_get_all_names(self):
         self.assertIn(self.chore_name3, all_chore_names)
 
     def test_search_for_process_name_happy_case(self):
-        chore_names = self.tm1.chores.search_for_process_name(process_name=process_name1)
+        chore_names = self.tm1.chores.search_for_process_name(process_name=self.process_name1)
         self.assertEqual(2, len(chore_names))
         self.assertEqual(self.chore_name1, chore_names[0].name)
         self.assertEqual(self.chore_name2, chore_names[1].name)
@@ -416,9 +416,10 @@ def test_exists(self):
         self.assertTrue(self.tm1.chores.exists(self.chore_name2))
         self.assertTrue(self.tm1.chores.exists(self.chore_name3))
         self.assertFalse(self.tm1.chores.exists(uuid.uuid4()))
-        def test_search_for_process_name_no_match(self):
-    chore_names = self.tm1.chores.search_for_process_name(process_name="NotAProcessName")
-    self.assertEqual([], chore_names)
+
+    def test_search_for_process_name_no_match(self):
+        chore_names = self.tm1.chores.search_for_process_name(process_name="NotAProcessName")
+        self.assertEqual([], chore_names)
 
     @classmethod
     def teardown_class(cls):