Add tests

This commit is contained in:
mmgul562 2023-12-09 12:52:32 +01:00
parent 3445834fa7
commit 72ff399bcd
10 changed files with 397 additions and 113 deletions

View File

@ -2,7 +2,7 @@
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,org.apache.http.impl.client.HttpClients,createDefault" />
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,org.apache.http.impl.client.HttpClients,createDefault,org.mockito.Mockito,mockStatic" />
</inspection_tool>
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ourVersions">

124
.idea/uiDesigner.xml Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

20
README.md Normal file
View File

@ -0,0 +1,20 @@
# Projekt na Pracownię Programowania
____
## Działanie:
1. Po uruchomieniu programu, w konsoli należy podać nazwę miasta, którego pogodę chcemy sprawdzić. Wielkość liter ma znaczenie.
2. Lista obsługiwanych miast znajduje się w pliku `cities.json`.
3. Aby dodać nowe miasto, należy do `cities.json` dopisać:
```
"<nazwa_miasta>": {
"lat": <szerokość_geograficzna>,
"lon": <długość_geograficzna>
}
```
4. Po zakończeniu korzystania z programu, istnieje możliwośc zapisania wyników do pliku *json*, *xml* lub *pdf*.
Zapisane wyniki znajdują się w folderze `src/weather-results`.
## Lista klas i ich działanie:
- **Coordinates** - rekord przechowujący dwie dane: szerokość i długość geograficzną
- **WeatherEntry** - klasa ułatwiająca przechowywanie danych otrzymanych w odpowiedzi API
- **WeatherJsonParser** - klasa pomagająca w serializacji i deserializacji
- **WeatherResponse** - klasa odpowiedzialna za wysyłanie zapytań do API i przechowywanie informacji o odpowiedzi

View File

@ -22,5 +22,13 @@
"Kair": {
"lat": 30.0444,
"lon": 31.2357
},
"Nowy Jork": {
"lat": 40.7128,
"lon": -74.0060
},
"Test": {
"lat": 100.0000,
"lon": 190.0000
}
}

View File

@ -1,14 +1,16 @@
package org.mikgul;
import java.io.IOException;
import java.security.InvalidParameterException;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Map<String, Coordinates> cities;
public static void main(String[] args) throws IOException {
WeatherJsonParser parser = new WeatherJsonParser();
Map<String, Coordinates> cities;
try {
cities = WeatherApp.prepareCities();
cities = parser.prepareCities();
} catch (IOException e) {
System.out.println("Blad przy wczytywaniu danych z `cities.json`: " + e);
return;
@ -21,6 +23,8 @@ public class Main {
// uzytkownik chce wyjsc z programu
if ("q".equalsIgnoreCase(cityName)) {
if (WeatherEntry.noEntries()) break;
System.out.print("Podaj format do zapisu - pdf/json/xml (q - wyjscie bez zapisu):\n>> ");
String format = scanner.nextLine().toLowerCase();
try {
@ -53,11 +57,18 @@ public class Main {
// uzytkownik chce otrzymac dane o podanym miescie
Coordinates coordinates = cities.get(cityName);
if (coordinates != null) {
WeatherEntry entry = WeatherApp.getWeatherData(cityName, coordinates);
WeatherResponse res = new WeatherResponse();
WeatherEntry entry;
try {
entry = parser.parseWeatherData(cityName, res.sendWeatherRequest(coordinates));
} catch(InvalidParameterException e) {
System.out.println("Parsowanie zapytania nie powiodlo sie: " + e + "\n");
continue;
}
System.out.println(entry);
} else {
System.out.println("Podane miasto nie jest obslugiwane (sprawdz plik `cities.json`).\n");
}
}
}
}
}

View File

@ -1,93 +0,0 @@
package org.mikgul;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class WeatherApp {
private static final String API_KEY = "c1a110184e10999b88cc360d8580ef57";
private static final String API_URL = "https://api.openweathermap.org/data/2.5/weather";
public static WeatherEntry getWeatherData(String cityName, Coordinates coordinates) {
String apiUrl = buildApiUrl(coordinates.latitude(), coordinates.longitude());
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
HttpGet request = new HttpGet(apiUrl);
try (CloseableHttpResponse response = httpclient.execute(request)) {
HttpEntity entity = response.getEntity();
return parseWeatherEntry(cityName, entity);
}
} catch (IOException e) {
// Handle exceptions more gracefully, log or rethrow as appropriate
throw new RuntimeException("Error fetching weather data", e);
}
}
private static String buildApiUrl(double latitude, double longitude) {
return String.format("%s?lat=%s&lon=%s&appid=%s&lang=pl&units=metric", API_URL, latitude, longitude, API_KEY);
}
private static WeatherEntry parseWeatherEntry(String cityName, HttpEntity entity) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(entity.getContent());
String desc = rootNode.get("weather").get(0).get("description").asText();
double temp = rootNode.get("main").get("temp").asDouble();
int press = rootNode.get("main").get("pressure").asInt();
int hum = rootNode.get("main").get("humidity").asInt();
return new WeatherEntry(cityName, desc, temp, press, hum);
}
// public static Map<String, Coordinates> prepareCities() throws IOException {
// File jsonFile = new File("cities.json");
// ObjectMapper objectMapper = new ObjectMapper();
// JsonNode rootNode = objectMapper.readTree(jsonFile);
//
// Map<String, Coordinates> citiesMap = new HashMap<>();
//
// Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields();
// while (fields.hasNext()) {
// Map.Entry<String, JsonNode> cityEntry = fields.next();
// String cityName = cityEntry.getKey();
//
// JsonNode coordinatesNode = cityEntry.getValue();
// double latitude = coordinatesNode.get("lat").asDouble();
// double longitude = coordinatesNode.get("lon").asDouble();
//
// Coordinates coordinates = new Coordinates(latitude, longitude);
// citiesMap.put(cityName, coordinates);
// }
// return citiesMap;
// }
public static Map<String, Coordinates> prepareCities() throws IOException {
File jsonFile = new File("cities.json");
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonFile);
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(rootNode.fields(), Spliterator.ORDERED), false)
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> new Coordinates(
entry.getValue().get("lat").asDouble(),
entry.getValue().get("lon").asDouble()
),
(existing, replacement) -> existing,
HashMap::new
));
}
}

