|
| 1 | +package resources |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "testing" |
| 6 | + |
| 7 | + "github.com/mongodb/openapi/tools/mcp-server/internal/registry" |
| 8 | + "github.com/stretchr/testify/assert" |
| 9 | + "github.com/stretchr/testify/require" |
| 10 | +) |
| 11 | + |
| 12 | +type wantOp struct { |
| 13 | + operationID string |
| 14 | + method string |
| 15 | + path string |
| 16 | + summary string |
| 17 | +} |
| 18 | + |
| 19 | +func assertOp(t *testing.T, got TagOperation, want wantOp) { |
| 20 | + t.Helper() |
| 21 | + assert.Equal(t, want.operationID, got.OperationID) |
| 22 | + assert.Equal(t, want.method, got.Method) |
| 23 | + assert.Equal(t, want.path, got.Path) |
| 24 | + assert.Equal(t, want.summary, got.Summary) |
| 25 | +} |
| 26 | + |
| 27 | +// TestHandleTags_Clusters verifies Clusters operations are returned sorted by path then method. |
| 28 | +func TestHandleTags_Clusters(t *testing.T) { |
| 29 | + result, err := handleTags(newTestRegistry(t), makeRequest("openapi://specs/test-api/tags/Clusters")) |
| 30 | + require.NoError(t, err) |
| 31 | + |
| 32 | + var body TagsResource |
| 33 | + require.NoError(t, json.Unmarshal([]byte(result.Contents[0].Text), &body)) |
| 34 | + assert.Equal(t, "Clusters", body.Tag) |
| 35 | + require.Equal(t, 4, body.Total) |
| 36 | + |
| 37 | + assertOp(t, body.Operations[0], wantOp{"listClusterDetails", "GET", |
| 38 | + "/api/atlas/v2/clusters", "Return All Authorized Clusters in All Projects"}) |
| 39 | + assertOp(t, body.Operations[1], wantOp{"listGroupClusters", "GET", |
| 40 | + "/api/atlas/v2/groups/{groupId}/clusters", "Return All Clusters in One Project"}) |
| 41 | + assertOp(t, body.Operations[2], wantOp{"createGroupCluster", "POST", |
| 42 | + "/api/atlas/v2/groups/{groupId}/clusters", "Create One Cluster in One Project"}) |
| 43 | + assertOp(t, body.Operations[3], wantOp{"deleteGroupCluster", "DELETE", |
| 44 | + "/api/atlas/v2/groups/{groupId}/clusters/{clusterName}", "Remove One Cluster from One Project"}) |
| 45 | +} |
| 46 | + |
| 47 | +// TestHandleTags_FlexClusters verifies that tag names containing spaces are resolved correctly. |
| 48 | +// The server decodes the URI automatically so agents can use tag names as they appear in the spec. |
| 49 | +func TestHandleTags_FlexClusters(t *testing.T) { |
| 50 | + result, err := handleTags(newTestRegistry(t), makeRequest("openapi://specs/test-api/tags/Flex%20Clusters")) |
| 51 | + require.NoError(t, err) |
| 52 | + |
| 53 | + var body TagsResource |
| 54 | + require.NoError(t, json.Unmarshal([]byte(result.Contents[0].Text), &body)) |
| 55 | + assert.Equal(t, "Flex Clusters", body.Tag) |
| 56 | + require.Equal(t, 2, body.Total) |
| 57 | + |
| 58 | + // Sorted: GET before POST on the same path. |
| 59 | + assertOp(t, body.Operations[0], wantOp{"listGroupFlexClusters", "GET", |
| 60 | + "/api/atlas/v2/groups/{groupId}/flexClusters", "Return All Flex Clusters from One Project"}) |
| 61 | + assertOp(t, body.Operations[1], wantOp{"createGroupFlexCluster", "POST", |
| 62 | + "/api/atlas/v2/groups/{groupId}/flexClusters", "Create One Flex Cluster in One Project"}) |
| 63 | +} |
| 64 | + |
| 65 | +// TestHandleTags_TagNotFound verifies that a non-existent tag returns an error. |
| 66 | +func TestHandleTags_TagNotFound(t *testing.T) { |
| 67 | + _, err := handleTags(newTestRegistry(t), makeRequest("openapi://specs/test-api/tags/NonExistent")) |
| 68 | + require.Error(t, err) |
| 69 | +} |
| 70 | + |
| 71 | +// TestHandleTags_TagCaseSensitive verifies that tag matching is case-sensitive. |
| 72 | +func TestHandleTags_TagCaseSensitive(t *testing.T) { |
| 73 | + _, err := handleTags(newTestRegistry(t), makeRequest("openapi://specs/test-api/tags/clusters")) |
| 74 | + require.Error(t, err) |
| 75 | +} |
| 76 | + |
| 77 | +// TestHandleTags_AliasNotFound verifies that a non-existent alias returns an error. |
| 78 | +func TestHandleTags_AliasNotFound(t *testing.T) { |
| 79 | + _, err := handleTags(registry.New(), makeRequest("openapi://specs/nonexistent/tags/Clusters")) |
| 80 | + require.Error(t, err) |
| 81 | +} |
| 82 | + |
| 83 | +// TestHandleTags_URIInvalid verifies that a URI missing the tag segment returns an error. |
| 84 | +func TestHandleTags_URIInvalid(t *testing.T) { |
| 85 | + _, err := handleTags(registry.New(), makeRequest("openapi://specs/test-api")) |
| 86 | + require.Error(t, err) |
| 87 | +} |
0 commit comments