summaryrefslogtreecommitdiff
path: root/internal/api/plantoeat_test.go
blob: 50ad4ed8426d1b8bf1e0c65af472daa81515b5f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package api

import (
	"strings"
	"testing"
)

func TestParseShoppingListHTML(t *testing.T) {
	// Sample HTML structure matching PlanToEat's shopping list
	html := `
	<div id="shopping_items" data-total-items="3">
		<div id="store-0" class="store" data-store-id="0">
			<div class="store_heading">
				<h4 class="store_name">Costco (3)</h4>
			</div>
			<table>
				<tr>
					<td class="column">
						<div class="category-box" id="cat01_350">
							<p class="category-title"><span>Baking</span></p>
							<ul class="ingredients">
								<li class="sli noselect i493745871" data-store-id="0">
									<label class="checkbox-label">
										<input type="checkbox" name="items[493745871]" value="493745871">
										<strong>Olive oil</strong> <span class="quan">2 tablespoons</span>
									</label>
								</li>
								<li class="sli noselect i493745872 checked" data-store-id="0">
									<label class="checkbox-label">
										<input type="checkbox" name="items[493745872]" value="493745872" checked>
										<strong>Flour</strong> <span class="quan">1 cup</span>
									</label>
								</li>
							</ul>
						</div>
						<div class="category-box" id="cat01_347">
							<p class="category-title"><span>Meat</span></p>
							<ul class="ingredients">
								<li class="sli noselect i493745889" data-store-id="0">
									<label class="checkbox-label">
										<input type="checkbox" name="items[493745889]" value="493745889">
										<strong>Ground beef</strong> <span class="quan">1 pound</span>
									</label>
								</li>
							</ul>
						</div>
					</td>
				</tr>
			</table>
		</div>
	</div>`

	items, err := parseShoppingListHTML(strings.NewReader(html))
	if err != nil {
		t.Fatalf("parseShoppingListHTML failed: %v", err)
	}

	if len(items) != 3 {
		t.Errorf("Expected 3 items, got %d", len(items))
	}

	// Check first item
	if items[0].Name != "Olive oil" {
		t.Errorf("Expected first item name 'Olive oil', got '%s'", items[0].Name)
	}
	if items[0].Quantity != "2 tablespoons" {
		t.Errorf("Expected quantity '2 tablespoons', got '%s'", items[0].Quantity)
	}
	if items[0].Category != "Baking" {
		t.Errorf("Expected category 'Baking', got '%s'", items[0].Category)
	}
	if items[0].Store != "Costco" {
		t.Errorf("Expected store 'Costco', got '%s'", items[0].Store)
	}
	if items[0].ID != "493745871" {
		t.Errorf("Expected ID '493745871', got '%s'", items[0].ID)
	}
	if items[0].Checked {
		t.Error("Expected first item to not be checked")
	}

	// Check checked item
	if !items[1].Checked {
		t.Error("Expected second item to be checked")
	}

	// Check item from different category
	if items[2].Name != "Ground beef" {
		t.Errorf("Expected 'Ground beef', got '%s'", items[2].Name)
	}
	if items[2].Category != "Meat" {
		t.Errorf("Expected category 'Meat', got '%s'", items[2].Category)
	}
}

func TestParseShoppingListHTML_EmptyList(t *testing.T) {
	html := `<div id="shopping_items" data-total-items="0"></div>`

	items, err := parseShoppingListHTML(strings.NewReader(html))
	if err != nil {
		t.Fatalf("parseShoppingListHTML failed: %v", err)
	}

	if len(items) != 0 {
		t.Errorf("Expected 0 items for empty list, got %d", len(items))
	}
}

func TestCleanQuantity(t *testing.T) {
	tests := []struct {
		input    string
		expected string
	}{
		{"1 cup", "1 cup"},
		{"2  tablespoons", "2 tablespoons"},
		{"1\u00a0pound", "1 pound"},
		{"  3 oz  ", "3 oz"},
	}

	for _, tt := range tests {
		result := cleanQuantity(tt.input)
		if result != tt.expected {
			t.Errorf("cleanQuantity(%q) = %q, want %q", tt.input, result, tt.expected)
		}
	}
}