View File

@ -102,8 +102,8 @@ public class WeatherEntry {
miasto, pogoda, temperatura, cisnienie, wilgotnosc);
}
public static List<WeatherEntry> getAllEntries() {
return new ArrayList<>(allEntries);
public static boolean noEntries() {
return allEntries.isEmpty();
}
public String getMiasto() {

View File

@ -0,0 +1,56 @@
package org.mikgul;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.security.InvalidParameterException;
import java.util.HashMap;
import java.util.Map;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class WeatherJsonParser {
public WeatherJsonParser() {}
public WeatherEntry parseWeatherData(String cityName, WeatherResponse response) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(response.getBody());
if (response.getStatusCode() != 200){
throw new InvalidParameterException(
rootNode.get("cod").asText()
+ " - "
+ rootNode.get("message").asText()
);
}
String desc = rootNode.get("weather").get(0).get("description").asText();
double temp = rootNode.get("main").get("temp").asDouble();
int press = rootNode.get("main").get("pressure").asInt();
int hum = rootNode.get("main").get("humidity").asInt();
return new WeatherEntry(cityName, desc, temp, press, hum);
}
public Map<String, Coordinates> prepareCities() throws IOException {
File jsonFile = new File("cities.json");
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonFile);
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(rootNode.fields(), Spliterator.ORDERED), false)
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> new Coordinates(
entry.getValue().get("lat").asDouble(),
entry.getValue().get("lon").asDouble()
),
(existing, replacement) -> existing,
HashMap::new
));
}
}

View File

@ -0,0 +1,54 @@
package org.mikgul;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class WeatherResponse {
private static final String API_KEY = "c1a110184e10999b88cc360d8580ef57";
private static final String API_URL = "https://api.openweathermap.org/data/2.5/weather";
private int statusCode;
private String responseBody;
public WeatherResponse() {}
public int getStatusCode() {
return statusCode;
}
public String getBody() {
return responseBody;
}
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
public void setResponseBody(String responseBody) {
this.responseBody = responseBody;
}
public WeatherResponse sendWeatherRequest(Coordinates coordinates) {
String apiUrl = String.format("%s?lat=%s&lon=%s&appid=%s&lang=pl&units=metric",
API_URL, coordinates.latitude(), coordinates.longitude(), API_KEY);
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
HttpGet request = new HttpGet(apiUrl);
try (CloseableHttpResponse response = httpclient.execute(request)) {
HttpEntity entity = response.getEntity();
setStatusCode(response.getStatusLine().getStatusCode());
setResponseBody(EntityUtils.toString(entity));
}
} catch (IOException e) {
throw new RuntimeException("Blad przy wysylaniu zapytania do API: ", e);
}
return this;
}
}

View File

