From 86f9b685de38d200dd27550c5d1a37121682e26c Mon Sep 17 00:00:00 2001 From: Shekhar Vaidya Date: Thu, 18 Jun 2026 11:39:09 +0530 Subject: [PATCH] feat(cli): product catalog with word-based search --- cli/catalog.go | 82 +++++++++++++++++++++++++++++++++++++++++++++ cli/catalog_test.go | 58 ++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 cli/catalog.go create mode 100644 cli/catalog_test.go diff --git a/cli/catalog.go b/cli/catalog.go new file mode 100644 index 0000000..9c949c2 --- /dev/null +++ b/cli/catalog.go @@ -0,0 +1,82 @@ +package main + +import "strings" + +type Product struct { + ID string + Name string +} + +type EvalProduct struct { + Slug string + Name string + EvalURL string +} + +var consumerProducts = []Product{ + {"52", "Windows 8.1 (9600.17415)"}, + {"2378", "Windows 10 22H2 Home China (19045.2006)"}, + {"2618", "Windows 10 22H2 v1 (19045.2965)"}, + {"3113", "Windows 11 24H2 (26100.1742)"}, + {"3114", "Windows 11 24H2 Home China (26100.1742)"}, + {"3115", "Windows 11 24H2 Pro China (26100.1742)"}, + {"3131", "Windows 11 Arm64 24H2 (26100.1742)"}, + {"3132", "Windows 11 Arm64 24H2 Home China (26100.1742)"}, + {"3133", "Windows 11 Arm64 24H2 Pro China (26100.1742)"}, + {"3262", "Windows 11 25H2 (26200.6584)"}, + {"3263", "Windows 11 25H2 Home China (26200.6584)"}, + {"3264", "Windows 11 25H2 Pro China (26200.6584)"}, + {"3265", "Windows 11 Arm64 25H2 (26200.6584)"}, + {"3266", "Windows 11 Arm64 25H2 Home China (26200.6584)"}, + {"3267", "Windows 11 Arm64 25H2 Pro China (26200.6584)"}, + {"3321", "Windows 11 25H2 (Updated Oct)"}, + {"3324", "Windows 11 Arm64 25H2 (Updated Oct)"}, +} + +var evalProducts = []EvalProduct{ + {"server-2025", "Windows Server 2025", "https://www.microsoft.com/en-us/evalcenter/download-windows-server-2025"}, + {"server-2022", "Windows Server 2022", "https://www.microsoft.com/en-us/evalcenter/download-windows-server-2022"}, + {"server-2019", "Windows Server 2019", "https://www.microsoft.com/en-us/evalcenter/download-windows-server-2019"}, + {"server-2016", "Windows Server 2016", "https://www.microsoft.com/en-us/evalcenter/download-windows-server-2016"}, + {"win11-ent", "Windows 11 Enterprise", "https://www.microsoft.com/en-us/evalcenter/download-windows-11-enterprise"}, +} + +func findProductByID(id string) (Product, bool) { + for _, p := range consumerProducts { + if p.ID == id { + return p, true + } + } + return Product{}, false +} + +func searchProducts(query string) []Product { + words := strings.Fields(strings.ToLower(query)) + if len(words) == 0 { + return consumerProducts + } + var results []Product + for _, p := range consumerProducts { + name := strings.ToLower(p.Name) + match := true + for _, w := range words { + if !strings.Contains(name, w) { + match = false + break + } + } + if match { + results = append(results, p) + } + } + return results +} + +func findEvalProduct(slug string) (EvalProduct, bool) { + for _, p := range evalProducts { + if p.Slug == slug { + return p, true + } + } + return EvalProduct{}, false +} diff --git a/cli/catalog_test.go b/cli/catalog_test.go new file mode 100644 index 0000000..fa316dc --- /dev/null +++ b/cli/catalog_test.go @@ -0,0 +1,58 @@ +package main + +import "testing" + +func TestFindProductByID_found(t *testing.T) { + p, ok := findProductByID("3262") + if !ok { + t.Fatal("expected product 3262 to exist") + } + if p.ID != "3262" { + t.Errorf("got ID %s, want 3262", p.ID) + } +} + +func TestFindProductByID_notFound(t *testing.T) { + _, ok := findProductByID("9999") + if ok { + t.Fatal("expected product 9999 to not exist") + } +} + +func TestSearchProducts_match(t *testing.T) { + results := searchProducts("windows 11 25h2") + if len(results) == 0 { + t.Fatal("expected at least one result for 'windows 11 25h2'") + } +} + +func TestSearchProducts_noMatch(t *testing.T) { + results := searchProducts("zzznomatch") + if len(results) != 0 { + t.Errorf("expected no results, got %d", len(results)) + } +} + +func TestSearchProducts_caseInsensitive(t *testing.T) { + results := searchProducts("WINDOWS 11") + if len(results) == 0 { + t.Fatal("expected results for uppercase query") + } +} + +func TestFindEvalProduct_found(t *testing.T) { + p, ok := findEvalProduct("server-2025") + if !ok { + t.Fatal("expected server-2025 to exist") + } + if p.Slug != "server-2025" { + t.Errorf("got slug %s, want server-2025", p.Slug) + } +} + +func TestFindEvalProduct_notFound(t *testing.T) { + _, ok := findEvalProduct("zzz-nope") + if ok { + t.Fatal("expected zzz-nope to not exist") + } +}