Repository: rogers-obrien-rad/ProPyCore (language: python)

Issue:
As a PROCORE USER, I want ACCESS TO CORRESONDENCE TOOL DATA, so that I can ANALYZE DATA
### Description
The correspondence tool is a new tool created by Procore that can be accessed via the [generic tool](https://developers.procore.com/reference/rest/v1/correspondences?version=1.0#create-generic-tool-item) endpoint

### Acceptance Criteria
- [x] new tool script within `access/`
- [x] import of new script into `procore.py` body
- [x] snippets to test functionality
- [ ] tests to ensure the tool is working



Discussion / hints:

Fix patch:
diff --git a/snippets/get_budget_details.py b/snippets/get_budget_details.py
index 047b111..378bb66 100644
--- a/snippets/get_budget_details.py
+++ b/snippets/get_budget_details.py
@@ -28,7 +28,7 @@
     budget_view = connection.__budgets__.find_view(
         company_id=company["id"],
         project_id=project["id"],
-        identifier=414205
+        identifier="Detailed Budget View"
     )
 
     # Example 1: List all columns
@@ -64,6 +64,9 @@
     )
 
     print(f"Number of Budget Rows: {len(budget_rows)}")
+    # Uncomment to save budget rows
+    #with open("rows.json", "w") as f:
+    #    json.dump(budget_rows, f, indent=4)
 
     # Example 4: Find row by name
     # ---------
@@ -89,5 +92,4 @@
     )
 
     print(f"Number of budget line items: {len(details)}")
-    '''
-    
\ No newline at end of file
+    '''
\ No newline at end of file


Test patch:
diff --git a/tests/integration/test_find_generic_tools.py b/tests/integration/test_find_generic_tools.py
new file mode 100644
index 0000000..fe17e50
--- /dev/null
+++ b/tests/integration/test_find_generic_tools.py
@@ -0,0 +1,43 @@
+import os
+import pytest
+from propycore.procore import Procore
+from dotenv import load_dotenv
+
+# Load environment variables
+load_dotenv()
+
+# Fixture for Procore connection
+@pytest.fixture
+def procore_connection():
+    return Procore(
+        client_id=os.getenv("CLIENT_ID"),
+        client_secret=os.getenv("CLIENT_SECRET"),
+        redirect_uri=os.getenv("REDIRECT_URI"),
+        oauth_url=os.getenv("OAUTH_URL"),
+        base_url=os.getenv("BASE_URL")
+    )
+
+def test_procore_integration(procore_connection):
+    # Get IDs for company, project, and tool
+    company = procore_connection.__companies__.find(identifier="Rogers-O`Brien Construction")
+    project = procore_connection.__projects__.find(
+        company_id=company["id"],
+        identifier="Sandbox Test Project"
+    )
+    tool = procore_connection.__tools__.find_tool(
+        company_id=company["id"],
+        identifier="Idea Submission"
+    )
+
+    assert company is not None
+    assert project is not None
+    assert tool is not None
+
+    # Example 1: list all items for idea submission tool
+    tool_items = procore_connection.__tools__.get_tool_items(
+        company_id=company["id"],
+        project_id=project["id"],
+        tool_id=tool["id"]
+    )
+
+    assert isinstance(tool_items, list)  # or any other assertion based on expected response
\ No newline at end of file
diff --git a/tests/unit/test_generic_tools.py b/tests/unit/test_generic_tools.py
new file mode 100644
index 0000000..afc6171
--- /dev/null
+++ b/tests/unit/test_generic_tools.py
@@ -0,0 +1,40 @@
+import pytest
+from unittest.mock import MagicMock
+from propycore.access.generic_tools import GenericTool
+from propycore.exceptions import NotFoundItemError
+
+# Fixture for GenericTool instance
+@pytest.fixture
+def generic_tool_instance():
+    return GenericTool('mock_access_token', 'mock_server_url')
+
+# Test for get_tools method
+def test_get_tools(generic_tool_instance):
+    # Mock the get_request method
+    mock_response = [{'id': 1, 'title': 'Tool 1'}, {'id': 2, 'title': 'Tool 2'}]
+    generic_tool_instance.get_request = MagicMock(return_value=mock_response)
+
+    response = generic_tool_instance.get_tools(123)
+
+    assert isinstance(response, list)
+    assert response == mock_response
+
+# Test for find_tool by id
+def test_find_tool_by_id(generic_tool_instance):
+    # Mock the get_tools method
+    mock_response = [{'id': 1, 'title': 'Tool 1'}, {'id': 2, 'title': 'Tool 2'}]
+    generic_tool_instance.get_tools = MagicMock(return_value=mock_response)
+
+    tool = generic_tool_instance.find_tool(123, 1)
+
+    assert tool == {'id': 1, 'title': 'Tool 1'}
+
+# Test for find_tool by title
+def test_find_tool_by_title(generic_tool_instance):
+    # Mock the get_tools method
+    mock_response = [{'id': 1, 'title': 'Tool 1'}, {'id': 2, 'title': 'Tool 2'}]
+    generic_tool_instance.get_tools = MagicMock(return_value=mock_response)
+
+    tool = generic_tool_instance.find_tool(123, 'Tool 2')
+
+    assert tool == {'id': 2, 'title': 'Tool 2'}
\ No newline at end of file