@ -1,22 +1,126 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.junit.jupiter.api.Test;
import org.mikgul.Coordinates;
import org.mikgul.WeatherApp;
import org.mikgul.WeatherEntry;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mikgul.WeatherJsonParser;
import org.mikgul.WeatherResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class WeatherAppTest {
class WeatherAppTest {
private boolean checkLongitude(double longitude) {
return longitude <= 180.00 && longitude >= -180.00;
}
private boolean checkLatitude(double latitude) {
return latitude <= 90.00 && latitude >= -90.00;
}
private WeatherResponse goodResponse(String body) {
WeatherResponse res = new WeatherResponse();
res.setStatusCode(200);
res.setResponseBody(body);
return res;
}
private WeatherResponse badResponse(String message) {
WeatherResponse res = new WeatherResponse();
res.setStatusCode(400);
res.setResponseBody(message);
return res;
}
// ********** TESTY Z POZYTYWNYM SCENARIUSZEM **********
@Test
void testWeatherRequestWithGoodCoordinates() throws IOException {
Coordinates goodCords = new Coordinates(40.7128, -74.0060);
assertTrue(checkLongitude(goodCords.longitude()));
assertTrue(checkLatitude(goodCords.latitude()));
String sampleBody = "{\"weather\":[{\"description\":\"pochmurnie\"}],\"main\":{\"temp\":25.5,\"feels_like\":25.31,\"temp_min\":19.58,\"temp_max\":28.12,\"pressure\":1015,\"humidity\":50}}";
WeatherResponse mockResponse = mock(WeatherResponse.class);
when(mockResponse.sendWeatherRequest(any()))
.thenReturn(goodResponse(sampleBody));
WeatherResponse realResponse = mockResponse.sendWeatherRequest(goodCords);
assertEquals(200, realResponse.getStatusCode());
WeatherJsonParser parser = new WeatherJsonParser();
WeatherEntry result = parser.parseWeatherData("Nowy Jork", realResponse);
assertEquals("Nowy Jork", result.getMiasto());
assertEquals("pochmurnie", result.getPogoda());
assertEquals(25.5, result.getTemperatura());
assertEquals(1015, result.getCisnienie());
assertEquals(50, result.getWilgotnosc());
}
@Test
void testWeatherRequestParsing() throws IOException {
// zakladamy ze zapytanie bylo poprawne a odpowiedz pozytywna, wiec nie sprawdzamy ich 'assertami'
Coordinates cords = new Coordinates(35.6895, 139.6917);
String sampleBody = "{\"weather\":[{\"description\":\"słonecznie\"}],\"main\":{\"temp\":13.5,\"feels_like\":11.21,\"temp_min\":10.58,\"temp_max\":16.12,\"pressure\":1022,\"humidity\":23}}";
WeatherResponse mockResponse = mock(WeatherResponse.class);
when(mockResponse.sendWeatherRequest(any()))
.thenReturn(goodResponse(sampleBody));
WeatherJsonParser parser = new WeatherJsonParser();
WeatherEntry result = parser.parseWeatherData("Tokio", mockResponse.sendWeatherRequest(cords));
assertEquals("Tokio", result.getMiasto());
assertEquals("słonecznie", result.getPogoda());
assertEquals(13.5, result.getTemperatura());
assertEquals(1022, result.getCisnienie());
assertEquals(23, result.getWilgotnosc());
assertEquals("Pogoda w Tokio:\nsłonecznie, temperatura: 13,50 C; cisnienie: 1022 hPa; wilgotnosc: 23%\n",
result.toString());
}
// ********** TESTY Z NEGATYWNYM SCENARIUSZEM **********
@Test
void testWeatherRequestWithBadLongitude() {
Coordinates badCords = new Coordinates(40.7128, -192.0060);
assertFalse(checkLongitude(badCords.longitude()));
assertTrue(checkLatitude(badCords.latitude()));
String message = "{\"cod\":\"400\",\"message\":\"wrong longitude\"}";
WeatherResponse mockResponse = mock(WeatherResponse.class);
when(mockResponse.sendWeatherRequest(any()))
.thenReturn(badResponse(message));
WeatherResponse realResponse = mockResponse.sendWeatherRequest(badCords);
assertEquals(400, realResponse.getStatusCode());
assertEquals("{\"cod\":\"400\",\"message\":\"wrong longitude\"}", realResponse.getBody());
}
@Test
void testWeatherRequestWithBadLatitude() {
Coordinates badCords = new Coordinates(90.7128, -74.0060);
assertTrue(checkLongitude(badCords.longitude()));
assertFalse(checkLatitude(badCords.latitude()));
String message = "{\"cod\":\"400\",\"message\":\"wrong latitude\"}";
WeatherResponse mockResponse = mock(WeatherResponse.class);
when(mockResponse.sendWeatherRequest(any()))
.thenReturn(badResponse(message));
WeatherResponse realResponse = mockResponse.sendWeatherRequest(badCords);
assertEquals(400, realResponse.getStatusCode());
assertEquals("{\"cod\":\"400\",\"message\":\"wrong latitude\"}", realResponse.getBody());
}
}