feat: update Composio components (#8868)
Co-authored-by: Uday-sidagana <uday.sidgana@gmail.com> Co-authored-by: Uday Sidagana <udaysidagana@Mac.lan> Co-authored-by: Edwin Jose <edwin.jose@datastax.com> Co-authored-by: Uday Sidagana <129588963+Uday-sidagana@users.noreply.github.com>
This commit is contained in:
parent
590682d748
commit
f6e6edbc37
54 changed files with 1749 additions and 4627 deletions
|
|
@ -1,132 +0,0 @@
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from langflow.base.composio.composio_base import ComposioBaseComponent
|
||||
|
||||
from tests.base import DID_NOT_EXIST, ComponentTestBaseWithoutClient
|
||||
|
||||
|
||||
class MockComposioToolSet:
|
||||
def __init__(self, api_key=None):
|
||||
self.api_key = api_key
|
||||
self.client = MagicMock()
|
||||
|
||||
def get_tools(self, *_):
|
||||
return []
|
||||
|
||||
def execute_action(self, *_, **__):
|
||||
return {"successful": True, "data": {"result": "mocked response"}}
|
||||
|
||||
|
||||
class TestComposioBase(ComponentTestBaseWithoutClient):
|
||||
@pytest.fixture
|
||||
def component_class(self):
|
||||
class TestComponent(ComposioBaseComponent):
|
||||
def execute_action(self):
|
||||
return []
|
||||
|
||||
return TestComponent
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_composio_toolset(self):
|
||||
with patch("langflow.base.composio.composio_base.ComposioToolSet", MockComposioToolSet):
|
||||
yield
|
||||
|
||||
@pytest.fixture
|
||||
def default_kwargs(self):
|
||||
return {
|
||||
"api_key": "",
|
||||
"entity_id": "default",
|
||||
"action": None,
|
||||
}
|
||||
|
||||
@pytest.fixture
|
||||
def file_names_mapping(self):
|
||||
# Component not yet released, mark all versions as non-existent
|
||||
return [
|
||||
{"version": "1.0.17", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.18", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.19", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.0", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.1", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
]
|
||||
|
||||
def test_build_wrapper_no_api_key(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
with pytest.raises(ValueError, match="Please provide a valid Composio API Key in the component settings"):
|
||||
component._build_wrapper()
|
||||
|
||||
def test_build_wrapper_with_api_key(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
wrapper = component._build_wrapper()
|
||||
assert isinstance(wrapper, MockComposioToolSet)
|
||||
assert wrapper.api_key == "test_key"
|
||||
|
||||
def test_build_action_maps(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
# Test with empty actions data
|
||||
component._actions_data = {}
|
||||
component._build_action_maps()
|
||||
assert component._display_to_key_map == {}
|
||||
assert component._key_to_display_map == {}
|
||||
assert component._sanitized_names == {}
|
||||
|
||||
# Test with sample actions data
|
||||
component._actions_data = {
|
||||
"ACTION_1": {"display_name": "Action One"},
|
||||
"ACTION_2": {"display_name": "Action Two"},
|
||||
}
|
||||
component._build_action_maps()
|
||||
assert component._display_to_key_map == {
|
||||
"Action One": "ACTION_1",
|
||||
"Action Two": "ACTION_2",
|
||||
}
|
||||
assert component._key_to_display_map == {
|
||||
"ACTION_1": "Action One",
|
||||
"ACTION_2": "Action Two",
|
||||
}
|
||||
|
||||
def test_get_action_fields(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component._actions_data = {
|
||||
"ACTION_1": {"action_fields": ["field1", "field2"]},
|
||||
"ACTION_2": {"action_fields": ["field3"]},
|
||||
}
|
||||
|
||||
# Test with valid action key
|
||||
fields = component._get_action_fields("ACTION_1")
|
||||
assert fields == {"field1", "field2"}
|
||||
|
||||
# Test with non-existent action key
|
||||
fields = component._get_action_fields("NON_EXISTENT")
|
||||
assert fields == set()
|
||||
|
||||
# Test with None action key
|
||||
fields = component._get_action_fields(None)
|
||||
assert fields == set()
|
||||
|
||||
def test_show_hide_fields(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component._all_fields = {"field1", "field2"}
|
||||
component._bool_variables = {"field2"}
|
||||
component._actions_data = {
|
||||
"ACTION_1": {"display_name": "Action One", "action_fields": ["field1"]},
|
||||
}
|
||||
|
||||
build_config = {
|
||||
"field1": {"show": False, "value": "old_value"},
|
||||
"field2": {"show": False, "value": True},
|
||||
}
|
||||
|
||||
# Test with no field value
|
||||
component.show_hide_fields(build_config, None)
|
||||
assert not build_config["field1"]["show"]
|
||||
assert not build_config["field2"]["show"]
|
||||
assert build_config["field1"]["value"] == ""
|
||||
assert build_config["field2"]["value"] is False
|
||||
|
||||
# Test with valid action
|
||||
component.show_hide_fields(build_config, [{"name": "Action One"}])
|
||||
assert build_config["field1"]["show"] # Should be shown since it's in ACTION_1's fields
|
||||
assert not build_config["field2"]["show"] # Should remain hidden
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from composio import Action
|
||||
from langflow.components.composio.github_composio import ComposioGitHubAPIComponent
|
||||
from langflow.schema.dataframe import DataFrame
|
||||
|
||||
from tests.base import DID_NOT_EXIST, ComponentTestBaseWithoutClient
|
||||
|
||||
from .test_base import MockComposioToolSet
|
||||
|
||||
|
||||
class MockAction:
|
||||
GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER = "GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER"
|
||||
GITHUB_LIST_BRANCHES = "GITHUB_LIST_BRANCHES"
|
||||
GITHUB_LIST_REPOSITORY_ISSUES = "GITHUB_LIST_REPOSITORY_ISSUES"
|
||||
|
||||
|
||||
class TestGitHubComponent(ComponentTestBaseWithoutClient):
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_composio_toolset(self):
|
||||
with patch("langflow.base.composio.composio_base.ComposioToolSet", MockComposioToolSet):
|
||||
yield
|
||||
|
||||
@pytest.fixture
|
||||
def component_class(self):
|
||||
return ComposioGitHubAPIComponent
|
||||
|
||||
@pytest.fixture
|
||||
def default_kwargs(self):
|
||||
return {
|
||||
"api_key": "",
|
||||
"entity_id": "default",
|
||||
"action": None,
|
||||
}
|
||||
|
||||
@pytest.fixture
|
||||
def file_names_mapping(self):
|
||||
# Component not yet released, mark all versions as non-existent
|
||||
return [
|
||||
{"version": "1.0.17", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.18", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.19", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.0", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.1", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
]
|
||||
|
||||
def test_init(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
assert component.display_name == "GitHub"
|
||||
assert component.app_name == "github"
|
||||
assert "GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER" in component._actions_data
|
||||
assert "GITHUB_LIST_BRANCHES" in component._actions_data
|
||||
|
||||
def test_execute_action_star_a_repo(self, component_class, default_kwargs, monkeypatch):
|
||||
# Mock Action enum
|
||||
monkeypatch.setattr(
|
||||
Action,
|
||||
"GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER",
|
||||
MockAction.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER,
|
||||
)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Star A Repository"}]
|
||||
component.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER_owner = "langflow-ai"
|
||||
component.GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER_repo = "langflow"
|
||||
|
||||
# For this specific test, customize the _actions_data to not use get_result_field
|
||||
component._actions_data = {
|
||||
"GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER": {
|
||||
"display_name": "Star A Repository",
|
||||
"action_fields": [
|
||||
"GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER_owner",
|
||||
"GITHUB_STAR_A_REPOSITORY_FOR_THE_AUTHENTICATED_USER_repo",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
# Execute action
|
||||
result = component.execute_action()
|
||||
assert result == {"result": "mocked response"}
|
||||
|
||||
def test_execute_action_list_branches(self, component_class, default_kwargs, monkeypatch):
|
||||
# Mock Action enum
|
||||
monkeypatch.setattr(Action, "GITHUB_LIST_BRANCHES", MockAction.GITHUB_LIST_BRANCHES)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "List Branches"}]
|
||||
component.GITHUB_LIST_BRANCHES_owner = "langflow-ai"
|
||||
component.GITHUB_LIST_BRANCHES_repo = "langflow"
|
||||
|
||||
# For this specific test, customize the _actions_data to not use get_result_field
|
||||
component._actions_data = {
|
||||
"GITHUB_LIST_BRANCHES": {
|
||||
"display_name": "List Branches",
|
||||
"action_fields": [
|
||||
"GITHUB_LIST_BRANCHES_owner",
|
||||
"GITHUB_LIST_BRANCHES_repo",
|
||||
"GITHUB_LIST_BRANCHES_protected",
|
||||
"GITHUB_LIST_BRANCHES_per_page",
|
||||
"GITHUB_LIST_BRANCHES_page",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
# Execute action
|
||||
result = component.execute_action()
|
||||
assert result == {"result": "mocked response"}
|
||||
|
||||
def test_execute_action_list_repo_issues(self, component_class, default_kwargs, monkeypatch):
|
||||
# Mock Action enum
|
||||
monkeypatch.setattr(Action, "GITHUB_LIST_REPOSITORY_ISSUES", MockAction.GITHUB_LIST_REPOSITORY_ISSUES)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "List Repository Issues"}]
|
||||
component.GITHUB_LIST_REPOSITORY_ISSUES_owner = "langflow-ai"
|
||||
component.GITHUB_LIST_REPOSITORY_ISSUES_repo = "langflow"
|
||||
|
||||
# For this specific test, customize the _actions_data to not use get_result_field
|
||||
component._actions_data = {
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES": {
|
||||
"display_name": "List Repository Issues",
|
||||
"action_fields": [
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_owner",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_repo",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_milestone",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_state",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_assignee",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_creator",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_mentioned",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_labels",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_sort",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_direction",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_since",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_per_page",
|
||||
"GITHUB_LIST_REPOSITORY_ISSUES_page",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
# Execute action
|
||||
result = component.execute_action()
|
||||
assert result == {"result": "mocked response"}
|
||||
|
||||
def test_execute_action_invalid_action(self, component_class, default_kwargs):
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Invalid Action"}]
|
||||
|
||||
# Execute action should raise ValueError
|
||||
with pytest.raises(ValueError, match="Invalid action: Invalid Action"):
|
||||
component.execute_action()
|
||||
|
||||
def test_as_dataframe(self, component_class, default_kwargs, monkeypatch):
|
||||
# Mock Action enum
|
||||
monkeypatch.setattr(Action, "GITHUB_LIST_REPOSITORY_ISSUES", MockAction.GITHUB_LIST_REPOSITORY_ISSUES)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "List Repository Issues"}]
|
||||
component.max_results = 10
|
||||
|
||||
# Create mock email data that would be returned by execute_action
|
||||
mock_issues = [
|
||||
{
|
||||
"url": "url1",
|
||||
"repository_url": "repository_url1",
|
||||
"id": "id1",
|
||||
"title": "test issue",
|
||||
"state": "open",
|
||||
},
|
||||
{
|
||||
"url": "url2",
|
||||
"repository_url": "repository_url2",
|
||||
"id": "id2",
|
||||
"title": "test issue",
|
||||
"state": "open",
|
||||
},
|
||||
]
|
||||
|
||||
# Mock the execute_action method to return our mock data
|
||||
with patch.object(component, "execute_action", return_value=mock_issues):
|
||||
# Test as_dataframe method
|
||||
result = component.as_dataframe()
|
||||
|
||||
# Verify the result is a DataFrame
|
||||
assert isinstance(result, DataFrame)
|
||||
|
||||
# Verify the DataFrame is not empty
|
||||
assert not result.empty
|
||||
|
||||
# Check for expected content in the DataFrame string representation
|
||||
data_str = str(result)
|
||||
assert "test issue" in data_str
|
||||
|
||||
def test_update_build_config(self, component_class, default_kwargs):
|
||||
# Test that the GitHub component properly inherits and uses the base component's
|
||||
# update_build_config method
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"auth_link": {"value": "", "auth_tooltip": ""},
|
||||
"action": {
|
||||
"options": [],
|
||||
"helper_text": "",
|
||||
"helper_text_metadata": {},
|
||||
},
|
||||
}
|
||||
|
||||
# Test with empty API key
|
||||
result = component.update_build_config(build_config, "", "api_key")
|
||||
assert result["auth_link"]["value"] == ""
|
||||
assert "Please provide a valid Composio API Key" in result["auth_link"]["auth_tooltip"]
|
||||
assert result["action"]["options"] == []
|
||||
|
||||
# Test with valid API key
|
||||
component.api_key = "test_key"
|
||||
result = component.update_build_config(build_config, "test_key", "api_key")
|
||||
assert len(result["action"]["options"]) > 0 # Should have GitHub actions
|
||||
|
|
@ -1,218 +0,0 @@
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from composio import Action
|
||||
from langflow.components.composio.gmail_composio import ComposioGmailAPIComponent
|
||||
from langflow.schema.dataframe import DataFrame
|
||||
|
||||
from tests.base import DID_NOT_EXIST, ComponentTestBaseWithoutClient
|
||||
|
||||
from .test_base import MockComposioToolSet
|
||||
|
||||
|
||||
class MockAction:
|
||||
GMAIL_SEND_EMAIL = "GMAIL_SEND_EMAIL"
|
||||
GMAIL_FETCH_EMAILS = "GMAIL_FETCH_EMAILS"
|
||||
GMAIL_GET_PROFILE = "GMAIL_GET_PROFILE"
|
||||
|
||||
|
||||
class TestGmailComponent(ComponentTestBaseWithoutClient):
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_composio_toolset(self):
|
||||
with patch("langflow.base.composio.composio_base.ComposioToolSet", MockComposioToolSet):
|
||||
yield
|
||||
|
||||
@pytest.fixture
|
||||
def component_class(self):
|
||||
return ComposioGmailAPIComponent
|
||||
|
||||
@pytest.fixture
|
||||
def default_kwargs(self):
|
||||
return {
|
||||
"api_key": "",
|
||||
"entity_id": "default",
|
||||
"action": None,
|
||||
"recipient_email": "",
|
||||
"subject": "",
|
||||
"body": "",
|
||||
"is_html": False,
|
||||
"max_results": 10,
|
||||
"query": "",
|
||||
}
|
||||
|
||||
@pytest.fixture
|
||||
def file_names_mapping(self):
|
||||
# Component not yet released, mark all versions as non-existent
|
||||
return [
|
||||
{"version": "1.0.17", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.18", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.19", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.0", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.1", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
]
|
||||
|
||||
def test_init(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
assert component.display_name == "Gmail"
|
||||
assert component.name == "GmailAPI"
|
||||
assert component.app_name == "gmail"
|
||||
assert "GMAIL_SEND_EMAIL" in component._actions_data
|
||||
assert "GMAIL_FETCH_EMAILS" in component._actions_data
|
||||
|
||||
def test_execute_action_send_email(self, component_class, default_kwargs, monkeypatch):
|
||||
# Mock Action enum
|
||||
monkeypatch.setattr(Action, "GMAIL_SEND_EMAIL", MockAction.GMAIL_SEND_EMAIL)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Send Email"}]
|
||||
component.recipient_email = "test@example.com"
|
||||
component.subject = "Test Subject"
|
||||
component.body = "Test Body"
|
||||
component.is_html = False
|
||||
|
||||
# For this specific test, customize the _actions_data to not use get_result_field
|
||||
component._actions_data = {
|
||||
"GMAIL_SEND_EMAIL": {
|
||||
"display_name": "Send Email",
|
||||
"action_fields": ["recipient_email", "subject", "body", "is_html"],
|
||||
"get_result_field": False,
|
||||
}
|
||||
}
|
||||
|
||||
# Execute action
|
||||
result = component.execute_action()
|
||||
assert result == {"result": "mocked response"}
|
||||
|
||||
def test_execute_action_fetch_emails(self, component_class, default_kwargs, monkeypatch):
|
||||
# Mock Action enum
|
||||
monkeypatch.setattr(Action, "GMAIL_FETCH_EMAILS", MockAction.GMAIL_FETCH_EMAILS)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Fetch Emails"}]
|
||||
component.max_results = 10
|
||||
component.query = "from:test@example.com"
|
||||
|
||||
# For this specific test, we need to customize the action_data to handle results field
|
||||
component._actions_data = {
|
||||
"GMAIL_FETCH_EMAILS": {
|
||||
"display_name": "Fetch Emails",
|
||||
"action_fields": ["max_results", "query"],
|
||||
"result_field": "messages",
|
||||
"get_result_field": True,
|
||||
}
|
||||
}
|
||||
|
||||
# Create a mock for the toolset with specific structure for this test
|
||||
mock_toolset = MagicMock()
|
||||
mock_toolset.execute_action.return_value = {"successful": True, "data": {"messages": "mocked response"}}
|
||||
|
||||
# Patch the _build_wrapper method
|
||||
with patch.object(component, "_build_wrapper", return_value=mock_toolset):
|
||||
result = component.execute_action()
|
||||
# Based on the component's actual behavior, it returns the result_field directly
|
||||
assert result == "mocked response"
|
||||
|
||||
def test_execute_action_get_profile(self, component_class, default_kwargs, monkeypatch):
|
||||
# Mock Action enum
|
||||
monkeypatch.setattr(Action, "GMAIL_GET_PROFILE", MockAction.GMAIL_GET_PROFILE)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Get User Profile"}]
|
||||
|
||||
# For this specific test, customize the _actions_data to not use get_result_field
|
||||
component._actions_data = {
|
||||
"GMAIL_GET_PROFILE": {
|
||||
"display_name": "Get User Profile",
|
||||
"action_fields": ["gmail_user_id"],
|
||||
"get_result_field": False,
|
||||
}
|
||||
}
|
||||
|
||||
# Execute action
|
||||
result = component.execute_action()
|
||||
assert result == {"result": "mocked response"}
|
||||
|
||||
def test_execute_action_invalid_action(self, component_class, default_kwargs):
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Invalid Action"}]
|
||||
|
||||
# Execute action should raise ValueError
|
||||
with pytest.raises(ValueError, match="Invalid action: Invalid Action"):
|
||||
component.execute_action()
|
||||
|
||||
def test_as_dataframe(self, component_class, default_kwargs, monkeypatch):
|
||||
# Mock Action enum
|
||||
monkeypatch.setattr(Action, "GMAIL_FETCH_EMAILS", MockAction.GMAIL_FETCH_EMAILS)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Fetch Emails"}]
|
||||
component.max_results = 10
|
||||
|
||||
# Create mock email data that would be returned by execute_action
|
||||
mock_emails = [
|
||||
{
|
||||
"id": "1",
|
||||
"threadId": "thread1",
|
||||
"subject": "Test Email 1",
|
||||
"from": "sender1@example.com",
|
||||
"date": "2023-01-01",
|
||||
"snippet": "This is a test email",
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"threadId": "thread2",
|
||||
"subject": "Test Email 2",
|
||||
"from": "sender2@example.com",
|
||||
"date": "2023-01-02",
|
||||
"snippet": "This is another test email",
|
||||
},
|
||||
]
|
||||
|
||||
# Mock the execute_action method to return our mock data
|
||||
with patch.object(component, "execute_action", return_value=mock_emails):
|
||||
# Test as_dataframe method
|
||||
result = component.as_dataframe()
|
||||
|
||||
# Verify the result is a DataFrame
|
||||
assert isinstance(result, DataFrame)
|
||||
|
||||
# Verify the DataFrame is not empty
|
||||
assert not result.empty
|
||||
|
||||
# Check for expected content in the DataFrame string representation
|
||||
data_str = str(result)
|
||||
assert "test email" in data_str
|
||||
|
||||
def test_update_build_config(self, component_class, default_kwargs):
|
||||
# Test that the Gmail component properly inherits and uses the base component's
|
||||
# update_build_config method
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"auth_link": {"value": "", "auth_tooltip": ""},
|
||||
"action": {
|
||||
"options": [],
|
||||
"helper_text": "",
|
||||
"helper_text_metadata": {},
|
||||
},
|
||||
}
|
||||
|
||||
# Test with empty API key
|
||||
result = component.update_build_config(build_config, "", "api_key")
|
||||
assert result["auth_link"]["value"] == ""
|
||||
assert "Please provide a valid Composio API Key" in result["auth_link"]["auth_tooltip"]
|
||||
assert result["action"]["options"] == []
|
||||
|
||||
# Test with valid API key
|
||||
component.api_key = "test_key"
|
||||
result = component.update_build_config(build_config, "test_key", "api_key")
|
||||
assert len(result["action"]["options"]) > 0 # Should have Gmail actions
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from composio import Action
|
||||
from langflow.components.composio.googlecalendar_composio import ComposioGoogleCalendarAPIComponent
|
||||
from langflow.schema.dataframe import DataFrame
|
||||
|
||||
from tests.base import DID_NOT_EXIST, ComponentTestBaseWithoutClient
|
||||
|
||||
from .test_base import MockComposioToolSet
|
||||
|
||||
|
||||
class MockAction:
|
||||
GOOGLECALENDAR_CREATE_EVENT = "GOOGLECALENDAR_CREATE_EVENT"
|
||||
GOOGLECALENDAR_LIST_CALENDARS = "GOOGLECALENDAR_LIST_CALENDARS"
|
||||
|
||||
|
||||
class TestGoogleCalendarComponent(ComponentTestBaseWithoutClient):
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_composio_toolset(self):
|
||||
with patch("langflow.base.composio.composio_base.ComposioToolSet", MockComposioToolSet):
|
||||
yield
|
||||
|
||||
@pytest.fixture
|
||||
def component_class(self):
|
||||
return ComposioGoogleCalendarAPIComponent
|
||||
|
||||
@pytest.fixture
|
||||
def default_kwargs(self):
|
||||
return {
|
||||
"api_key": "",
|
||||
"entity_id": "default",
|
||||
"action": None,
|
||||
}
|
||||
|
||||
@pytest.fixture
|
||||
def file_names_mapping(self):
|
||||
return [
|
||||
{"version": "1.0.17", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.18", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.19", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.0", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.1", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
]
|
||||
|
||||
def test_init(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
assert component.display_name == "Google Calendar"
|
||||
assert component.app_name == "googlecalendar"
|
||||
assert "GOOGLECALENDAR_CREATE_EVENT" in component._actions_data
|
||||
assert "GOOGLECALENDAR_LIST_CALENDARS" in component._actions_data
|
||||
|
||||
def test_execute_action_create_event(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(Action, "GOOGLECALENDAR_CREATE_EVENT", MockAction.GOOGLECALENDAR_CREATE_EVENT)
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Create Event"}]
|
||||
component.GOOGLECALENDAR_CREATE_EVENT_attendees = "test@example.com"
|
||||
component.GOOGLECALENDAR_CREATE_EVENT_start_datetime = "2025-01-16T15:00:00"
|
||||
component.GOOGLECALENDAR_CREATE_EVENT_summary = "test title"
|
||||
|
||||
component._actions_data = {
|
||||
"GOOGLECALENDAR_CREATE_EVENT": {
|
||||
"display_name": "Create Event",
|
||||
"action_fields": [
|
||||
"GOOGLECALENDAR_CREATE_EVENT_description",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_eventType",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_create_meeting_room",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_guestsCanSeeOtherGuests",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_guestsCanInviteOthers",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_location",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_summary",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_transparency",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_visibility",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_timezone",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_recurrence",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_guests_can_modify",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_attendees",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_send_updates",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_start_datetime",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_event_duration_hour",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_event_duration_minutes",
|
||||
"GOOGLECALENDAR_CREATE_EVENT_calendar_id",
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
result = component.execute_action()
|
||||
assert result == "mocked response"
|
||||
|
||||
def test_execute_action_list_calendars(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(Action, "GOOGLECALENDAR_LIST_CALENDARS", MockAction.GOOGLECALENDAR_LIST_CALENDARS)
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "List Google Calendars"}]
|
||||
component.GOOGLECALENDAR_LIST_CALENDARS_max_results = 1
|
||||
|
||||
component._actions_data = {
|
||||
"GOOGLECALENDAR_LIST_CALENDARS": {
|
||||
"display_name": "List Google Calendars",
|
||||
"action_fields": [
|
||||
"GOOGLECALENDAR_LIST_CALENDARS_max_results",
|
||||
"GOOGLECALENDAR_LIST_CALENDARS_min_access_role",
|
||||
"GOOGLECALENDAR_LIST_CALENDARS_page_token",
|
||||
"GOOGLECALENDAR_LIST_CALENDARS_show_deleted",
|
||||
"GOOGLECALENDAR_LIST_CALENDARS_show_hidden",
|
||||
"GOOGLECALENDAR_LIST_CALENDARS_sync_token",
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
mock_toolset = MagicMock()
|
||||
mock_toolset.execute_action.return_value = {"successful": True, "data": {"messages": "mocked response"}}
|
||||
|
||||
with patch.object(component, "_build_wrapper", return_value=mock_toolset):
|
||||
result = component.execute_action()
|
||||
assert result == "mocked response"
|
||||
|
||||
def test_execute_action_invalid_action(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Invalid Action"}]
|
||||
|
||||
with pytest.raises(ValueError, match="Invalid action: Invalid Action"):
|
||||
component.execute_action()
|
||||
|
||||
def test_as_dataframe(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(Action, "GOOGLECALENDAR_LIST_CALENDARS", MockAction.GOOGLECALENDAR_LIST_CALENDARS)
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "List Google Calendars"}]
|
||||
component.GOOGLECALENDAR_LIST_CALENDARS_max_results = 10
|
||||
|
||||
mock_emails = [
|
||||
{
|
||||
"kind": "test kind 1",
|
||||
"etag": "1",
|
||||
"id": "1",
|
||||
"summary": "test summary 1",
|
||||
"description": "test description 1",
|
||||
},
|
||||
{
|
||||
"kind": "test kind 2",
|
||||
"etag": "2",
|
||||
"id": "2",
|
||||
"summary": "test summary 2",
|
||||
"description": "test description 2",
|
||||
},
|
||||
]
|
||||
|
||||
with patch.object(component, "execute_action", return_value=mock_emails):
|
||||
result = component.as_dataframe()
|
||||
|
||||
assert isinstance(result, DataFrame)
|
||||
|
||||
assert not result.empty
|
||||
|
||||
data_str = str(result)
|
||||
assert "test summary 2" in data_str
|
||||
|
||||
def test_update_build_config(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"auth_link": {"value": "", "auth_tooltip": ""},
|
||||
"action": {
|
||||
"options": [],
|
||||
"helper_text": "",
|
||||
"helper_text_metadata": {},
|
||||
},
|
||||
}
|
||||
|
||||
result = component.update_build_config(build_config, "", "api_key")
|
||||
assert result["auth_link"]["value"] == ""
|
||||
assert "Please provide a valid Composio API Key" in result["auth_link"]["auth_tooltip"]
|
||||
assert result["action"]["options"] == []
|
||||
|
||||
component.api_key = "test_key"
|
||||
result = component.update_build_config(build_config, "test_key", "api_key")
|
||||
assert len(result["action"]["options"]) > 0
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from composio import Action
|
||||
from langflow.components.composio.outlook_composio import ComposioOutlookAPIComponent
|
||||
from langflow.schema.dataframe import DataFrame
|
||||
|
||||
from tests.base import DID_NOT_EXIST, ComponentTestBaseWithoutClient
|
||||
|
||||
from .test_base import MockComposioToolSet
|
||||
|
||||
|
||||
class MockAction:
|
||||
OUTLOOK_OUTLOOK_SEND_EMAIL = "OUTLOOK_OUTLOOK_SEND_EMAIL"
|
||||
OUTLOOK_OUTLOOK_LIST_MESSAGES = "OUTLOOK_OUTLOOK_LIST_MESSAGES"
|
||||
|
||||
|
||||
class TestOutlookComponent(ComponentTestBaseWithoutClient):
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_composio_toolset(self):
|
||||
with patch("langflow.base.composio.composio_base.ComposioToolSet", MockComposioToolSet):
|
||||
yield
|
||||
|
||||
@pytest.fixture
|
||||
def component_class(self):
|
||||
return ComposioOutlookAPIComponent
|
||||
|
||||
@pytest.fixture
|
||||
def default_kwargs(self):
|
||||
return {
|
||||
"api_key": "",
|
||||
"entity_id": "default",
|
||||
"action": None,
|
||||
}
|
||||
|
||||
@pytest.fixture
|
||||
def file_names_mapping(self):
|
||||
return [
|
||||
{"version": "1.0.17", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.18", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.19", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.0", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.1", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
]
|
||||
|
||||
def test_init(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
assert component.display_name == "Outlook"
|
||||
assert component.app_name == "outlook"
|
||||
assert "OUTLOOK_OUTLOOK_SEND_EMAIL" in component._actions_data
|
||||
assert "OUTLOOK_OUTLOOK_LIST_MESSAGES" in component._actions_data
|
||||
|
||||
def test_execute_action_send_email(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(Action, "OUTLOOK_OUTLOOK_SEND_EMAIL", MockAction.OUTLOOK_OUTLOOK_SEND_EMAIL)
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Send Email"}]
|
||||
component.OUTLOOK_OUTLOOK_SEND_EMAIL_subject = "Test Subject"
|
||||
component.OUTLOOK_OUTLOOK_SEND_EMAIL_body = "Test Body"
|
||||
component.OUTLOOK_OUTLOOK_SEND_EMAIL_to_email = "test@example.com"
|
||||
|
||||
component._actions_data = {
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL": {
|
||||
"display_name": "Send Email",
|
||||
"action_fields": [
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_user_id",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_subject",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_body",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_to_email",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_to_name",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_cc_emails",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_bcc_emails",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_is_html",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_save_to_sent_items",
|
||||
"OUTLOOK_OUTLOOK_SEND_EMAIL_attachment",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
result = component.execute_action()
|
||||
assert result == {"result": "mocked response"}
|
||||
|
||||
def test_execute_action_fetch_emails(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(Action, "OUTLOOK_OUTLOOK_LIST_MESSAGES", MockAction.OUTLOOK_OUTLOOK_LIST_MESSAGES)
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "List Messages"}]
|
||||
component.OUTLOOK_OUTLOOK_LIST_MESSAGES_folder = "Inbox"
|
||||
component.OUTLOOK_OUTLOOK_LIST_MESSAGES_top = 10
|
||||
|
||||
component._actions_data = {
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES": {
|
||||
"display_name": "List Messages",
|
||||
"action_fields": [
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_user_id",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_folder",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_top",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_skip",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_is_read",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_importance",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_subject",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_received_date_time_gt",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_subject_startswith",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_subject_endswith",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_subject_contains",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_received_date_time_ge",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_received_date_time_lt",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_received_date_time_le",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_from_address",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_has_attachments",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_body_preview_contains",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_sent_date_time_gt",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_sent_date_time_lt",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_categories",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_select",
|
||||
"OUTLOOK_OUTLOOK_LIST_MESSAGES_orderby",
|
||||
],
|
||||
"get_result_field": True,
|
||||
"result_field": "value",
|
||||
},
|
||||
}
|
||||
|
||||
mock_toolset = MagicMock()
|
||||
mock_toolset.execute_action.return_value = {
|
||||
"successful": True,
|
||||
"data": {"response_data": {"value": [{"subject": "Test Email", "from": "test@example.com"}]}},
|
||||
}
|
||||
|
||||
with patch.object(component, "_build_wrapper", return_value=mock_toolset):
|
||||
result = component.execute_action()
|
||||
assert result == [{"subject": "Test Email", "from": "test@example.com"}]
|
||||
|
||||
def test_execute_action_invalid_action(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Invalid Action"}]
|
||||
|
||||
with pytest.raises(ValueError, match="Invalid action: Invalid Action"):
|
||||
component.execute_action()
|
||||
|
||||
def test_as_dataframe(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(Action, "OUTLOOK_OUTLOOK_SEND_EMAIL", MockAction.OUTLOOK_OUTLOOK_SEND_EMAIL)
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Send Email"}]
|
||||
component.OUTLOOK_OUTLOOK_SEND_EMAIL_subject = "Test Subject"
|
||||
component.OUTLOOK_OUTLOOK_SEND_EMAIL_body = "Test Body"
|
||||
component.OUTLOOK_OUTLOOK_SEND_EMAIL_to_email = "test@example.com"
|
||||
|
||||
mock_emails = [
|
||||
{
|
||||
"message": "Email sent successfully.",
|
||||
}
|
||||
]
|
||||
with patch.object(component, "execute_action", return_value=mock_emails):
|
||||
result = component.as_dataframe()
|
||||
|
||||
assert isinstance(result, DataFrame)
|
||||
assert not result.empty
|
||||
data_str = str(result)
|
||||
assert "Email sent successfully." in data_str
|
||||
|
||||
def test_update_build_config(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"auth_link": {"value": "", "auth_tooltip": ""},
|
||||
"action": {
|
||||
"options": [],
|
||||
"helper_text": "",
|
||||
"helper_text_metadata": {},
|
||||
},
|
||||
}
|
||||
|
||||
result = component.update_build_config(build_config, "", "api_key")
|
||||
assert result["auth_link"]["value"] == ""
|
||||
assert "Please provide a valid Composio API Key" in result["auth_link"]["auth_tooltip"]
|
||||
assert result["action"]["options"] == []
|
||||
|
||||
component.api_key = "test_key"
|
||||
result = component.update_build_config(build_config, "test_key", "api_key")
|
||||
assert len(result["action"]["options"]) > 0
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from composio import Action
|
||||
from langflow.components.composio.slack_composio import ComposioSlackAPIComponent
|
||||
from langflow.schema.dataframe import DataFrame
|
||||
|
||||
from tests.base import DID_NOT_EXIST, ComponentTestBaseWithoutClient
|
||||
|
||||
from .test_base import MockComposioToolSet
|
||||
|
||||
|
||||
class MockAction:
|
||||
SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL = "SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL"
|
||||
SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION = "SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION"
|
||||
|
||||
|
||||
class TestSlackComponent(ComponentTestBaseWithoutClient):
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_composio_toolset(self):
|
||||
with patch("langflow.base.composio.composio_base.ComposioToolSet", MockComposioToolSet):
|
||||
yield
|
||||
|
||||
@pytest.fixture
|
||||
def component_class(self):
|
||||
return ComposioSlackAPIComponent
|
||||
|
||||
@pytest.fixture
|
||||
def default_kwargs(self):
|
||||
return {
|
||||
"api_key": "",
|
||||
"entity_id": "default",
|
||||
"action": None,
|
||||
}
|
||||
|
||||
@pytest.fixture
|
||||
def file_names_mapping(self):
|
||||
return [
|
||||
{"version": "1.0.17", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.18", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.0.19", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.0", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
{"version": "1.1.1", "module": "composio", "file_name": DID_NOT_EXIST},
|
||||
]
|
||||
|
||||
def test_init(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
assert component.display_name == "Slack"
|
||||
assert component.app_name == "slack"
|
||||
assert "SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL" in component._actions_data
|
||||
assert "SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION" in component._actions_data
|
||||
|
||||
def test_execute_action_send_message_to_channel(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
Action, "SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL", MockAction.SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL
|
||||
)
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Post Message To Channel"}]
|
||||
component.SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_channel = "random"
|
||||
component.SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_text = "Test Body"
|
||||
|
||||
component._actions_data = {
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL": {
|
||||
"display_name": "Post Message To Channel",
|
||||
"action_fields": [
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_as_user",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_attachments",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_blocks",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_channel",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_icon_emoji",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_icon_url",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_link_names",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_mrkdwn",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_parse",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_reply_broadcast",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_text",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_thread_ts",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_unfurl_links",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_unfurl_media",
|
||||
"SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_username",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
result = component.execute_action()
|
||||
assert result == {"result": "mocked response"}
|
||||
|
||||
def test_execute_action_list_all_slack_team_users(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
Action,
|
||||
"SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION",
|
||||
MockAction.SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION,
|
||||
)
|
||||
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "List Users"}]
|
||||
component.SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION_limit = 1
|
||||
|
||||
component._actions_data = {
|
||||
"SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION": {
|
||||
"display_name": "List Users",
|
||||
"action_fields": [
|
||||
"SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION_limit",
|
||||
"SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION_cursor",
|
||||
"SLACK_LIST_ALL_SLACK_TEAM_USERS_WITH_PAGINATION_include_locale",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
mock_toolset = MagicMock()
|
||||
mock_toolset.execute_action.return_value = {"successful": True, "data": {"messages": "mocked response"}}
|
||||
|
||||
with patch.object(component, "_build_wrapper", return_value=mock_toolset):
|
||||
result = component.execute_action()
|
||||
assert result == {"messages": "mocked response"}
|
||||
|
||||
def test_execute_action_invalid_action(self, component_class, default_kwargs):
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Invalid Action"}]
|
||||
|
||||
# Execute action should raise ValueError
|
||||
with pytest.raises(ValueError, match="Invalid action: Invalid Action"):
|
||||
component.execute_action()
|
||||
|
||||
def test_as_dataframe(self, component_class, default_kwargs, monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
Action, "SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL", MockAction.SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL
|
||||
)
|
||||
|
||||
# Setup component
|
||||
component = component_class(**default_kwargs)
|
||||
component.api_key = "test_key"
|
||||
component.action = [{"name": "Post Message To Channel"}]
|
||||
component.SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_channel = "random"
|
||||
component.SLACK_SENDS_A_MESSAGE_TO_A_SLACK_CHANNEL_text = "Test Body"
|
||||
|
||||
mock_slack_messages = [
|
||||
{"channel": "channel1", "user": "user1", "text": "text message 1", "ts": "ts1", "team": "team1"},
|
||||
{"channel": "channel2", "user": "user2", "text": "text message 2", "ts": "ts2", "team": "team2"},
|
||||
]
|
||||
|
||||
with patch.object(component, "execute_action", return_value=mock_slack_messages):
|
||||
result = component.as_dataframe()
|
||||
|
||||
assert isinstance(result, DataFrame)
|
||||
|
||||
assert not result.empty
|
||||
|
||||
data_str = str(result)
|
||||
assert "text message 1" in data_str
|
||||
assert "text message 2" in data_str
|
||||
|
||||
def test_update_build_config(self, component_class, default_kwargs):
|
||||
component = component_class(**default_kwargs)
|
||||
build_config = {
|
||||
"auth_link": {"value": "", "auth_tooltip": ""},
|
||||
"action": {
|
||||
"options": [],
|
||||
"helper_text": "",
|
||||
"helper_text_metadata": {},
|
||||
},
|
||||
}
|
||||
|
||||
result = component.update_build_config(build_config, "", "api_key")
|
||||
assert result["auth_link"]["value"] == ""
|
||||
assert "Please provide a valid Composio API Key" in result["auth_link"]["auth_tooltip"]
|
||||
assert result["action"]["options"] == []
|
||||
|
||||
component.api_key = "test_key"
|
||||
result = component.update_build_config(build_config, "test_key", "api_key")
|
||||
assert len(result["action"]["options"]) > 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue