From 32da6afab89e20d890911516e52f8f8c733c8189 Mon Sep 17 00:00:00 2001 From: Charles Iliya Krempeaux Date: Fri, 11 Aug 2023 16:21:18 -0700 Subject: [PATCH] initial commits --- httpaccept.go | 32 ++++++++ httpaccept_parse_test.go | 164 ++++++++++++++++++++++++++++++++++++++ httpaccept_string_test.go | 26 ++++++ 3 files changed, 222 insertions(+) create mode 100644 httpaccept_parse_test.go diff --git a/httpaccept.go b/httpaccept.go index 0dc85bc..387a091 100644 --- a/httpaccept.go +++ b/httpaccept.go @@ -33,6 +33,38 @@ func Create(mediaranges ...mediarange.MediaRange) HTTPAccept { } } + +// Parse parses a list of strings and returns an HTTPAccept. +// +// For example: +// +// mr, err := mediaaccept.Parse("text/html,application/xhtml+xml, application/xml , image/avif,image/webp, */*") +// +// And: +// +// mr, err := mediaaccept.Parse("image/png,image/gif", "text/html,text/plain", "*/*") +func Parse(headers ...string) (HTTPAccept, error) { + var accepts []mediarange.MediaRange + + for _, header := range headers { + + //@TODO: This is an inefficient way of doing this. + + acceptValues := strings.Split(header, ",") //@TODO: This isn't correct, as per the specification, but it will probably work most of the time. + for _, acceptValue := range acceptValues { + mediaRange, err := mediarange.Parse(acceptValue) + if nil != err { + + return HTTPAccept{}, err + } + + accepts = append(accepts, mediaRange) + } + } + + return Create(accepts...), nil +} + // Negotiate figures out if there is an acceptable media-type, and if there is returns the "best" one. // // For example: diff --git a/httpaccept_parse_test.go b/httpaccept_parse_test.go new file mode 100644 index 0000000..74765f7 --- /dev/null +++ b/httpaccept_parse_test.go @@ -0,0 +1,164 @@ +package httpaccept_test + +import ( + "sourcecode.social/reiver/go-httpaccept" + "sourcecode.social/reiver/go-httpaccept/mediarange" + + "reflect" + + "testing" +) + +func TestParse(t *testing.T) { + + tests := []struct{ + Values []string + Expected httpaccept.HTTPAccept + }{ + { + Values: nil, + Expected: httpaccept.Create(), + }, + { + Values: []string(nil), + Expected: httpaccept.Create(), + }, + { + Values: []string{}, + Expected: httpaccept.Create(), + }, + + + + { + Values: []string{"*/*"}, + Expected: httpaccept.Create(mediarange.Create("*","*")), + }, + + + + { + Values: []string{"text/html"}, + Expected: httpaccept.Create(mediarange.Create("text","html")), + }, + { + Values: []string{"tEXt/HtmL"}, + Expected: httpaccept.Create(mediarange.Create("text","html")), + }, + { + Values: []string{"Text/html"}, + Expected: httpaccept.Create(mediarange.Create("text","html")), + }, + { + Values: []string{"TEXT/html"}, + Expected: httpaccept.Create(mediarange.Create("text","html")), + }, + { + Values: []string{"text/Html"}, + Expected: httpaccept.Create(mediarange.Create("text","html")), + }, + { + Values: []string{"text/HTML"}, + Expected: httpaccept.Create(mediarange.Create("text","html")), + }, + { + Values: []string{"TEXT/HTML"}, + Expected: httpaccept.Create(mediarange.Create("text","html")), + }, + + + + { + Values: []string{"text/html,application/xhtml+xml"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml")), + }, + { + Values: []string{"tEXt/HtmL, APPlication/xhtml+xml"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml")), + }, + { + Values: []string{"Text/html , APPLICATION/xhtml+xml"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml")), + }, + { + Values: []string{"TEXT/html ,appLICATION/xhtml+XML"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml")), + }, + { + Values: []string{"text/Html , application/xhtml+xml"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml")), + }, + { + Values: []string{"text/HTML, application/XHTML+xml"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml")), + }, + { + Values: []string{"TEXT/HTML,APPLICATION/XHTML+XML"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml")), + }, + + + + { + Values: []string{"text/html,application/xhtml+xml", "*/*"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml"),mediarange.Create("*","*")), + }, + { + Values: []string{"tEXt/HtmL, APPlication/xhtml+xml", "*/*"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml"),mediarange.Create("*","*")), + }, + { + Values: []string{"Text/html , APPLICATION/xhtml+xml", "*/*"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml"),mediarange.Create("*","*")), + }, + { + Values: []string{"TEXT/html ,appLICATION/xhtml+XML", "*/*"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml"),mediarange.Create("*","*")), + }, + { + Values: []string{"text/Html , application/xhtml+xml", "*/*"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml"),mediarange.Create("*","*")), + }, + { + Values: []string{"text/HTML, application/XHTML+xml", "*/*"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml"),mediarange.Create("*","*")), + }, + { + Values: []string{"TEXT/HTML,APPLICATION/XHTML+XML", "*/*"}, + Expected: httpaccept.Create(mediarange.Create("text","html"),mediarange.Create("application","xhtml+xml"),mediarange.Create("*","*")), + }, + + + + { + Values: []string{"application/activity+json", "application/json"}, + Expected: httpaccept.Create(mediarange.Create("application","activity+json"),mediarange.Create("application","json")), + }, + { + Values: []string{"application/activity+json", "application/json", "application/*"}, + Expected: httpaccept.Create(mediarange.Create("application","activity+json"),mediarange.Create("application","json"),mediarange.Create("application","*")), + }, + } + + for testNumber, test := range tests { + + actual, err := httpaccept.Parse(test.Values...) + if nil != err { + t.Errorf("For test #%d, did not expect an error but actually got one.", testNumber) + t.Logf("VALUES: %#v", test.Values) + t.Logf("EXPECTED: %q %#v", test.Expected, test.Expected) + t.Logf("ERROR: (%T) %s", err, err) + continue + } + + expected := test.Expected + + if !reflect.DeepEqual(expected, actual) { + t.Errorf("For test #%d, the actual resulting HTTP Accept is not what was expected.", testNumber) + t.Logf("VALUES: %#v", test.Values) + t.Logf("EXPECTED: %q %#v", expected, expected) + t.Logf("ACTUAL: %q %#v", actual, actual) + continue + } + } +} diff --git a/httpaccept_string_test.go b/httpaccept_string_test.go index 52546de..b455da9 100644 --- a/httpaccept_string_test.go +++ b/httpaccept_string_test.go @@ -20,18 +20,44 @@ func TestHTTPAccept_String(t *testing.T) { + { + HTTPAccept: httpaccept.Create(mediarange.Create("", "")), + Expected: "Accept: */*"+"\r\n", + }, { HTTPAccept: httpaccept.Create(mediarange.Create("*", "*")), Expected: "Accept: */*"+"\r\n", }, + + + { HTTPAccept: httpaccept.Create(mediarange.Create("text", "html"), mediarange.Create("*", "*")), Expected: "Accept: text/html,*/*"+"\r\n", }, + { + HTTPAccept: httpaccept.Create(mediarange.Create("Text", "html"), mediarange.Create("*", "*")), + Expected: "Accept: text/html,*/*"+"\r\n", + }, + { + HTTPAccept: httpaccept.Create(mediarange.Create("text", "Html"), mediarange.Create("*", "*")), + Expected: "Accept: text/html,*/*"+"\r\n", + }, + { + HTTPAccept: httpaccept.Create(mediarange.Create("TEXT", "HTML"), mediarange.Create("*", "*")), + Expected: "Accept: text/html,*/*"+"\r\n", + }, + + + { HTTPAccept: httpaccept.Create(mediarange.Create("text", "html"), mediarange.Create("application", "xhtml+xml"), mediarange.Create("*", "*")), Expected: "Accept: text/html,application/xhtml+xml,*/*"+"\r\n", }, + { + HTTPAccept: httpaccept.Create(mediarange.Create("TEXT", "HtmL"), mediarange.Create("APPlication", "XHtmL+XmL"), mediarange.Create("*", "*")), + Expected: "Accept: text/html,application/xhtml+xml,*/*"+"\r\n", + },