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: "pasta",
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: " pasta ",
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 != "pasta" {
49 t.Fatalf("updated product group ID = %q, want pasta", 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 != "pasta" {
61 t.Fatalf("output updated product group ID = %q, want pasta", 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: "pasta"}},
69 }}}}
70 server := NewServer(backend, "test")
71
72 _, _, err := server.callChangeShoppingListTool(
73 context.Background(),
74 nil,
75 ChangeShoppingListArguments{Action: "update_item", ProductGroupID: "tomato"},
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
88func TestCallToolACIDToolsChangeShoppingListTool4RequiresUpdateItemProductGroupID(t *testing.T) {
89 tests := []struct {
90 name string
91 arguments ChangeShoppingListArguments
92 }{
93 {name: "missing", arguments: ChangeShoppingListArguments{Action: "update_item"}},
94 {name: "blank", arguments: ChangeShoppingListArguments{Action: "update_item", ProductGroupID: " "}},
95 }
96
97 for _, tt := range tests {
98 t.Run(tt.name, func(t *testing.T) {
99 backend := &fakeBackend{}
100 server := NewServer(backend, "test")
101
102 _, _, err := server.callChangeShoppingListTool(context.Background(), nil, tt.arguments)
103 if err == nil {
104 t.Fatal("callChangeShoppingListTool() error = nil, want missing product_group_id error")
105 }
106 if backend.readShoppingListCalls != 0 {
107 t.Fatalf("read shopping-list calls = %d, want none", backend.readShoppingListCalls)
108 }
109 if backend.updateShoppingListCalls != 0 {
110 t.Fatalf("update shopping-list calls = %d, want none", backend.updateShoppingListCalls)
111 }
112 })
113 }
114}