feat(cli): product catalog with word-based search
This commit is contained in:
parent
9a860022fd
commit
86f9b685de
2 changed files with 140 additions and 0 deletions
82
cli/catalog.go
Normal file
82
cli/catalog.go
Normal file
|
|
@ -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
|
||||
}
|
||||
58
cli/catalog_test.go
Normal file
58
cli/catalog_test.go
Normal file
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue