package httpapi import ( "net/http/httptest" "testing" ) // Сравнение меток слабое, звёздочка совпадает с любой существующей меткой, а // мусор условия не выполняет — и это не отказ: клиент, приславший кривой // заголовок, получает данные, а не `400`. func TestУсловиеЗапроса(t *testing.T) { t.Parallel() const tag = `W/"metrics.gen-7"` cases := []struct { name string header []string tag string want bool }{ {"заголовка нет", nil, tag, false}, {"пустая строка", []string{""}, tag, false}, {"та же метка", []string{tag}, tag, true}, {"та же метка без W/", []string{`"metrics.gen-7"`}, tag, true}, {"чужая метка", []string{`W/"metrics.gen-8"`}, tag, false}, {"метка другого ресурса", []string{`W/"points.gen-7"`}, tag, false}, {"список, метка вторая", []string{`W/"metrics.gen-1", W/"metrics.gen-7"`}, tag, true}, {"две строки заголовка", []string{`W/"metrics.gen-1"`, `W/"metrics.gen-7"`}, tag, true}, {"запятая внутри метки", []string{`W/"points.a,b-7"`}, `W/"points.a,b-7"`, true}, {"метка без закрывающей кавычки", []string{`W/"metrics.gen-7`}, tag, false}, {"звёздочка", []string{"*"}, tag, true}, {"звёздочка без метки", []string{"*"}, "", false}, {"мусор", []string{"metrics.gen-7"}, tag, false}, {"мусор со звёздочкой внутри", []string{`"*"`}, tag, false}, {"метки нет", []string{tag}, "", false}, } for _, c := range cases { if got := notModified(c.header, c.tag); got != c.want { t.Errorf("%s: %v, ждали %v", c.name, got, c.want) } } } // Пустая версия метки не даёт: подписать ответ нечем, и притворяться нельзя. func TestМеткаИзВерсии(t *testing.T) { t.Parallel() if got := etag("metrics", ""); got != "" { t.Errorf("пустая версия дала метку %q", got) } if got := etag("metrics", "gen-7"); got != `W/"metrics.gen-7"` { t.Errorf("метка %q, ждали слабую с областью", got) } if etag("metrics", "gen-7") == etag("points", "gen-7") { t.Error("метки разных ресурсов совпали — 304 отдал бы чужие данные") } } // Подписать нечем — заголовка нет вовсе. Пустой `ETag:` синтаксически невалиден, // и что с ним сделает посредник, не определено ничем. func TestОтветБезВерсииНеНесётМетки(t *testing.T) { t.Parallel() rec := httptest.NewRecorder() setReadHeaders(rec, "") if _, ok := rec.Header()["Etag"]; ok { t.Errorf("ответ без версии несёт метку %q", rec.Header().Get("ETag")) } if got := rec.Header().Get("Cache-Control"); got != "private, no-cache" { t.Errorf("правило кеширования %q — оно не зависит от наличия метки", got) } }