Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions client/src/api/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24896,6 +24896,15 @@ export interface components {
};
/** VisualizationPluginResponse */
VisualizationPluginResponse: {
/**
* Data Sources
* @description The data sources of the plugin.
*/
data_sources?:
| {
[key: string]: unknown;
}[]
| null;
/**
* Description
* @description The description of the plugin.
Expand All @@ -24913,6 +24922,11 @@ export interface components {
entry_point: {
[key: string]: unknown;
};
/**
* Help
* @description The help text of the plugin.
*/
help?: string | null;
/**
* Href
* @description The href of the plugin.
Expand All @@ -24933,6 +24947,13 @@ export interface components {
* @description The name of the plugin.
*/
name: string;
/**
* Params
* @description The parameters of the plugin.
*/
params?: {
[key: string]: unknown;
} | null;
/**
* Settings
* @description The settings of the plugin.
Expand All @@ -24949,6 +24970,20 @@ export interface components {
specs?: {
[key: string]: unknown;
} | null;
/**
* Tags
* @description The tags of the plugin.
*/
tags?: string[] | null;
/**
* Tests
* @description The tests of the plugin.
*/
tests?:
| {
[key: string]: unknown;
}[]
| null;
/**
* Title
* @description The title of the plugin.
Expand Down
25 changes: 25 additions & 0 deletions lib/galaxy/schema/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,31 @@ class VisualizationPluginResponse(Model):
title="Specs",
description="The specs of the plugin.",
)
params: Optional[dict] = Field(
None,
title="Params",
description="The parameters of the plugin.",
)
data_sources: Optional[list[dict]] = Field(
None,
title="Data Sources",
description="The data sources of the plugin.",
)
help: Optional[str] = Field(
None,
title="Help",
description="The help text of the plugin.",
)
tags: Optional[list[str]] = Field(
None,
title="Tags",
description="The tags of the plugin.",
)
tests: Optional[list[dict]] = Field(
None,
title="Tests",
description="The tests of the plugin.",
)
href: str = Field(
...,
title="Href",
Expand Down
56 changes: 55 additions & 1 deletion test/integration/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,68 @@
TEST_VISUALIZATION_PLUGINS_DIR = os.path.join(os.path.dirname(__file__), "test_visualization_plugins")


class TestAiApi(IntegrationTestCase):
class TestVisualizationPluginsApi(IntegrationTestCase):
"""Tests for the visualization plugins API endpoints."""

@classmethod
def handle_galaxy_config_kwds(cls, config) -> None:
config["ai_api_key"] = "ai_api_key"
config["ai_api_base_url"] = "ai_api_base_url"
config["ai_model"] = "ai_model"
config["visualization_plugins_directory"] = TEST_VISUALIZATION_PLUGINS_DIR

def test_index(self):
"""Test that GET /api/plugins returns a list of plugins."""
response = self._get("plugins")
self._assert_status_code_is(response, 200)
plugins = response.json()
assert isinstance(plugins, list)

def test_show_returns_all_fields(self):
"""Test that GET /api/plugins/{id} returns all expected fields including params, tags, tests, help, data_sources."""
response = self._get("plugins/jupyterlite")
self._assert_status_code_is(response, 200)
plugin = response.json()

# Verify required fields
assert plugin["name"] == "jupyterlite"
assert plugin["html"] == "JupyterLite Test"
assert plugin["description"] == "Test fixture for visualization plugin integration tests"
assert plugin["embeddable"] is False
assert "entry_point" in plugin
assert "href" in plugin

# Verify params are returned correctly
assert "params" in plugin
params = plugin["params"]
assert "dataset_id" in params
assert params["dataset_id"]["required"] is True
assert params["dataset_id"]["type"] == "str"

# Verify data_sources are returned
assert "data_sources" in plugin
data_sources = plugin["data_sources"]
assert len(data_sources) >= 1
assert data_sources[0]["model_class"] == "HistoryDatasetAssociation"

# Verify specs are returned
assert "specs" in plugin
assert plugin["specs"]["custom_setting"] == "test_value"

# Verify tags are returned
assert "tags" in plugin
tags = plugin["tags"]
assert "Test" in tags
assert "Integration" in tags

# Verify help is returned
assert "help" in plugin
assert "test help text" in plugin["help"]

# Verify tests are returned
assert "tests" in plugin
assert len(plugin["tests"]) >= 1

def _create_payload(self, extra=None):
payload = {
"messages": [{"role": "user", "content": "hi"}],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<visualization name="JupyterLite Test" hidden="true">
<description>Test fixture for AI chat integration tests</description>
<description>Test fixture for visualization plugin integration tests</description>
<data_sources>
<data_source>
<model_class>HistoryDatasetAssociation</model_class>
</data_source>
</data_sources>
<params>
<param required="true">dataset_id</param>
</params>
<entry_point entry_point_type="script" src="script.js" />
<specs>
<ai_prompt>test prompt</ai_prompt>
<custom_setting>test_value</custom_setting>
</specs>
<tags>
<tag>Test</tag>
<tag>Integration</tag>
</tags>
<help>This is test help text for the JupyterLite test plugin.</help>
<tests>
<test>
<param name="dataset_id" value="test.tabular" />
</test>
</tests>
</visualization>
Loading