1// Copyright 2015 Brian J. Downs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package openweathermap
16
17import (
18	"net/http"
19	"os"
20	"reflect"
21	"testing"
22	"time"
23)
24
25var forecastRange = []int{3, 7, 10}
26
27// TestNewForecast will make sure the a new instance of Forecast is returned
28func TestNewForecast(t *testing.T) {
29	t.Parallel()
30
31	for d := range DataUnits {
32		t.Logf("Data unit: %s", d)
33
34		if ValidDataUnit(d) {
35			c5, err := NewForecast("5", d, "ru", os.Getenv("OWM_API_KEY"))
36			if err != nil {
37				t.Error(err)
38			}
39
40			if reflect.TypeOf(c5).String() != "*openweathermap.ForecastWeatherData" {
41				t.Error("incorrect data type returned")
42			}
43
44			c16, err := NewForecast("16", d, "ru", os.Getenv("OWM_API_KEY"))
45			if err != nil {
46				t.Error(err)
47			}
48
49			if reflect.TypeOf(c16).String() != "*openweathermap.ForecastWeatherData" {
50				t.Error("incorrect data type returned")
51			}
52		} else {
53			t.Errorf("unusable data unit - %s", d)
54		}
55	}
56
57	_, err := NewForecast("", "asdf", "en", os.Getenv("OWM_API_KEY"))
58	if err == nil {
59		t.Error("created instance when it shouldn't have")
60	}
61}
62
63// TestNewForecastWithCustomHttpClient will verify that a new instance of ForecastWeatherData
64// is created with custom http client
65func TestNewForecastWithCustomHttpClient(t *testing.T) {
66
67	hc := http.DefaultClient
68	hc.Timeout = time.Duration(1) * time.Second
69	f, err := NewForecast("5", "c", "en", os.Getenv("OWM_API_KEY"), WithHttpClient(hc))
70	if err != nil {
71		t.Error(err)
72	}
73
74	if reflect.TypeOf(f).String() != "*openweathermap.ForecastWeatherData" {
75		t.Error("incorrect data type returned")
76	}
77
78	// expected := time.Duration(1) * time.Second
79	// if f.client.Timeout != expected {
80	// 	t.Errorf("Expected Duration %v, but got %v", expected, f.client.Timeout)
81	// }
82}
83
84// TestNewForecastWithInvalidOptions will verify that returns an error with
85// invalid option
86func TestNewForecastWithInvalidOptions(t *testing.T) {
87
88	optionsPattern := [][]Option{
89		{nil},
90		{nil, nil},
91		{WithHttpClient(&http.Client{}), nil},
92		{nil, WithHttpClient(&http.Client{})},
93	}
94
95	for _, options := range optionsPattern {
96		c, err := NewForecast("5", "c", "en", os.Getenv("OWM_API_KEY"), options...)
97		if err == errInvalidOption {
98			t.Logf("Received expected invalid option error. message: %s", err.Error())
99		} else if err != nil {
100			t.Errorf("Expected %v, but got %v", errInvalidOption, err)
101		}
102		if c != nil {
103			t.Errorf("Expected nil, but got %v", c)
104		}
105	}
106}
107
108// TestNewForecastWithCustomHttpClient will verify that returns an error with
109// invalid http client
110func TestNewForecastWithInvalidHttpClient(t *testing.T) {
111
112	f, err := NewForecast("5", "c", "en", os.Getenv("OWM_API_KEY"), WithHttpClient(nil))
113	if err == errInvalidHttpClient {
114		t.Logf("Received expected bad client error. message: %s", err.Error())
115	} else if err != nil {
116		t.Errorf("Expected %v, but got %v", errInvalidHttpClient, err)
117	}
118	if f != nil {
119		t.Errorf("Expected nil, but got %v", f)
120	}
121}
122
123// TestDailyByName will verify that a daily forecast can be retrieved for
124// a given named location
125func TestDailyByName(t *testing.T) {
126	t.Parallel()
127
128	f, err := NewForecast("5", "f", "fi", os.Getenv("OWM_API_KEY"))
129	if err != nil {
130		t.Error(err)
131	}
132
133	for _, d := range forecastRange {
134		err = f.DailyByName("Dubai", d)
135		if err != nil {
136			t.Error(err)
137		}
138	}
139}
140
141// TestDailyByCooridinates will verify that a daily forecast can be retrieved
142// for a given set of coordinates
143func TestDailyByCoordinates(t *testing.T) {
144	t.Parallel()
145
146	f, err := NewForecast("5", "f", "PL", os.Getenv("OWM_API_KEY"))
147	if err != nil {
148		t.Error(err)
149	}
150
151	for _, d := range forecastRange {
152		err = f.DailyByCoordinates(
153			&Coordinates{
154				Longitude: -112.07,
155				Latitude:  33.45,
156			}, d,
157		)
158		if err != nil {
159			t.Error(err)
160		}
161	}
162}
163
164// TestDailyByID will verify that a daily forecast can be retrieved for a
165// given location ID
166func TestDailyByID(t *testing.T) {
167	t.Parallel()
168
169	f, err := NewForecast("5", "c", "fr", os.Getenv("OWM_API_KEY"))
170	if err != nil {
171		t.Error(err)
172	}
173
174	for _, d := range forecastRange {
175		err = f.DailyByID(524901, d)
176		if err != nil {
177			t.Error(err)
178		}
179	}
180}
181