diff --git a/src/config/segment_types.go b/src/config/segment_types.go index b15b1fec..4751999f 100644 --- a/src/config/segment_types.go +++ b/src/config/segment_types.go @@ -104,7 +104,7 @@ const ( // JAVA writes the active java version JAVA SegmentType = "java" // API writes the output of a custom JSON API - JSONAPI SegmentType = "jsonapi" + HTTP SegmentType = "http" // JULIA writes which julia version is currently active JULIA SegmentType = "julia" // KOTLIN writes the active kotlin version @@ -261,7 +261,7 @@ var Segments = map[SegmentType]func() SegmentWriter{ HELM: func() SegmentWriter { return &segments.Helm{} }, IPIFY: func() SegmentWriter { return &segments.IPify{} }, JAVA: func() SegmentWriter { return &segments.Java{} }, - JSONAPI: func() SegmentWriter { return &segments.JSONAPI{} }, + HTTP: func() SegmentWriter { return &segments.HTTP{} }, JULIA: func() SegmentWriter { return &segments.Julia{} }, KOTLIN: func() SegmentWriter { return &segments.Kotlin{} }, KUBECTL: func() SegmentWriter { return &segments.Kubectl{} }, diff --git a/src/segments/http.go b/src/segments/http.go new file mode 100644 index 00000000..a7e6bccf --- /dev/null +++ b/src/segments/http.go @@ -0,0 +1,60 @@ +package segments + +import ( + "encoding/json" + + "net/http" + + "github.com/jandedobbeleer/oh-my-posh/src/properties" +) + +type HTTP struct { + base + + URL string + Result map[string]interface{} +} + +const ( + HTTPURL properties.Property = "url" + METHOD properties.Property = "method" +) + +func (cs *HTTP) Template() string { + return " {{ .Result }} " +} + +func (cs *HTTP) Enabled() bool { + url := cs.props.GetString(HTTPURL, "") + if len(url) == 0 { + return false + } + method := cs.props.GetString(METHOD, "GET") + + result, err := cs.getResult(url, method) + if err != nil { + return false + } + + cs.Result = result + return true +} + +func (cs *HTTP) getResult(url, method string) (map[string]interface{}, error) { + setMethod := func(request *http.Request) { + request.Method = method + } + + resultBody, err := cs.env.HTTPRequest(url, nil, 10000, setMethod) + if err != nil { + return nil, err + } + + var result map[string]interface{} + err = json.Unmarshal(resultBody, &result) + if err != nil { + return nil, err + } + + return result, nil +} diff --git a/src/segments/http_test.go b/src/segments/http_test.go new file mode 100644 index 00000000..72c81d8e --- /dev/null +++ b/src/segments/http_test.go @@ -0,0 +1,111 @@ +package segments + +import ( + "errors" + "testing" + + "github.com/jandedobbeleer/oh-my-posh/src/properties" + "github.com/jandedobbeleer/oh-my-posh/src/runtime/mock" + + "github.com/stretchr/testify/assert" +) + +func TestHTTPSegmentEnabled(t *testing.T) { + cases := []struct { + caseName string + url string + method string + response string + responseID string + isError bool + expected bool + }{ + { + caseName: "Valid URL with GET response", + url: "https://jsonplaceholder.typicode.com/posts/1", + method: "GET", + response: `{"id": "1"}`, + responseID: "1", + isError: false, + expected: true, + }, + { + caseName: "Valid URL with POST response", + url: "https://jsonplaceholder.typicode.com/posts", + method: "POST", + response: `{"id": "101"}`, + responseID: "101", + isError: false, + expected: true, + }, + { + caseName: "Valid URL with error response", + url: "https://api.example.com/data", + method: "GET", + response: ``, + responseID: ``, + isError: true, + expected: false, + }, + { + caseName: "Empty URL", + url: "", + method: "GET", + response: ``, + responseID: ``, + isError: false, + expected: false, + }, + } + + for _, tc := range cases { + t.Run(tc.caseName, func(t *testing.T) { + env := new(mock.Environment) + props := properties.Map{ + URL: tc.url, + METHOD: tc.method, + } + + env.On("HTTPRequest", tc.url).Return([]byte(tc.response), func() error { + if tc.isError { + return errors.New("error") + } + return nil + }()) + + cs := &HTTP{ + base: base{ + env: env, + props: props, + }, + } + + enabled := cs.Enabled() + assert.Equal(t, tc.expected, enabled) + if enabled { + assert.Equal(t, tc.responseID, cs.Result["id"]) + } + }) + } +} + +func TestHTTPSegmentTemplate(t *testing.T) { + env := new(mock.Environment) + props := properties.Map{ + URL: "https://jsonplaceholder.typicode.com/posts/1", + } + + env.On("HTTPRequest", "https://jsonplaceholder.typicode.com/posts/1").Return([]byte(`{"key": "value"}`), nil) + + cs := &HTTP{ + base: base{ + env: env, + props: props, + }, + } + + cs.Enabled() + template := cs.Template() + expectedTemplate := " {{ .Result }} " + assert.Equal(t, expectedTemplate, template) +} diff --git a/src/segments/jsonapi.go b/src/segments/jsonapi.go deleted file mode 100644 index 8d0720d3..00000000 --- a/src/segments/jsonapi.go +++ /dev/null @@ -1,52 +0,0 @@ -package segments - -import ( - "encoding/json" - - "github.com/jandedobbeleer/oh-my-posh/src/properties" -) - -type JSONAPI struct { - base - - URL string - Result map[string]interface{} -} - -const ( - JSONAPIURL properties.Property = "api_url" -) - -func (cs *JSONAPI) Template() string { - return " {{ .Result }} " -} - -func (cs *JSONAPI) Enabled() bool { - url := cs.props.GetString(JSONAPIURL, "") - if len(url) == 0 { - return false - } - - result, err := cs.getResult(url) - if err != nil { - return false - } - - cs.Result = result - return true -} - -func (cs *JSONAPI) getResult(url string) (map[string]interface{}, error) { - body, err := cs.env.HTTPRequest(url, nil, 10000) - if err != nil { - return nil, err - } - - var result map[string]interface{} - err = json.Unmarshal(body, &result) - if err != nil { - return nil, err - } - - return result, nil -} diff --git a/src/segments/jsonapi_test.go b/src/segments/jsonapi_test.go deleted file mode 100644 index e80125eb..00000000 --- a/src/segments/jsonapi_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package segments - -import ( - "errors" - "testing" - - "github.com/jandedobbeleer/oh-my-posh/src/properties" - "github.com/jandedobbeleer/oh-my-posh/src/runtime/mock" - - "github.com/stretchr/testify/assert" -) - -func TestJSONAPISegmentEnabled(t *testing.T) { - cases := []struct { - caseName string - url string - response string - isError bool - expected bool - }{ - { - caseName: "Valid URL with response", - url: "https://jsonplaceholder.typicode.com/posts/1", - response: `{"id": "1"}`, - isError: false, - expected: true, - }, - { - caseName: "Valid URL with error response", - url: "https://api.example.com/data", - response: ``, - isError: true, - expected: false, - }, - { - caseName: "Empty URL", - url: "", - response: ``, - isError: false, - expected: false, - }, - } - - for _, tc := range cases { - t.Run(tc.caseName, func(t *testing.T) { - env := new(mock.Environment) - props := properties.Map{ - JSONAPIURL: tc.url, - } - - env.On("HTTPRequest", tc.url).Return([]byte(tc.response), func() error { - if tc.isError { - return errors.New("error") - } - return nil - }()) - - cs := &JSONAPI{ - base: base{ - env: env, - props: props, - }, - } - - enabled := cs.Enabled() - assert.Equal(t, tc.expected, enabled) - }) - } -} - -func TestJSONAPISegmentTemplate(t *testing.T) { - env := new(mock.Environment) - props := properties.Map{ - JSONAPIURL: "https://jsonplaceholder.typicode.com/posts/1", - } - - env.On("HTTPRequest", "https://jsonplaceholder.typicode.com/posts/1").Return([]byte(`{"key": "value"}`), nil) - - cs := &JSONAPI{ - base: base{ - env: env, - props: props, - }, - } - - cs.Enabled() - template := cs.Template() - expectedTemplate := " {{ .Result }} " - assert.Equal(t, expectedTemplate, template) -} diff --git a/themes/schema.json b/themes/schema.json index 4b71ab95..6001e898 100644 --- a/themes/schema.json +++ b/themes/schema.json @@ -328,8 +328,8 @@ "go", "haskell", "helm", + "http", "ipify", - "jsonapi", "julia", "java", "kotlin", @@ -3741,21 +3741,27 @@ "if": { "properties": { "type": { - "const": "jsonapi" + "const": "http" } } }, "then": { "title": "Display your any JSON property from any API", - "description": "https://ohmyposh.dev/docs/segments/web/jsonapi", + "description": "https://ohmyposh.dev/docs/segments/web/http", "properties": { "properties": { "properties": { - "api_url": { + "url": { "type": "string", - "title": "API URL", - "description": "The JSON API URL", + "title": "URL", + "description": "The HTTP URL", "default": "https://jsonplaceholder.typicode.com/posts/1" + }, + "method": { + "type": "string", + "title": "HTTP method", + "description": "The HTTP method", + "default": "GET" } } } diff --git a/website/docs/segments/web/jsonapi.mdx b/website/docs/segments/web/http.mdx similarity index 55% rename from website/docs/segments/web/jsonapi.mdx rename to website/docs/segments/web/http.mdx index 521a4cdb..c0f928e8 100644 --- a/website/docs/segments/web/jsonapi.mdx +++ b/website/docs/segments/web/http.mdx @@ -1,12 +1,12 @@ --- -id: jsonapi -title: JSON API -sidebar_label: JSON API +id: http +title: HTTP Request +sidebar_label: HTTP Request --- ## What -JSON API is a simple segment to return any json data from any (anonymous) API. +HTTP Request is a simple segment to return any json data from any (anonymous) HTTP call. ## Sample Configuration @@ -14,7 +14,7 @@ import Config from "@site/src/components/Config.js"; ## Properties -| Name | Type | Default | Description | -| --------- | :------: | :--------------------------------------------: | -------------------------------- | -| `api_url` | `string` | `https://jsonplaceholder.typicode.com/posts/1` | The JSON API URL you want to use | +| Name | Type | Default | Description | +| -------- | :------: | :--------------------------------------------: | ----------------------------- | +| `url` | `string` | `https://jsonplaceholder.typicode.com/posts/1` | The HTTP URL you want to call | +| `method` | `string` | `GET` | The HTTP method to use | ## Template ([info][templates]) diff --git a/website/sidebars.js b/website/sidebars.js index a511f263..ab5228ab 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -199,7 +199,7 @@ module.exports = { "segments/web/brewfather", "segments/web/carbonintensity", "segments/web/ipify", - "segments/web/jsonapi", + "segments/web/http", "segments/web/nba", "segments/web/owm", "segments/web/wakatime",