Repository: JanDeDobbeleer/oh-my-posh
Pull request #3883 (2023-05-20 05:17:13)

feat: Update Open Weather Map to use Geocoding API
Updated the Open Weather Map Current Weather URL to remove the deprecated query parameter. Updated the URL to add the supported latitude and longitude parameters.

Added a call to the Open Wetaher Map Geocoding API to resolve the location parameter to latitude and longitude values as specified in the Open Weather Map documentation.

Added properties to the Open Weather Map segment to allow users to manually specify the latitude and longitude if desired. Doing this will skip the geocoding API call and ignore the location parameter.

Updated the website documentation for the Open Weather Map segment to reflect the property changes and explain how to use them.

### Prerequisites

- [x] I have read and understood the [contributing guide][CONTRIBUTING.md]
- [x] The commit message follows the [conventional commits][cc] guidelines
- [x] Tests for the changes have been added (for bug fixes/features)
- [x] Docs have been added/updated (for bug fixes/features)

### Description

<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 0a7f642</samp>

This pull request enhances the Owm segment to allow users to specify the location for the weather information by latitude and longitude, and uses the Open Weather Map geocoding API to resolve the location name if provided. It also updates the tests and the documentation to reflect the new functionality.

### How

<!--
copilot:walkthrough
-->
### <samp>🤖 Generated by Copilot at 0a7f642</samp>

