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 "git.secluded.site/cooked-mcp/internal/cooked"
12)
13
14func TestCallToolACIDShoppingListUpdateItem1To6And8And9UpdatesProductGroupWithMergedFields(t *testing.T) {
15 name := "Whole wheat pasta"
16 selected := false
17 backend := &fakeBackend{shoppingList: cooked.ShoppingList{Aisles: []cooked.Aisle{{
18 ID: "pantry",
19 ProductGroups: []cooked.ProductGroup{{
20 ID: testProductGroupID,
21 Name: "Pasta",
22 Quantity: "200g",
23 Selected: true,
24 }},
25 }}}}
26 server := NewServer(backend, "test")
27
28 _, output, err := server.callChangeShoppingListTool(
29 context.Background(),
30 nil,
31 ChangeShoppingListArguments{
32 Action: " update_item ",
33 ProductGroupID: " " + testProductGroupID + " ",
34 Name: &name,
35 Selected: &selected,
36 },
37 )
38 if err != nil {
39 t.Fatalf("callChangeShoppingListTool() error = %v", err)
40 }
41
42 if backend.readShoppingListCalls != 1 {
43 t.Fatalf("read shopping-list calls = %d, want 1", backend.readShoppingListCalls)
44 }
45 if backend.updateShoppingListCalls != 1 {
46 t.Fatalf("update shopping-list calls = %d, want 1", backend.updateShoppingListCalls)
47 }
48 if backend.updateShoppingListProductGroupID != testProductGroupID {
49 t.Fatalf("updated product group ID = %q, want test product group ID", backend.updateShoppingListProductGroupID)
50 }
51 expectedUpdate := cooked.ShoppingListProductGroupUpdate{
52 Name: "Whole wheat pasta",
53 Quantity: "200g",
54 AisleID: "pantry",
55 Selected: false,
56 }
57 if backend.updateShoppingListProductGroup != expectedUpdate {
58 t.Fatalf("update = %#v, want %#v", backend.updateShoppingListProductGroup, expectedUpdate)
59 }
60 if output.UpdatedProductGroupID != testProductGroupID {
61 t.Fatalf("output updated product group ID = %q, want test product group ID", output.UpdatedProductGroupID)
62 }
63}
64
65func TestCallToolACIDShoppingListUpdateItem7ReportsMissingProductGroup(t *testing.T) {
66 backend := &fakeBackend{shoppingList: cooked.ShoppingList{Aisles: []cooked.Aisle{{
67 ID: "pantry",
68 ProductGroups: []cooked.ProductGroup{{ID: testProductGroupID}},
69 }}}}
70 server := NewServer(backend, "test")
71
72 _, _, err := server.callChangeShoppingListTool(
73 context.Background(),
74 nil,
75 ChangeShoppingListArguments{Action: "update_item", ProductGroupID: testProductGroupID2},
76 )
77 if err == nil {
78 t.Fatal("callChangeShoppingListTool() error = nil, want missing product group error")
79 }
80 if backend.readShoppingListCalls != 1 {
81 t.Fatalf("read shopping-list calls = %d, want 1", backend.readShoppingListCalls)
82 }
83 if backend.updateShoppingListCalls != 0 {
84 t.Fatalf("update shopping-list calls = %d, want none", backend.updateShoppingListCalls)
85 }
86}
87
88// recipes.VALIDATION.1 recipes.VALIDATION.2
89func TestCallToolACIDRecipesValidation1And2RejectsMalformedUpdateItemProductGroupIDBeforeCooked(t *testing.T) {
90 backend := &fakeBackend{}
91 server := NewServer(backend, "test")
92
93 _, _, err := server.callChangeShoppingListTool(
94 context.Background(),
95 nil,
96 ChangeShoppingListArguments{Action: "update_item", ProductGroupID: "not-a-uuid"},
97 )
98 if err == nil {
99 t.Fatal("callChangeShoppingListTool() error = nil, want malformed product_group_id error")
100 }
101 if backend.readShoppingListCalls != 0 {
102 t.Fatalf("read shopping-list calls = %d, want none", backend.readShoppingListCalls)
103 }
104 if backend.updateShoppingListCalls != 0 {
105 t.Fatalf("update shopping-list calls = %d, want none", backend.updateShoppingListCalls)
106 }
107}
108
109func TestCallToolACIDToolsChangeShoppingListTool4RequiresUpdateItemProductGroupID(t *testing.T) {
110 tests := []struct {
111 name string
112 arguments ChangeShoppingListArguments
113 }{
114 {name: "missing", arguments: ChangeShoppingListArguments{Action: "update_item"}},
115 {name: "blank", arguments: ChangeShoppingListArguments{Action: "update_item", ProductGroupID: " "}},
116 }
117
118 for _, tt := range tests {
119 t.Run(tt.name, func(t *testing.T) {
120 backend := &fakeBackend{}
121 server := NewServer(backend, "test")
122
123 _, _, err := server.callChangeShoppingListTool(context.Background(), nil, tt.arguments)
124 if err == nil {
125 t.Fatal("callChangeShoppingListTool() error = nil, want missing product_group_id error")
126 }
127 if backend.readShoppingListCalls != 0 {
128 t.Fatalf("read shopping-list calls = %d, want none", backend.readShoppingListCalls)
129 }
130 if backend.updateShoppingListCalls != 0 {
131 t.Fatalf("update shopping-list calls = %d, want none", backend.updateShoppingListCalls)
132 }
133 })
134 }
135}