server_wording_test.go

  1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  2//
  3// SPDX-License-Identifier: LicenseRef-MutuaL-1.2
  4
  5package mcp
  6
  7import (
  8	"context"
  9	"reflect"
 10	"strings"
 11	"testing"
 12)
 13
 14// tools.READ_TOOL.1 tools.SCHEMA.4 tools.RESPONSES.6
 15func TestCallToolACIDToolsReadTool1RejectsUnsupportedTargetBeforeCallingCooked(t *testing.T) {
 16	backend := &fakeBackend{}
 17	server := NewServer(backend, "test")
 18
 19	_, err := server.CallReadTool(context.Background(), ReadArguments{Target: "meal_plan"})
 20	if err == nil {
 21		t.Fatal("CallReadTool() error = nil, want unsupported target error")
 22	}
 23	if err.Error() != `unsupported read target "meal_plan" (supported: shopping_list, recipes, recipe, example_recipes)` {
 24		t.Fatalf("CallReadTool() error = %q", err.Error())
 25	}
 26	if backend.readShoppingListCalls != 0 || backend.metadataCalls != 0 || backend.contentCalls != 0 {
 27		t.Fatalf(
 28			"backend calls = shopping list %d metadata %d content %d, want none",
 29			backend.readShoppingListCalls,
 30			backend.metadataCalls,
 31			backend.contentCalls,
 32		)
 33	}
 34}
 35
 36// recipes.SAVE.10 tools.SCHEMA.4 tools.RESPONSES.6
 37func TestCallToolACIDRecipesSave10RejectsUnsupportedSourceBeforeCallingCooked(t *testing.T) {
 38	backend := &fakeBackend{}
 39	server := NewServer(backend, "test")
 40
 41	_, _, err := server.callSaveRecipeTool(context.Background(), nil, SaveRecipeArguments{Source: "unsupported"})
 42	if err == nil {
 43		t.Fatal("callSaveRecipeTool() error = nil, want unsupported source error")
 44	}
 45	if err.Error() != `unsupported save_recipe source "unsupported" (supported: raw_text, prepared, url, draft, existing)` {
 46		t.Fatalf("callSaveRecipeTool() error = %q", err.Error())
 47	}
 48	if backend.saveCalls != 0 || backend.draftSaveCalls != 0 {
 49		t.Fatalf("save calls = prepared %d draft %d, want none", backend.saveCalls, backend.draftSaveCalls)
 50	}
 51}
 52
 53// tools.SCHEMA.3 tools.SCHEMA.5 tools.SAVE_RECIPE_TOOL.1 tools.CHANGE_SHOPPING_LIST_TOOL.1
 54func TestToolDescriptionsACIDToolsSchema3And5DescribeCurrentLimits(t *testing.T) {
 55	read := readTool()
 56	for _, want := range []string{
 57		"shopping_list",
 58		"recipes",
 59		"recipe with recipe_id",
 60		"example_recipes",
 61		"Recipe results omit images and thumbnails",
 62	} {
 63		if !strings.Contains(read.Description, want) {
 64			t.Fatalf("read description missing %q: %q", want, read.Description)
 65		}
 66	}
 67
 68	save := saveRecipeTool()
 69	for _, want := range []string{
 70		"raw text",
 71		"prepared markdown",
 72		"URL import",
 73		"reviewed URL-import draft",
 74		"existing recipe update",
 75		"draft_id",
 76	} {
 77		if !strings.Contains(save.Description, want) {
 78			t.Fatalf("save_recipe description missing %q: %q", want, save.Description)
 79		}
 80	}
 81
 82	shopping := changeShoppingListTool()
 83	for _, want := range []string{
 84		"add",
 85		"update_item",
 86		"replace_selection",
 87		"add_selection",
 88		"remove_selection",
 89		"remove",
 90		"clear",
 91		"Remove and clear are destructive",
 92		"put quantities before names",
 93		"milk — 1",
 94	} {
 95		if !strings.Contains(shopping.Description, want) {
 96			t.Fatalf("change_shopping_list description missing %q: %q", want, shopping.Description)
 97		}
 98	}
 99}
100
101// tools.READ_TOOL.1 tools.SAVE_RECIPE_TOOL.3 tools.SAVE_RECIPE_TOOL.5 tools.SAVE_RECIPE_TOOL.6
102func TestArgumentDescriptionsACIDToolsReadTool1AndSaveRecipeTool3And5And6PointToExampleRecipes(t *testing.T) {
103	readTarget, ok := reflect.TypeFor[ReadArguments]().FieldByName("Target")
104	if !ok {
105		t.Fatal("ReadArguments.Target field missing")
106	}
107	if !strings.Contains(string(readTarget.Tag), "example_recipes") {
108		t.Fatalf("ReadArguments.Target tag = %q, want example_recipes", readTarget.Tag)
109	}
110
111	saveMarkdown, ok := reflect.TypeFor[SaveRecipeArguments]().FieldByName("Markdown")
112	if !ok {
113		t.Fatal("SaveRecipeArguments.Markdown field missing")
114	}
115	for _, want := range []string{"example_recipes", "Cooked's markdown dialect"} {
116		if !strings.Contains(string(saveMarkdown.Tag), want) {
117			t.Fatalf("SaveRecipeArguments.Markdown tag missing %q: %q", want, saveMarkdown.Tag)
118		}
119	}
120}