···11+package handler
22+33+import (
44+ "context"
55+ "net/http"
66+ "net/http/httptest"
77+ "net/url"
88+ "strings"
99+ "testing"
1010+ "tumble/internal/config"
1111+ "tumble/internal/data"
1212+)
1313+1414+// MockStore implements data.Store for testing
1515+type MockStore struct {
1616+ data.Store // Embed interface to skip implementing everything
1717+ LastQuote string
1818+ LastAuthor string
1919+}
2020+2121+func (m *MockStore) InsertQuote(ctx context.Context, quote, author string) error {
2222+ m.LastQuote = quote
2323+ m.LastAuthor = author
2424+ return nil
2525+}
2626+2727+func TestQuoteHandler_UnescapesInput(t *testing.T) {
2828+ // Setup
2929+ mockStore := &MockStore{}
3030+ h := &Handler{
3131+ Store: mockStore,
3232+ Config: &config.Config{},
3333+ }
3434+3535+ // Test Case: Encoded HTML entities
3636+ // "I"ve been to fort Dicks" -> "I"ve been to fort Dicks"
3737+ form := url.Values{}
3838+ form.Add("quote", "I"ve been to fort Dicks")
3939+ form.Add("author", "james<white>")
4040+4141+ req := httptest.NewRequest("POST", "/quote/", strings.NewReader(form.Encode()))
4242+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
4343+ w := httptest.NewRecorder()
4444+4545+ // Execute
4646+ h.QuoteHandler(w, req)
4747+4848+ // Verify
4949+ if w.Code != http.StatusOK {
5050+ t.Errorf("Expected status 200, got %d", w.Code)
5151+ }
5252+5353+ // Check if the store received the UNESCAPED string
5454+ expectedQuote := "I\"ve been to fort Dicks"
5555+ if mockStore.LastQuote != expectedQuote {
5656+ t.Errorf("Expected quote %q, got %q", expectedQuote, mockStore.LastQuote)
5757+ }
5858+5959+ expectedAuthor := "james<white>"
6060+ if mockStore.LastAuthor != expectedAuthor {
6161+ t.Errorf("Expected author %q, got %q", expectedAuthor, mockStore.LastAuthor)
6262+ }
6363+}
+1-1
internal/templates/views/index.html
···162162 return div.innerHTML;
163163 }
164164165165- // Global handler for video replacement
165165+ // Global handler for video replacemen
166166 window.replaceWithVideo = function(container) {
167167 // Find URL from parent item
168168 var item = container.closest('.item');