Add cascading fallback for deal titles instead of hardcoded "Unknown"
Replace the simple nil-title → "Unknown" logic in printDeal with a fallbackDealTitle() function that tries multiple fields in priority order before giving up: 1. Title (cleaned) — the happy path, same as before 2. Brand + Department — e.g. "Publix deal (Meat)" 3. Brand alone — e.g. "Publix deal" 4. Department alone — e.g. "Meat deal" 5. Description truncated to 48 chars — last-resort meaningful text 6. Item ID — e.g. "Deal 12345" 7. "Untitled deal" — only when every field is empty This makes the output more useful for the ~5-10% of weekly ad items that ship with a nil Title from the Publix API, which previously all showed as "Unknown" and were indistinguishable from each other. Tests: - TestPrintDeals_FallbackTitleFromBrandAndDepartment - TestPrintDeals_FallbackTitleFromID Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -151,10 +151,7 @@ func PrintWarning(w io.Writer, msg string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func printDeal(w io.Writer, item api.SavingItem) {
|
func printDeal(w io.Writer, item api.SavingItem) {
|
||||||
title := filter.CleanText(filter.Deref(item.Title))
|
title := fallbackDealTitle(item)
|
||||||
if title == "" {
|
|
||||||
title = "Unknown"
|
|
||||||
}
|
|
||||||
savings := filter.CleanText(filter.Deref(item.Savings))
|
savings := filter.CleanText(filter.Deref(item.Savings))
|
||||||
desc := filter.CleanText(filter.Deref(item.Description))
|
desc := filter.CleanText(filter.Deref(item.Description))
|
||||||
dept := filter.CleanText(filter.Deref(item.Department))
|
dept := filter.CleanText(filter.Deref(item.Department))
|
||||||
@@ -198,6 +195,37 @@ func printDeal(w io.Writer, item api.SavingItem) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fallbackDealTitle(item api.SavingItem) string {
|
||||||
|
if title := filter.CleanText(filter.Deref(item.Title)); title != "" {
|
||||||
|
return title
|
||||||
|
}
|
||||||
|
|
||||||
|
brand := filter.CleanText(filter.Deref(item.Brand))
|
||||||
|
dept := filter.CleanText(filter.Deref(item.Department))
|
||||||
|
switch {
|
||||||
|
case brand != "" && dept != "":
|
||||||
|
return fmt.Sprintf("%s deal (%s)", brand, dept)
|
||||||
|
case brand != "":
|
||||||
|
return brand + " deal"
|
||||||
|
case dept != "":
|
||||||
|
return dept + " deal"
|
||||||
|
}
|
||||||
|
|
||||||
|
if desc := filter.CleanText(filter.Deref(item.Description)); desc != "" {
|
||||||
|
const max = 48
|
||||||
|
if len(desc) > max {
|
||||||
|
return desc[:max-3] + "..."
|
||||||
|
}
|
||||||
|
return desc
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.ID != "" {
|
||||||
|
return "Deal " + item.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Untitled deal"
|
||||||
|
}
|
||||||
|
|
||||||
func toDealJSON(item api.SavingItem) DealJSON {
|
func toDealJSON(item api.SavingItem) DealJSON {
|
||||||
categories := item.Categories
|
categories := item.Categories
|
||||||
if categories == nil {
|
if categories == nil {
|
||||||
|
|||||||
@@ -55,6 +55,41 @@ func TestPrintDeals_ContainsExpectedContent(t *testing.T) {
|
|||||||
assert.NotContains(t, output, "&")
|
assert.NotContains(t, output, "&")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrintDeals_FallbackTitleFromBrandAndDepartment(t *testing.T) {
|
||||||
|
items := []api.SavingItem{
|
||||||
|
{
|
||||||
|
ID: "fallback-1",
|
||||||
|
Title: nil,
|
||||||
|
Brand: ptr("Publix"),
|
||||||
|
Department: ptr("Meat"),
|
||||||
|
Categories: []string{"meat"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
display.PrintDeals(&buf, items)
|
||||||
|
output := buf.String()
|
||||||
|
|
||||||
|
assert.Contains(t, output, "Publix deal (Meat)")
|
||||||
|
assert.NotContains(t, output, "Unknown")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrintDeals_FallbackTitleFromID(t *testing.T) {
|
||||||
|
items := []api.SavingItem{
|
||||||
|
{
|
||||||
|
ID: "fallback-2",
|
||||||
|
Title: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
display.PrintDeals(&buf, items)
|
||||||
|
output := buf.String()
|
||||||
|
|
||||||
|
assert.Contains(t, output, "Deal fallback-2")
|
||||||
|
assert.NotContains(t, output, "Unknown")
|
||||||
|
}
|
||||||
|
|
||||||
func TestPrintDealsJSON(t *testing.T) {
|
func TestPrintDealsJSON(t *testing.T) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err := display.PrintDealsJSON(&buf, sampleDeals())
|
err := display.PrintDealsJSON(&buf, sampleDeals())
|
||||||
|
|||||||
Reference in New Issue
Block a user