server_save_draft_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	"testing"
 10)
 11
 12// recipes.SAVE.7 recipes.SAVE.9 recipes.SAVE.16 recipes.SAFETY.1 tools.SAVE_RECIPE_TOOL.1 tools.SAVE_RECIPE_TOOL.5
 13func TestCallToolACIDRecipesSave7And9And16SavesReviewedDraft(t *testing.T) {
 14	backend := &fakeBackend{draftSaveRecipeID: "recipe-1"}
 15	server := NewServer(backend, "test")
 16
 17	_, output, err := server.callSaveRecipeTool(
 18		context.Background(),
 19		nil,
 20		SaveRecipeArguments{
 21			Source:   " draft ",
 22			DraftID:  " draft-1 ",
 23			Markdown: "  # Pasta\n\n1. Boil pasta.\n",
 24			Portions: 2,
 25		},
 26	)
 27	if err != nil {
 28		t.Fatalf("callSaveRecipeTool() error = %v", err)
 29	}
 30
 31	if backend.draftSaveCalls != 1 {
 32		t.Fatalf("draft save calls = %d, want 1", backend.draftSaveCalls)
 33	}
 34	if backend.draftSaveID != "draft-1" {
 35		t.Fatalf("backend draft ID = %q, want draft-1", backend.draftSaveID)
 36	}
 37	if backend.draftSaveMarkdown != "  # Pasta\n\n1. Boil pasta.\n" {
 38		t.Fatalf("backend draft markdown = %q, want raw markdown preserved", backend.draftSaveMarkdown)
 39	}
 40	if backend.draftSavePortions != 2 {
 41		t.Fatalf("backend draft portions = %d, want 2", backend.draftSavePortions)
 42	}
 43	if output.RecipeID != "recipe-1" || output.DraftID != "" || output.Markdown != "" || output.Portions != 0 {
 44		t.Fatalf("draft save output = %#v, want recipe_id only", output)
 45	}
 46	if backend.importRecipeURLCalls != 0 || backend.metadataCalls != 0 || backend.contentCalls != 0 {
 47		t.Fatalf(
 48			"unexpected import/read calls = import %d metadata %d content %d, want none",
 49			backend.importRecipeURLCalls,
 50			backend.metadataCalls,
 51			backend.contentCalls,
 52		)
 53	}
 54	if backend.saveCalls != 0 || backend.updateCalls != 0 {
 55		t.Fatalf("prepared/update calls = %d/%d, want none", backend.saveCalls, backend.updateCalls)
 56	}
 57}
 58
 59// recipes.SAVE.7-1 recipes.SAVE.7-2 recipes.SAVE.7-3 tools.SAVE_RECIPE_TOOL.5
 60func TestCallToolACIDRecipesSave7_1To7_3AndToolsSaveRecipeTool5RequiresDraftFields(t *testing.T) {
 61	tests := []struct {
 62		name      string
 63		arguments SaveRecipeArguments
 64	}{
 65		{
 66			name:      "draft_id",
 67			arguments: SaveRecipeArguments{Source: "draft", DraftID: "   ", Markdown: "# Pasta", Portions: 2},
 68		},
 69		{
 70			name:      "markdown",
 71			arguments: SaveRecipeArguments{Source: "draft", DraftID: "draft-1", Markdown: "   ", Portions: 2},
 72		},
 73		{
 74			name:      "portions",
 75			arguments: SaveRecipeArguments{Source: "draft", DraftID: "draft-1", Markdown: "# Pasta", Portions: 0},
 76		},
 77	}
 78
 79	for _, tt := range tests {
 80		t.Run(tt.name, func(t *testing.T) {
 81			backend := &fakeBackend{}
 82			server := NewServer(backend, "test")
 83
 84			_, _, err := server.callSaveRecipeTool(context.Background(), nil, tt.arguments)
 85			if err == nil {
 86				t.Fatal("callSaveRecipeTool() error = nil, want missing draft field error")
 87			}
 88			if backend.draftSaveCalls != 0 {
 89				t.Fatalf("draft save calls = %d, want none", backend.draftSaveCalls)
 90			}
 91			if backend.saveCalls != 0 || backend.updateCalls != 0 || backend.importRecipeURLCalls != 0 {
 92				t.Fatalf(
 93					"unexpected backend calls = prepared %d update %d import %d, want none",
 94					backend.saveCalls,
 95					backend.updateCalls,
 96					backend.importRecipeURLCalls,
 97				)
 98			}
 99		})
100	}
101}