* Add two new properties, `Latitude` and `Longitude`, to the `segments` package to specify the location for the Open Weather Map API request ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-f3466da260bee7c26f73ce616c897cbbd74feea39e1005bfbd08d24ce4b30660R31-R34))
* Modify the `getResult` function in `owm.go` to use the `Latitude` and `Longitude` properties if they are valid, or to use the `Location` property and the Open Weather Map geocoding API otherwise ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-f3466da260bee7c26f73ce616c897cbbd74feea39e1005bfbd08d24ce4b30660L79-R110))
* Update the URL format for the weather API to use the latitude and longitude parameters instead of the query parameter ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-f3466da260bee7c26f73ce616c897cbbd74feea39e1005bfbd08d24ce4b30660L79-R110), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL182-R242), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL209-R266), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL243-R297), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL253-R307), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL267-R321))
* Define a new struct, `geoLocation`, to hold the latitude and longitude values returned by the Open Weather Map geocoding API ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-f3466da260bee7c26f73ce616c897cbbd74feea39e1005bfbd08d24ce4b30660R55-R59))
* Update the `TestOWMSegmentSingle` function in `owm_test.go` to include the new properties and the geocoding API URL in the test cases ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL15-R115))
* Add two new test cases to `TestOWMSegmentSingle` to check the behavior when `Latitude` and `Longitude` are specified and when `Location` is omitted ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL15-R115))
* Update the `TestOWMSegmentIcons`, `TestOWMSegmentFromCache`, and `TestOWMSegmentFromCacheWithHyperlink` functions in `owm_test.go` to include the geocoding API URL and response in the mock environment ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL182-R242), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL209-R266), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL243-R297), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL253-R307), [link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-180913b484d7703a273da972bc99c79268f443077bff1ba4f301a78af30020eaL267-R321))
* Update the documentation for the `Owm` segment in `owm.mdx` to include the new properties and the explanation of how to specify the location ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-a201377cc6b05439129794f496695fe474856daa7a2a0cdaa3056442ad903140L38-R52))
* Add a new section for Specifying Location in `owm.mdx` ([link](https://github.com/JanDeDobbeleer/oh-my-posh/pull/3883/files?diff=unified&w=0#diff-a201377cc6b05439129794f496695fe474856daa7a2a0cdaa3056442ad903140L38-R52))

<!---

Tips:

If you're not comfortable with working with Git,
we're working a guide (https://ohmyposh.dev/docs/contributing_git) to help you out.
Oh My Posh advises GitKraken (https://www.gitkraken.com/invite/nQmDPR9D) as your preferred cross platform Git GUI power tool.

-->

[CONTRIBUTING.md]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/CONTRIBUTING.md
[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/segments/owm.go b/src/segments/owm.go
index 584552b5..7a2967c1 100644
--- a/src/segments/owm.go
+++ b/src/segments/owm.go
@@ -28,6 +28,10 @@ const (
 	Location properties.Property = "location"
 	// Units openweathermap units
 	Units properties.Property = "units"
+	// Latitude for the location used in place of location
+	Latitude properties.Property = "latitude"
+	// Longitude for the location used in place of location
+	Longitude properties.Property = "longitude"
 	// CacheKeyResponse key used when caching the response
 	CacheKeyResponse string = "owm_response"
 	// CacheKeyURL key used when caching the url responsible for the response
@@ -48,9 +52,20 @@ type owmDataResponse struct {
 	temperature `json:"main"`
 }
 
+type geoLocation struct {
+	Lat float64 `json:"lat"`
+	Lon float64 `json:"lon"`
+}
+
 func (d *Owm) Enabled() bool {
 	err := d.setStatus()
-	return err == nil
+
+	if err != nil {
+		d.env.Error(err)
+		return false
+	}
+
+	return true
 }
 
 func (d *Owm) Template() string {
@@ -76,9 +91,41 @@ func (d *Owm) getResult() (*owmDataResponse, error) {
 
 	apikey := d.props.GetString(APIKey, ".")
 	location := d.props.GetString(Location, "De Bilt,NL")
+	latitude := d.props.GetFloat64(Latitude, 91)    // This default value is intentionally invalid since there should not be a default for this and 0 is a valid value
+	longitude := d.props.GetFloat64(Longitude, 181) // This default value is intentionally invalid since there should not be a default for this and 0 is a valid value
 	units := d.props.GetString(Units, "standard")
 	httpTimeout := d.props.GetInt(properties.HTTPTimeout, properties.DefaultHTTPTimeout)
-	d.URL = fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?q=%s&units=%s&appid=%s", location, units, apikey)
+
+	validCoordinates := func(latitude, longitude float64) bool {
+		// Latitude values are only valid if they are between -90 and 90
+		// Longitude values are only valid if they are between -180 and 180
+		// https://gisgeography.com/latitude-longitude-coordinates/
+		return latitude <= 90 && latitude >= -90 && longitude <= 180 && longitude >= -180
+	}
+
+	if !validCoordinates(latitude, longitude) {
+		var geoResponse []geoLocation
+		geocodingURL := fmt.Sprintf("http://api.openweathermap.org/geo/1.0/direct?q=%s&limit=1&appid=%s", location, apikey)
+
+		body, err := d.env.HTTPRequest(geocodingURL, nil, httpTimeout)
+		if err != nil {
+			return new(owmDataResponse), err
+		}
+
+		err = json.Unmarshal(body, &geoResponse)
+		if err != nil {
+			return new(owmDataResponse), err
+		}
+
+		if len(geoResponse) == 0 {
+			return new(owmDataResponse), fmt.Errorf("no coordinates found for %s", location)
+		}
+
+		latitude = geoResponse[0].Lat
+		longitude = geoResponse[0].Lon
+	}
+
+	d.URL = fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?lat=%v&lon=%v&units=%s&appid=%s", latitude, longitude, units, apikey)
 
 	body, err := d.env.HTTPRequest(d.URL, nil, httpTimeout)
 	if err != nil {
@@ -99,13 +146,16 @@ func (d *Owm) getResult() (*owmDataResponse, error) {
 
 func (d *Owm) setStatus() error {
 	units := d.props.GetString(Units, "standard")
+
 	q, err := d.getResult()
 	if err != nil {
 		return err
 	}
+
 	if len(q.Data) == 0 {
 		return errors.New("No data found")
 	}
+
 	id := q.Data[0].TypeID
 
 	d.Temperature = int(math.Round(q.temperature.Value))
diff --git a/website/docs/segments/owm.mdx b/website/docs/segments/owm.mdx
index 05e5a49d..305263ec 100644
--- a/website/docs/segments/owm.mdx
+++ b/website/docs/segments/owm.mdx
@@ -35,14 +35,20 @@ import Config from '@site/src/components/Config.js';
 
 ## Properties
 
-| Name            | Type     | Description                                                                                                                                                                                                        |
-| --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `apikey`        | `string` | Your API key from [Open Weather Map][owm]                                                                                                                                                                          |
-| `location`      | `string` | The requested location. Formatted as <City,STATE,COUNTRY_CODE>. City name, state code and country code divided by comma. Please, refer to ISO 3166 for the state codes or country codes - defaults to `DE BILT,NL` |
-| `units`         | `string` | Units of measurement. Available values are standard (kelvin), metric (celsius), and imperial (fahrenheit) - defaults to `standard`                                                                                 |
-| `http_timeout`  | `int`    | The default timeout for http request is 20ms.                                                                                                                                                                      |
-| `cache_timeout` | `int`    | The default timeout for request caching is 10m. A value of 0 disables the cache.                                                                                                                                   |
-| `template`      | `string` | A go [text/template][go-text-template] template extended with [sprig][sprig] utilizing the properties below - defaults to `{{.Weather}} ({{.Temperature}}{{.UnitIcon}})`                                           |
+| Name            | Type      | Description                                                                                                                                                                                                        |
+| --------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `apikey`        | `string`  | Your API key from [Open Weather Map][owm]                                                                                                                                                                          |
+| `latitude`      | `float64` | The latitude of the requested location.                                                                                                                                                                            |
+| `longitude`     | `float64` | The longitude of the requested location.                                                                                                                                                                           |
+| `location`      | `string`  | The requested location. Formatted as <City,STATE,COUNTRY_CODE>. City name, state code and country code divided by comma. Please, refer to ISO 3166 for the state codes or country codes - defaults to `DE BILT,NL` |
+| `units`         | `string`  | Units of measurement. Available values are standard (kelvin), metric (celsius), and imperial (fahrenheit) - defaults to `standard`                                                                                 |
+| `http_timeout`  | `int`     | The default timeout for http request is 20ms.                                                                                                                                                                      |
+| `cache_timeout` | `int`     | The default timeout for request caching is 10m. A value of 0 disables the cache.                                                                                                                                   |
+| `template`      | `string`  | A go [text/template][go-text-template] template extended with [sprig][sprig] utilizing the properties below - defaults to `{{.Weather}} ({{.Temperature}}{{.UnitIcon}})`                                           |
+
+### Specifying Location
+
+The given location can either be specified through the Latitude and Longitude properties or through the Location property. If both Latitude and Longitude are specified and valid then Location will be ignored if it is included. If Latitude or Longitude are not specified or are invalid then Location will be used.
 
 ## Template ([info][templates])
 


Test patch:
diff --git a/src/http/oauth_test.go b/src/http/oauth_test.go
index b4dc1460..201007bb 100644
--- a/src/http/oauth_test.go
+++ b/src/http/oauth_test.go
@@ -161,7 +161,7 @@ func TestOauthResult(t *testing.T) {
 		env.On("Cache").Return(cache)
 		env.On("HTTPRequest", url).Return([]byte(tc.JSONResponse), tc.Error)
 		env.On("HTTPRequest", tokenURL).Return([]byte(tc.TokenResponse), tc.Error)
-		env.On("Error", mock2.Anything).Return()
+		env.On("Error", mock2.Anything)
 
 		oauth := &OAuthRequest{
 			AccessTokenKey:  accessTokenKey,
diff --git a/src/segments/owm_test.go b/src/segments/owm_test.go
index 681d431f..fed85fd2 100644
--- a/src/segments/owm_test.go
+++ b/src/segments/owm_test.go
@@ -9,59 +9,112 @@ import (
 	"github.com/jandedobbeleer/oh-my-posh/src/properties"
 
 	"github.com/stretchr/testify/assert"
+	mock2 "github.com/stretchr/testify/mock"
 )
 
 const (
-	OWMAPIURL = "http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key"
+	OWMGEOAPIURL     = "http://api.openweathermap.org/geo/1.0/direct?q=AMSTERDAM,NL&limit=1&appid=key"
+	OWMWEATHERAPIURL = "http://api.openweathermap.org/data/2.5/weather?lat=52.3727598&lon=4.8936041&units=metric&appid=key"
 )
 
 func TestOWMSegmentSingle(t *testing.T) {
 	cases := []struct {
-		Case            string
-		JSONResponse    string
-		ExpectedString  string
-		ExpectedEnabled bool
-		Template        string
-		Error           error
+		Case                string
+		Location            string
+		Latitude            float64
+		Longitude           float64
+		GeoJSONResponse     string
+		WeatherJSONResponse string
+		ExpectedString      string
+		ExpectedEnabled     bool
+		Template            string
+		Error               error
 	}{
 		{
-			Case:            "Sunny Display",
-			JSONResponse:    `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
-			ExpectedString:  "\ue30d (20°C)",
-			ExpectedEnabled: true,
+			Case:                "Sunny Display",
+			Location:            "AMSTERDAM,NL",
+			GeoJSONResponse:     `[{"lat": 52.3727598,"lon": 4.8936041}]`,
+			WeatherJSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
+			ExpectedString:      "\ue30d (20°C)",
+			ExpectedEnabled:     true,
 		},
 		{
-			Case:            "Sunny Display",
-			JSONResponse:    `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
-			ExpectedString:  "\ue30d (20°C)",
-			ExpectedEnabled: true,
-			Template:        "{{.Weather}} ({{.Temperature}}{{.UnitIcon}})",
+			Case:                "Sunny Display",
+			Location:            "AMSTERDAM,NL",
+			GeoJSONResponse:     `[{"lat": 52.3727598,"lon": 4.8936041}]`,
+			WeatherJSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
+			ExpectedString:      "\ue30d (20°C)",
+			ExpectedEnabled:     true,
+			Template:            "{{.Weather}} ({{.Temperature}}{{.UnitIcon}})",
 		},
 		{
-			Case:            "Sunny Display",
-			JSONResponse:    `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
-			ExpectedString:  "\ue30d",
-			ExpectedEnabled: true,
-			Template:        "{{.Weather}} ",
+			Case:                "Sunny Display",
+			Location:            "AMSTERDAM,NL",
+			GeoJSONResponse:     `[{"lat": 52.3727598,"lon": 4.8936041}]`,
+			WeatherJSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
+			ExpectedString:      "\ue30d",
+			ExpectedEnabled:     true,
+			Template:            "{{.Weather}} ",
 		},
 		{
-			Case:            "Error in retrieving data",
-			JSONResponse:    "nonsense",
-			Error:           errors.New("Something went wrong"),
-			ExpectedEnabled: false,
+			Case:                "Config Skip Geocoding Check With Location",
+			Location:            "AMSTERDAM,NL",
+			Latitude:            52.3727598,
+			Longitude:           4.8936041,
+			WeatherJSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
+			ExpectedString:      "\ue30d (20°C)",
+			ExpectedEnabled:     true,
+		},
+		{
+			Case:                "Config Skip Geocoding Check Without Location",
+			Latitude:            52.3727598,
+			Longitude:           4.8936041,
+			WeatherJSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
+			ExpectedString:      "\ue30d (20°C)",
+			ExpectedEnabled:     true,
+		},
+		{
+			Case:                "Error in retrieving data",
+			Location:            "AMSTERDAM,NL",
+			GeoJSONResponse:     "nonsense",
+			WeatherJSONResponse: "nonsense",
+			Error:               errors.New("Something went wrong"),
+			ExpectedEnabled:     false,
 		},
 	}
 
 	for _, tc := range cases {
 		env := &mock.MockedEnvironment{}
-		props := properties.Map{
-			APIKey:                  "key",
-			Location:                "AMSTERDAM,NL",
-			Units:                   "metric",
-			properties.CacheTimeout: 0,
+		var props properties.Map
+		if tc.Latitude != 0 && tc.Longitude != 0 && tc.Location != "" {
+			props = properties.Map{
+				APIKey:                  "key",
+				Location:                tc.Location,
+				Latitude:                tc.Latitude,
+				Longitude:               tc.Longitude,
+				Units:                   "metric",
+				properties.CacheTimeout: 0,
+			}
+		} else if tc.Location != "" {
+			props = properties.Map{
+				APIKey:                  "key",
+				Location:                tc.Location,
+				Units:                   "metric",
+				properties.CacheTimeout: 0,
+			}
+		} else if tc.Latitude != 0 && tc.Longitude != 0 {
+			props = properties.Map{
+				APIKey:                  "key",
+				Latitude:                tc.Latitude,
+				Longitude:               tc.Longitude,
+				Units:                   "metric",
+				properties.CacheTimeout: 0,
+			}
 		}
 
-		env.On("HTTPRequest", OWMAPIURL).Return([]byte(tc.JSONResponse), tc.Error)
+		env.On("HTTPRequest", OWMGEOAPIURL).Return([]byte(tc.GeoJSONResponse), tc.Error)
+		env.On("HTTPRequest", OWMWEATHERAPIURL).Return([]byte(tc.WeatherJSONResponse), tc.Error)
+		env.On("Error", mock2.Anything)
 
 		o := &Owm{
 			props: props,
@@ -179,14 +232,16 @@ func TestOWMSegmentIcons(t *testing.T) {
 			ExpectedIconString: "\ue313",
 		},
 	}
+	geoResponse := `[{"lat": 52.3727598,"lon": 4.8936041}]`
 
 	for _, tc := range cases {
 		env := &mock.MockedEnvironment{}
 
-		response := fmt.Sprintf(`{"weather":[{"icon":"%s"}],"main":{"temp":20.3}}`, tc.IconID)
+		weatherResponse := fmt.Sprintf(`{"weather":[{"icon":"%s"}],"main":{"temp":20.3}}`, tc.IconID)
 		expectedString := fmt.Sprintf("%s (20°C)", tc.ExpectedIconString)
 
-		env.On("HTTPRequest", OWMAPIURL).Return([]byte(response), nil)
+		env.On("HTTPRequest", OWMGEOAPIURL).Return([]byte(geoResponse), nil)
+		env.On("HTTPRequest", OWMWEATHERAPIURL).Return([]byte(weatherResponse), nil)
 
 		o := &Owm{
 			props: properties.Map{
@@ -206,10 +261,11 @@ func TestOWMSegmentIcons(t *testing.T) {
 	for _, tc := range cases {
 		env := &mock.MockedEnvironment{}
 
-		response := fmt.Sprintf(`{"weather":[{"icon":"%s"}],"main":{"temp":20.3}}`, tc.IconID)
-		expectedString := fmt.Sprintf("«%s (20°C)»(http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key)", tc.ExpectedIconString)
+		weatherResponse := fmt.Sprintf(`{"weather":[{"icon":"%s"}],"main":{"temp":20.3}}`, tc.IconID)
+		expectedString := fmt.Sprintf("«%s (20°C)»(http://api.openweathermap.org/data/2.5/weather?lat=52.3727598&lon=4.8936041&units=metric&appid=key)", tc.ExpectedIconString)
 
-		env.On("HTTPRequest", OWMAPIURL).Return([]byte(response), nil)
+		env.On("HTTPRequest", OWMGEOAPIURL).Return([]byte(geoResponse), nil)
+		env.On("HTTPRequest", OWMWEATHERAPIURL).Return([]byte(weatherResponse), nil)
 
 		o := &Owm{
 			props: properties.Map{
@@ -240,7 +296,7 @@ func TestOWMSegmentFromCache(t *testing.T) {
 		env: env,
 	}
 	cache.On("Get", "owm_response").Return(response, true)
-	cache.On("Get", "owm_url").Return("http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key", true)
+	cache.On("Get", "owm_url").Return("http://api.openweathermap.org/data/2.5/weather?lat=52.3727598&lon=4.8936041&units=metric&appid=key", true)
 	cache.On("Set").Return()
 	env.On("Cache").Return(cache)
 
@@ -250,7 +306,7 @@ func TestOWMSegmentFromCache(t *testing.T) {
 
 func TestOWMSegmentFromCacheWithHyperlink(t *testing.T) {
 	response := fmt.Sprintf(`{"weather":[{"icon":"%s"}],"main":{"temp":20}}`, "01d")
-	expectedString := fmt.Sprintf("«%s (20°C)»(http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key)", "\ue30d")
+	expectedString := fmt.Sprintf("«%s (20°C)»(http://api.openweathermap.org/data/2.5/weather?lat=52.3727598&lon=4.8936041&units=metric&appid=key)", "\ue30d")
 
 	env := &mock.MockedEnvironment{}
 	cache := &mock.MockedCache{}
@@ -264,7 +320,7 @@ func TestOWMSegmentFromCacheWithHyperlink(t *testing.T) {
 		env: env,
 	}
 	cache.On("Get", "owm_response").Return(response, true)
-	cache.On("Get", "owm_url").Return("http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key", true)
+	cache.On("Get", "owm_url").Return("http://api.openweathermap.org/data/2.5/weather?lat=52.3727598&lon=4.8936041&units=metric&appid=key", true)
 	cache.On("Set").Return()
 	env.On("Cache").Return(cache)