mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-02-14 09:05:04 -05:00
feat(tools/looker): Validate project tool (#2430)
## Description Validate changes to a LookML project and report LookML errors. ## PR Checklist > Thank you for opening a Pull Request! Before submitting your PR, there are a > few things you can do to make sure it goes smoothly: - [x] Make sure you reviewed [CONTRIBUTING.md](https://github.com/googleapis/genai-toolbox/blob/main/CONTRIBUTING.md) - [x] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/genai-toolbox/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [x] Appropriate docs were updated (if necessary) - [x] Make sure to add `!` if this involve a breaking change
This commit is contained in:
@@ -37,8 +37,9 @@ https://dev.mysql.com/doc/refman/8.4/en/sql-prepared-statements.html
|
|||||||
https://dev.mysql.com/doc/refman/8.4/en/user-names.html
|
https://dev.mysql.com/doc/refman/8.4/en/user-names.html
|
||||||
|
|
||||||
# npmjs links can occasionally trigger rate limiting during high-frequency CI builds
|
# npmjs links can occasionally trigger rate limiting during high-frequency CI builds
|
||||||
https://www.npmjs.com/package/@toolbox-sdk/core
|
|
||||||
https://www.npmjs.com/package/@toolbox-sdk/adk
|
https://www.npmjs.com/package/@toolbox-sdk/adk
|
||||||
|
https://www.npmjs.com/package/@toolbox-sdk/core
|
||||||
|
https://www.npmjs.com/package/@toolbox-sdk/server
|
||||||
https://www.oceanbase.com/
|
https://www.oceanbase.com/
|
||||||
|
|
||||||
# Ignore social media and blog profiles to reduce external request overhead
|
# Ignore social media and blog profiles to reduce external request overhead
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ import (
|
|||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerrundashboard"
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerrundashboard"
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerrunlook"
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerrunlook"
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerupdateprojectfile"
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookerupdateprojectfile"
|
||||||
|
_ "github.com/googleapis/genai-toolbox/internal/tools/looker/lookervalidateproject"
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbexecutesql"
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbexecutesql"
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbsql"
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mindsdb/mindsdbsql"
|
||||||
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbaggregate"
|
_ "github.com/googleapis/genai-toolbox/internal/tools/mongodb/mongodbaggregate"
|
||||||
|
|||||||
@@ -2370,7 +2370,7 @@ func TestPrebuiltTools(t *testing.T) {
|
|||||||
wantToolset: server.ToolsetConfigs{
|
wantToolset: server.ToolsetConfigs{
|
||||||
"looker_tools": tools.ToolsetConfig{
|
"looker_tools": tools.ToolsetConfig{
|
||||||
Name: "looker_tools",
|
Name: "looker_tools",
|
||||||
ToolNames: []string{"get_models", "get_explores", "get_dimensions", "get_measures", "get_filters", "get_parameters", "query", "query_sql", "query_url", "get_looks", "run_look", "make_look", "get_dashboards", "run_dashboard", "make_dashboard", "add_dashboard_element", "add_dashboard_filter", "generate_embed_url", "health_pulse", "health_analyze", "health_vacuum", "dev_mode", "get_projects", "get_project_files", "get_project_file", "create_project_file", "update_project_file", "delete_project_file", "get_connections", "get_connection_schemas", "get_connection_databases", "get_connection_tables", "get_connection_table_columns"},
|
ToolNames: []string{"get_models", "get_explores", "get_dimensions", "get_measures", "get_filters", "get_parameters", "query", "query_sql", "query_url", "get_looks", "run_look", "make_look", "get_dashboards", "run_dashboard", "make_dashboard", "add_dashboard_element", "add_dashboard_filter", "generate_embed_url", "health_pulse", "health_analyze", "health_vacuum", "dev_mode", "get_projects", "get_project_files", "get_project_file", "create_project_file", "update_project_file", "delete_project_file", "validate_project", "get_connections", "get_connection_schemas", "get_connection_databases", "get_connection_tables", "get_connection_table_columns"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -488,6 +488,7 @@ See [Usage Examples](../reference/cli.md#examples).
|
|||||||
* `create_project_file`: Create a new LookML file.
|
* `create_project_file`: Create a new LookML file.
|
||||||
* `update_project_file`: Update an existing LookML file.
|
* `update_project_file`: Update an existing LookML file.
|
||||||
* `delete_project_file`: Delete a LookML file.
|
* `delete_project_file`: Delete a LookML file.
|
||||||
|
* `validate_project`: Check the syntax of a LookML project.
|
||||||
* `get_connections`: Get the available connections in a Looker instance.
|
* `get_connections`: Get the available connections in a Looker instance.
|
||||||
* `get_connection_schemas`: Get the available schemas in a connection.
|
* `get_connection_schemas`: Get the available schemas in a connection.
|
||||||
* `get_connection_databases`: Get the available databases in a connection.
|
* `get_connection_databases`: Get the available databases in a connection.
|
||||||
|
|||||||
47
docs/en/resources/tools/looker/looker-validate-project.md
Normal file
47
docs/en/resources/tools/looker/looker-validate-project.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
title: "looker-validate-project"
|
||||||
|
type: docs
|
||||||
|
weight: 1
|
||||||
|
description: >
|
||||||
|
A "looker-validate-project" tool checks the syntax of a LookML project and reports any errors
|
||||||
|
aliases:
|
||||||
|
- /resources/tools/looker-validate-project
|
||||||
|
---
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
A "looker-validate-project" tool checks the syntax of a LookML project and reports any errors
|
||||||
|
|
||||||
|
It's compatible with the following sources:
|
||||||
|
|
||||||
|
- [looker](../../sources/looker.md)
|
||||||
|
|
||||||
|
`looker-validate-project` accepts a project_id parameter.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tools:
|
||||||
|
validate_project:
|
||||||
|
kind: looker-validate-project
|
||||||
|
source: looker-source
|
||||||
|
description: |
|
||||||
|
This tool checks a LookML project for syntax errors.
|
||||||
|
|
||||||
|
Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- project_id (required): The unique ID of the LookML project.
|
||||||
|
|
||||||
|
Output:
|
||||||
|
A list of error details including the file path and line number, and also a list of models
|
||||||
|
that are not currently valid due to LookML errors.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
| **field** | **type** | **required** | **description** |
|
||||||
|
|-------------|:--------:|:------------:|----------------------------------------------------|
|
||||||
|
| kind | string | true | Must be "looker-validate-project". |
|
||||||
|
| source | string | true | Name of the source Looker instance. |
|
||||||
|
| description | string | true | Description of the tool that is passed to the LLM. |
|
||||||
@@ -959,6 +959,21 @@ tools:
|
|||||||
Output:
|
Output:
|
||||||
A confirmation message upon successful file deletion.
|
A confirmation message upon successful file deletion.
|
||||||
|
|
||||||
|
validate_project:
|
||||||
|
kind: looker-validate-project
|
||||||
|
source: looker-source
|
||||||
|
description: |
|
||||||
|
This tool checks a LookML project for syntax errors.
|
||||||
|
|
||||||
|
Prerequisite: The Looker session must be in Development Mode. Use `dev_mode: true` first.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- project_id (required): The unique ID of the LookML project.
|
||||||
|
|
||||||
|
Output:
|
||||||
|
A list of error details including the file path and line number, and also a list of models
|
||||||
|
that are not currently valid due to LookML errors.
|
||||||
|
|
||||||
get_connections:
|
get_connections:
|
||||||
kind: looker-get-connections
|
kind: looker-get-connections
|
||||||
source: looker-source
|
source: looker-source
|
||||||
@@ -1072,6 +1087,7 @@ toolsets:
|
|||||||
- create_project_file
|
- create_project_file
|
||||||
- update_project_file
|
- update_project_file
|
||||||
- delete_project_file
|
- delete_project_file
|
||||||
|
- validate_project
|
||||||
- get_connections
|
- get_connections
|
||||||
- get_connection_schemas
|
- get_connection_schemas
|
||||||
- get_connection_databases
|
- get_connection_databases
|
||||||
|
|||||||
@@ -0,0 +1,177 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
package lookervalidateproject
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
yaml "github.com/goccy/go-yaml"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/embeddingmodels"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/tools"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/util"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||||
|
|
||||||
|
"github.com/looker-open-source/sdk-codegen/go/rtl"
|
||||||
|
v4 "github.com/looker-open-source/sdk-codegen/go/sdk/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
const resourceType string = "looker-validate-project"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if !tools.Register(resourceType, newConfig) {
|
||||||
|
panic(fmt.Sprintf("tool type %q already registered", resourceType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (tools.ToolConfig, error) {
|
||||||
|
actual := Config{Name: name}
|
||||||
|
if err := decoder.DecodeContext(ctx, &actual); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return actual, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type compatibleSource interface {
|
||||||
|
UseClientAuthorization() bool
|
||||||
|
GetAuthTokenHeaderName() string
|
||||||
|
LookerApiSettings() *rtl.ApiSettings
|
||||||
|
GetLookerSDK(string) (*v4.LookerSDK, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Name string `yaml:"name" validate:"required"`
|
||||||
|
Type string `yaml:"type" validate:"required"`
|
||||||
|
Source string `yaml:"source" validate:"required"`
|
||||||
|
Description string `yaml:"description" validate:"required"`
|
||||||
|
AuthRequired []string `yaml:"authRequired"`
|
||||||
|
Annotations *tools.ToolAnnotations `yaml:"annotations,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate interface
|
||||||
|
var _ tools.ToolConfig = Config{}
|
||||||
|
|
||||||
|
func (cfg Config) ToolConfigType() string {
|
||||||
|
return resourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error) {
|
||||||
|
projectIdParameter := parameters.NewStringParameter("project_id", "The id of the project to validate")
|
||||||
|
params := parameters.Parameters{projectIdParameter}
|
||||||
|
|
||||||
|
annotations := cfg.Annotations
|
||||||
|
if annotations == nil {
|
||||||
|
readOnlyHint := true
|
||||||
|
annotations = &tools.ToolAnnotations{
|
||||||
|
ReadOnlyHint: &readOnlyHint,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mcpManifest := tools.GetMcpManifest(cfg.Name, cfg.Description, cfg.AuthRequired, params, annotations)
|
||||||
|
|
||||||
|
// finish tool setup
|
||||||
|
return Tool{
|
||||||
|
Config: cfg,
|
||||||
|
Parameters: params,
|
||||||
|
manifest: tools.Manifest{
|
||||||
|
Description: cfg.Description,
|
||||||
|
Parameters: params.Manifest(),
|
||||||
|
AuthRequired: cfg.AuthRequired,
|
||||||
|
},
|
||||||
|
mcpManifest: mcpManifest,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate interface
|
||||||
|
var _ tools.Tool = Tool{}
|
||||||
|
|
||||||
|
type Tool struct {
|
||||||
|
Config
|
||||||
|
Parameters parameters.Parameters `yaml:"parameters"`
|
||||||
|
manifest tools.Manifest
|
||||||
|
mcpManifest tools.McpManifest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) ToConfig() tools.ToolConfig {
|
||||||
|
return t.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) Invoke(ctx context.Context, resourceMgr tools.SourceProvider, params parameters.ParamValues, accessToken tools.AccessToken) (any, error) {
|
||||||
|
source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger, err := util.LoggerFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to get logger from ctx: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sdk, err := source.GetLookerSDK(string(accessToken))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error getting sdk: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mapParams := params.AsMap()
|
||||||
|
projectId, ok := mapParams["project_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("'project_id' must be a string, got %T", mapParams["project_id"])
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := sdk.ValidateProject(projectId, "", source.LookerApiSettings())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error making validate_project request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.DebugContext(ctx, "Got response of %v\n", resp)
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) EmbedParams(ctx context.Context, paramValues parameters.ParamValues, embeddingModelsMap map[string]embeddingmodels.EmbeddingModel) (parameters.ParamValues, error) {
|
||||||
|
return parameters.EmbedParams(ctx, t.Parameters, paramValues, embeddingModelsMap, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) Manifest() tools.Manifest {
|
||||||
|
return t.manifest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) McpManifest() tools.McpManifest {
|
||||||
|
return t.mcpManifest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) Authorized(verifiedAuthServices []string) bool {
|
||||||
|
return tools.IsAuthorized(t.AuthRequired, verifiedAuthServices)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) RequiresClientAuthorization(resourceMgr tools.SourceProvider) (bool, error) {
|
||||||
|
source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return source.UseClientAuthorization(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) GetAuthTokenHeaderName(resourceMgr tools.SourceProvider) (string, error) {
|
||||||
|
source, err := tools.GetCompatibleSource[compatibleSource](resourceMgr, t.Source, t.Name, t.Type)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return source.GetAuthTokenHeaderName(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Tool) GetParameters() parameters.Parameters {
|
||||||
|
return t.Parameters
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
// Copyright 2026 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package lookervalidateproject_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/server"
|
||||||
|
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||||
|
lkr "github.com/googleapis/genai-toolbox/internal/tools/looker/lookervalidateproject"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseFromYamlLookerValidateProject(t *testing.T) {
|
||||||
|
ctx, err := testutils.ContextWithNewLogger()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
tcs := []struct {
|
||||||
|
desc string
|
||||||
|
in string
|
||||||
|
want server.ToolConfigs
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "basic example",
|
||||||
|
in: `
|
||||||
|
kind: tools
|
||||||
|
name: example_tool
|
||||||
|
type: looker-validate-project
|
||||||
|
source: my-instance
|
||||||
|
description: some description
|
||||||
|
`,
|
||||||
|
want: server.ToolConfigs{
|
||||||
|
"example_tool": lkr.Config{
|
||||||
|
Name: "example_tool",
|
||||||
|
Type: "looker-validate-project",
|
||||||
|
Source: "my-instance",
|
||||||
|
Description: "some description",
|
||||||
|
AuthRequired: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tcs {
|
||||||
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
|
// Parse contents
|
||||||
|
_, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to unmarshal: %s", err)
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||||
|
t.Fatalf("incorrect parse: diff %v", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFailParseFromYamlLookerValidateProject(t *testing.T) {
|
||||||
|
ctx, err := testutils.ContextWithNewLogger()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
tcs := []struct {
|
||||||
|
desc string
|
||||||
|
in string
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "Invalid method",
|
||||||
|
in: `
|
||||||
|
kind: tools
|
||||||
|
name: example_tool
|
||||||
|
type: looker-validate-project
|
||||||
|
source: my-instance
|
||||||
|
method: GOT
|
||||||
|
description: some description
|
||||||
|
`,
|
||||||
|
err: "error unmarshaling tools: unable to parse tool \"example_tool\" as type \"looker-validate-project\": [3:1] unknown field \"method\"\n 1 | authRequired: []\n 2 | description: some description\n> 3 | method: GOT\n ^\n 4 | name: example_tool\n 5 | source: my-instance\n 6 | type: looker-validate-project",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tcs {
|
||||||
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
|
// Parse contents
|
||||||
|
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect parsing to fail")
|
||||||
|
}
|
||||||
|
errStr := err.Error()
|
||||||
|
if !strings.Contains(errStr, tc.err) {
|
||||||
|
t.Fatalf("unexpected error string: got %q, want substring %q", errStr, tc.err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -222,6 +222,11 @@ func TestLooker(t *testing.T) {
|
|||||||
"source": "my-instance",
|
"source": "my-instance",
|
||||||
"description": "Simple tool to test end to end functionality.",
|
"description": "Simple tool to test end to end functionality.",
|
||||||
},
|
},
|
||||||
|
"validate_project": map[string]any{
|
||||||
|
"type": "looker-validate-project",
|
||||||
|
"source": "my-instance",
|
||||||
|
"description": "Simple tool to test end to end functionality.",
|
||||||
|
},
|
||||||
"generate_embed_url": map[string]any{
|
"generate_embed_url": map[string]any{
|
||||||
"type": "looker-generate-embed-url",
|
"type": "looker-generate-embed-url",
|
||||||
"source": "my-instance",
|
"source": "my-instance",
|
||||||
@@ -1446,6 +1451,23 @@ func TestLooker(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
tests.RunToolGetTestByName(t, "validate_project",
|
||||||
|
map[string]any{
|
||||||
|
"validate_project": map[string]any{
|
||||||
|
"description": "Simple tool to test end to end functionality.",
|
||||||
|
"authRequired": []any{},
|
||||||
|
"parameters": []any{
|
||||||
|
map[string]any{
|
||||||
|
"authSources": []any{},
|
||||||
|
"description": "The id of the project to validate",
|
||||||
|
"name": "project_id",
|
||||||
|
"required": true,
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
tests.RunToolGetTestByName(t, "generate_embed_url",
|
tests.RunToolGetTestByName(t, "generate_embed_url",
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"generate_embed_url": map[string]any{
|
"generate_embed_url": map[string]any{
|
||||||
@@ -1665,6 +1687,9 @@ func TestLooker(t *testing.T) {
|
|||||||
wantResult = "deleted"
|
wantResult = "deleted"
|
||||||
tests.RunToolInvokeParametersTest(t, "delete_project_file", []byte(`{"project_id": "the_look", "file_path": "foo.view.lkml"}`), wantResult)
|
tests.RunToolInvokeParametersTest(t, "delete_project_file", []byte(`{"project_id": "the_look", "file_path": "foo.view.lkml"}`), wantResult)
|
||||||
|
|
||||||
|
wantResult = "\"errors\":[]"
|
||||||
|
tests.RunToolInvokeParametersTest(t, "validate_project", []byte(`{"project_id": "the_look"}`), wantResult)
|
||||||
|
|
||||||
wantResult = "production"
|
wantResult = "production"
|
||||||
tests.RunToolInvokeParametersTest(t, "dev_mode", []byte(`{"devMode": false}`), wantResult)
|
tests.RunToolInvokeParametersTest(t, "dev_mode", []byte(`{"devMode": false}`), wantResult)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user