cities = new ArrayList<>();
@@ -18,24 +16,34 @@ public class TravelService {
* @throws IllegalArgumentException if city already exists
*/
public void add(CityInfo cityInfo) {
- // do something
+ if (cities.stream().anyMatch(city -> city.equals(cityInfo))) {
+ throw new IllegalArgumentException("This city already added");
+ }
+ cities.add(cityInfo);
}
/**
* remove city info.
*
- * @param cityName - city name
+ * @param cityInfo - city name
* @throws IllegalArgumentException if city doesn't exist
+ *
+ * ИСПРАВИЛ НА CITYINFO входной параметр! Могут существовать несколько городов с одним названием. Paris например штук 6.
*/
- public void remove(String cityName) {
- // do something
+ public void remove(CityInfo cityInfo) {
+ List cityToRemove = cities.stream().filter(city -> city.equals(cityInfo)).toList();
+ if (cityToRemove.isEmpty()) {
+ throw new IllegalArgumentException(String.format("City %s not found", cityInfo.getName()));
+ }
+ cities.removeAll(cityToRemove);
}
/**
* Get cities names.
*/
public List citiesNames() {
- return null;
+ return cities.stream()
+ .map(CityInfo::getName).toList();
}
/**
@@ -46,8 +54,17 @@ public List citiesNames() {
* @param destCityName - destination city
* @throws IllegalArgumentException if source or destination city doesn't exist.
*/
- public int getDistance(String srcCityName, String destCityName) {
- return 0;
+ public double getDistance(CityInfo srcCityName, CityInfo destCityName) {
+
+ double lat1 = srcCityName.getPosition().getLatitude();
+ double lon1 = srcCityName.getPosition().getLongitude();
+ double lat2 = destCityName.getPosition().getLatitude();
+ double lon2 = destCityName.getPosition().getLongitude();
+ double dlon = lon2 - lon1;
+ double dlat = lat2 - lat1;
+ double a = Math.pow(Math.sin(dlat / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon / 2), 2);
+ double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+ return EARTH_RADIUS_KM * c;
}
/**
@@ -57,7 +74,20 @@ public int getDistance(String srcCityName, String destCityName) {
* @param radius - radius in kilometers for search
* @throws IllegalArgumentException if city with cityName city doesn't exist.
*/
- public List getCitiesNear(String cityName, int radius) {
- return null;
+ public List getCitiesNear(CityInfo cityName, double radius) {
+ List targetCity = cities.stream()
+ .filter(city -> {
+ double distance = getDistance(city, cityName);
+ return distance < radius;
+ })
+ .toList();
+
+ if (targetCity.isEmpty()) {
+ throw new IllegalArgumentException("Вокруг нет городов в радиусе " + radius);
+
+ } else {
+ return targetCity;
+ }
}
+
}
diff --git a/module05/src/test/java/ru/sberbank/edu/AppTest.java b/module05/src/test/java/ru/sberbank/edu/AppTest.java
deleted file mode 100644
index 895d735c..00000000
--- a/module05/src/test/java/ru/sberbank/edu/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package ru.sberbank.edu;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}
diff --git a/module05/src/test/java/ru/sberbank/edu/CityInfoTest.java b/module05/src/test/java/ru/sberbank/edu/CityInfoTest.java
new file mode 100644
index 00000000..9bd85cb3
--- /dev/null
+++ b/module05/src/test/java/ru/sberbank/edu/CityInfoTest.java
@@ -0,0 +1,57 @@
+package ru.sberbank.edu;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+public class CityInfoTest {
+
+ @Test
+ public void testGetName() {
+ CityInfo cityInfo = new CityInfo("CityName", new GeoPosition("55(01'01'')", "55(45'47'')"));
+
+ assertEquals("CityName", cityInfo.getName());
+ }
+
+ @Test
+ public void testGetPosition() {
+ CityInfo cityInfo = new CityInfo("CityName", new GeoPosition("55(01'01'')", "55(45'47'')"));
+
+ assertEquals(0.960226824942358, cityInfo.getPosition().getLatitude());
+ assertEquals(0.9732489204169602, cityInfo.getPosition().getLongitude());
+ }
+
+ @Test
+ public void testToString() {
+ CityInfo cityInfo = new CityInfo("CityName", new GeoPosition("55(01'01'')", "55(45'47'')"));
+
+ String expected = "CityInfo{name='CityName', position=GeoPosition{latitude=0.960226824942358, longitude=0.9732489204169602}}";
+ assertEquals(expected, cityInfo.toString());
+ }
+
+ @Test
+ public void testEquals() {
+ CityInfo cityInfo1 = new CityInfo("CityName", new GeoPosition("55(01'01'')", "55(45'47'')"));
+ CityInfo cityInfo2 = new CityInfo("CityName", new GeoPosition("55(01'01'')", "55(45'47'')"));
+
+ assertEquals(cityInfo2, cityInfo1);
+ }
+
+ @Test
+ public void testEqualsWithDifferentName() {
+ CityInfo cityInfo1 = new CityInfo("CityName", new GeoPosition("55(01'01'')", "55(45'47'')"));
+ CityInfo cityInfo2 = new CityInfo("CityName ", new GeoPosition("55(01'01'')", "55(45'47'')"));
+
+ assertNotEquals(cityInfo2, cityInfo1);
+ }
+
+ @Test
+ public void testEqualsWithDifferentLatitude() {
+ CityInfo cityInfo1 = new CityInfo("CityName", new GeoPosition("55(01'00'')", "55(45'47'')"));
+ CityInfo cityInfo2 = new CityInfo("CityName", new GeoPosition("55(01'01'')", "55(45'47'')"));
+
+ assertNotEquals(cityInfo2, cityInfo1);
+ }
+
+}
diff --git a/module05/src/test/java/ru/sberbank/edu/GeoPositionTest.java b/module05/src/test/java/ru/sberbank/edu/GeoPositionTest.java
new file mode 100644
index 00000000..5d2b6972
--- /dev/null
+++ b/module05/src/test/java/ru/sberbank/edu/GeoPositionTest.java
@@ -0,0 +1,45 @@
+package ru.sberbank.edu;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class GeoPositionTest {
+
+ @Test
+ public void testGetLatitude() {
+ GeoPosition geoPosition = new GeoPosition("10.5", "20.5");
+
+ assertEquals(0.1832595714594046, geoPosition.getLatitude());
+ }
+
+ @Test
+ public void testGetLongitude() {
+ GeoPosition geoPosition = new GeoPosition("10.5", "20.5");
+
+ assertEquals(0.35779249665883756, geoPosition.getLongitude());
+ }
+
+ @Test
+ public void testToString() {
+ GeoPosition geoPosition = new GeoPosition("10.5", "20.5");
+
+ String expected = "GeoPosition{latitude=0.1832595714594046, longitude=0.35779249665883756}";
+ assertEquals(expected, geoPosition.toString());
+ }
+
+ @Test
+ public void testGetLatitudeWithSecs() {
+ GeoPosition geoPosition = new GeoPosition("55(01'01'')", "55(45'47'')");
+
+ assertEquals(0.960226824942358, geoPosition.getLatitude());
+ }
+
+ @Test
+ public void testGetLongitudeWithSecs() {
+ GeoPosition geoPosition = new GeoPosition("55(01'01'')", "55(45'47'')");
+
+ assertEquals(0.9732489204169602, geoPosition.getLongitude());
+ }
+
+}
diff --git a/module05/src/test/java/ru/sberbank/edu/TravelServiceTest.java b/module05/src/test/java/ru/sberbank/edu/TravelServiceTest.java
new file mode 100644
index 00000000..6bb3858f
--- /dev/null
+++ b/module05/src/test/java/ru/sberbank/edu/TravelServiceTest.java
@@ -0,0 +1,99 @@
+package ru.sberbank.edu;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class TravelServiceTest {
+
+ TravelService travelService;
+
+ @BeforeEach
+ public void setUp() {
+ travelService = new TravelService();
+
+ CityInfo moscow = new CityInfo();
+ moscow.setName("Moscow");
+ moscow.setPosition(new GeoPosition("55(01'01'')", "55(01'01'')"));
+
+ CityInfo saintPetersburg = new CityInfo();
+ saintPetersburg.setName("Saint Petersburg");
+ saintPetersburg.setPosition(new GeoPosition("75(01'01'')", "75(01'01'')"));
+
+ travelService.add(moscow);
+ travelService.add(saintPetersburg);
+ }
+
+ @Test
+ public void addCity_AlreadyExists_ThrowsException() {
+ CityInfo city = new CityInfo();
+ city.setName("Moscow");
+ city.setPosition(new GeoPosition("55(01'01'')", "55(01'01'')"));
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> travelService.add(city));
+ }
+
+ @Test
+ public void removeCity_NotFound_ThrowsException() {
+ CityInfo city = new CityInfo();
+ city.setName("Berlin");
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> travelService.remove(city));
+ }
+
+ @Test
+ public void removeCity_Successful_NoException() {
+ CityInfo moscow = new CityInfo();
+ moscow.setName("Moscow");
+ moscow.setPosition(new GeoPosition("55(01'01'')", "55(01'01'')"));
+ Assertions.assertDoesNotThrow(() -> travelService.remove(moscow));
+ }
+
+ @Test
+ public void citiesNames_ReturnsCorrectCitiesList() {
+ List cityNames = travelService.citiesNames();
+
+ Assertions.assertTrue(cityNames.contains("Moscow"));
+ Assertions.assertTrue(cityNames.contains("Saint Petersburg"));
+ assertEquals(2, cityNames.size());
+ }
+
+ @Test
+ public void getDistance_BetweenTwoCities_ReturnsCorrectDistance() {
+ CityInfo moscow = new CityInfo();
+ moscow.setName("Moscow");
+ moscow.setPosition(new GeoPosition("55(01'01'')", "55(01'01'')"));
+
+ CityInfo saintPetersburg = new CityInfo();
+ saintPetersburg.setName("Saint Petersburg");
+ saintPetersburg.setPosition(new GeoPosition("75(01'01'')", "75(01'01'')"));
+
+ double distance = travelService.getDistance(moscow, saintPetersburg);
+
+ assertEquals(2384.844535114297, distance);
+ }
+
+ @Test
+ public void getCitiesNear_WithinRadius_ReturnsCorrectListOfCities() {
+ CityInfo city = new CityInfo();
+ city.setName("city");
+ city.setPosition(new GeoPosition("55(01'01'')", "55(01'01'')"));
+
+ List nearbyCities = travelService.getCitiesNear(city, 100000);
+
+ assertEquals(nearbyCities.size(), 2);
+ }
+
+ @Test
+ public void getCitiesNear_NoCitiesWithinRadius_ThrowsException() {
+ CityInfo city = new CityInfo();
+ city.setName("city");
+ city.setPosition(new GeoPosition("99(01'01'')", "99(01'01'')"));
+
+ Assertions.assertThrows(IllegalArgumentException.class, () -> travelService.getCitiesNear(city, 10.0));
+ }
+}
\ No newline at end of file
diff --git a/module06/src/main/java/ru/sberbank/edu/repository/CarDbRepositoryImpl.java b/module06/src/main/java/ru/sberbank/edu/repository/CarDbRepositoryImpl.java
index 0a7a2d25..2cfefac4 100644
--- a/module06/src/main/java/ru/sberbank/edu/repository/CarDbRepositoryImpl.java
+++ b/module06/src/main/java/ru/sberbank/edu/repository/CarDbRepositoryImpl.java
@@ -3,27 +3,36 @@
import ru.sberbank.edu.model.Car;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
+import java.sql.*;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.Optional;
+import java.util.Set;
public class CarDbRepositoryImpl implements CarRepository {
private final Connection connection;
- private static final String CREATE_CAR_SQL = "INSERT INTO car (id, model) VALUES (?,?)";
- private static final String UPDATE_CAR_SQL = "UPDATE car SET model = ? WHERE id = ?";
- private static final String SELECT_CAR_BY_ID = "SELECT * FROM car WHERE id = ?";
+ public static final String CREATE_CAR_SQL = "INSERT INTO car (id, model) VALUES (?,?)";
+ public static final String UPDATE_CAR_SQL = "UPDATE car SET model = ? WHERE id = ?";
+ public static final String SELECT_CAR_BY_ID = "SELECT * FROM car WHERE id = ?";
+ public static final String DELETE_CAR_BY_ID = "DELETE FROM car WHERE id = ?";
+ public static final String DELETE_ALL_CARS = "DELETE FROM car";
+ public static final String FIND_ALL_CARS = "SELECT * FROM car";
+ public static final String SELECT_CAR_BY_MODEL = "SELECT * FROM car WHERE model = ?";
+ public static final String COUNT_ROWS_BY_ID = "SELECT COUNT(*) FROM car where id = ?";
private final PreparedStatement createPreStmt;
private final PreparedStatement updatePreStmt;
private final PreparedStatement findByIdPreStmt;
+ private final PreparedStatement deleteByIdPreStmt;
+ private final PreparedStatement findByModelPreStmt;
public CarDbRepositoryImpl(Connection connection) throws SQLException {
this.connection = connection;
this.createPreStmt = connection.prepareStatement(CREATE_CAR_SQL);
this.updatePreStmt = connection.prepareStatement(UPDATE_CAR_SQL);
this.findByIdPreStmt = connection.prepareStatement(SELECT_CAR_BY_ID);
+ this.deleteByIdPreStmt = connection.prepareStatement(DELETE_CAR_BY_ID);
+ this.findByModelPreStmt = connection.prepareStatement(SELECT_CAR_BY_MODEL);
}
@Override
@@ -41,6 +50,37 @@ public Car createOrUpdate(Car car) throws SQLException {
return car;
}
+ @Override
+ public Set createAll(Collection cars) {
+ cars
+ .forEach(car->{
+ try {
+ createPreStmt.setString(1,car.getId());
+ createPreStmt.setString(2, car.getModel());
+ createPreStmt.executeUpdate();
+ } catch (SQLException throwables) {
+ throwables.printStackTrace();
+ }
+
+ });
+ return new HashSet<>(cars);
+ }
+
+ @Override
+ public Set findAll() {
+ Set cars = new HashSet<>();
+ try(Statement statement = connection.createStatement();
+ ResultSet resultSet= statement.executeQuery(FIND_ALL_CARS)){
+ String id = resultSet.getString("id");
+ String model = resultSet.getString("model");
+ Car car = new Car(id,model);
+ cars.add(car);
+ } catch (SQLException throwables) {
+ throwables.printStackTrace();
+ }
+ return cars;
+ }
+
@Override
public Optional findById(String id) throws SQLException {
// validation
@@ -61,11 +101,27 @@ public Optional findById(String id) throws SQLException {
@Override
public Boolean deleteById(String id) {
- return null;
+ try {
+ deleteByIdPreStmt.setString(1, id);
+ deleteByIdPreStmt.executeUpdate();
+ return true;
+ } catch (SQLException e){
+ return false;
+ }
+ }
+
+ @Override
+ public Boolean deleteAll() {
+ try(Statement statement = connection.createStatement()){
+ statement.executeUpdate(DELETE_ALL_CARS);
+ return true;
+ }catch (SQLException e){
+ return false;
+ }
}
private int countRowsById(String id) throws SQLException {
- PreparedStatement preparedStatement = connection.prepareStatement("SELECT COUNT(*) FROM car where id = ?");
+ PreparedStatement preparedStatement = connection.prepareStatement(COUNT_ROWS_BY_ID);
preparedStatement.setString(1, id);
ResultSet resultSet = preparedStatement.executeQuery();
int rowCount = 0;
@@ -74,4 +130,25 @@ private int countRowsById(String id) throws SQLException {
}
return rowCount;
}
+
+ @Override
+ public Set findByModel(String model) {
+ Set cars = new HashSet<>();
+ try {
+ findByModelPreStmt.setString(1, model);
+ ResultSet resultSet = findByModelPreStmt.executeQuery();
+ while (resultSet.next()) {
+ String id = resultSet.getString("id");
+ Car car = new Car(id, model);
+ cars.add(car);
+ }
+ resultSet.close();
+ } catch (SQLException e){
+ throw new RuntimeException(e);
+ }
+ return cars;
+ }
+
+
+
}
diff --git a/module06/src/main/java/ru/sberbank/edu/service/CarServiceImpl.java b/module06/src/main/java/ru/sberbank/edu/service/CarServiceImpl.java
index e5eb91b4..d4f916c2 100644
--- a/module06/src/main/java/ru/sberbank/edu/service/CarServiceImpl.java
+++ b/module06/src/main/java/ru/sberbank/edu/service/CarServiceImpl.java
@@ -26,6 +26,11 @@ public void editModel(String id, String newModel) throws SQLException {
updateCarModel(car, newModel);
}
+ @Override
+ public void deleteCar(String id) {
+ carRepository.deleteById(id);
+ }
+
private void updateCarModel(Car car, String newModel) {
car.setModel(newModel);
try {
diff --git a/module06/src/test/java/ru/sberbank/edu/AppTest.java b/module06/src/test/java/ru/sberbank/edu/AppTest.java
deleted file mode 100644
index 895d735c..00000000
--- a/module06/src/test/java/ru/sberbank/edu/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package ru.sberbank.edu;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}
diff --git a/module06/src/test/java/ru/sberbank/edu/CarDbRepositoryImplTest.java b/module06/src/test/java/ru/sberbank/edu/CarDbRepositoryImplTest.java
new file mode 100644
index 00000000..1a991414
--- /dev/null
+++ b/module06/src/test/java/ru/sberbank/edu/CarDbRepositoryImplTest.java
@@ -0,0 +1,127 @@
+package ru.sberbank.edu;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import ru.sberbank.edu.model.Car;
+import ru.sberbank.edu.repository.CarDbRepositoryImpl;
+
+import java.sql.*;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import static ru.sberbank.edu.repository.CarDbRepositoryImpl.*;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+public class CarDbRepositoryImplTest {
+
+ @Mock
+ private Connection connection;
+
+ @Mock
+ private PreparedStatement createPreStmt;
+ @Mock
+ private PreparedStatement statement;
+ @Mock
+ private PreparedStatement deleteByIdPreStmt;
+ @Mock
+ private PreparedStatement findByModelPreStmt;
+
+ @Mock
+ private ResultSet resultSet;
+
+ private CarDbRepositoryImpl carDbRepositoryImpl;
+
+ @BeforeEach
+ void setUp() throws SQLException {
+ when(connection.prepareStatement(CREATE_CAR_SQL)).thenReturn(createPreStmt);
+ when(connection.createStatement()).thenReturn(statement);
+ when(statement.executeQuery(anyString())).thenReturn(resultSet);
+ when(connection.prepareStatement(DELETE_CAR_BY_ID)).thenReturn(deleteByIdPreStmt);
+ when(connection.prepareStatement(SELECT_CAR_BY_MODEL)).thenReturn(findByModelPreStmt);
+ carDbRepositoryImpl = new CarDbRepositoryImpl(connection);
+ }
+ @Test
+ void testCreateAll() throws SQLException {
+ Car car = new Car("1", "ModelX");
+ Set cars = Collections.singleton(car);
+ Set result = carDbRepositoryImpl.createAll(cars);
+ verify(createPreStmt, times(1)).executeUpdate();
+ assertEquals(cars, result);
+ }
+ @Test
+ void testFindAll() throws SQLException {
+ // Arrange
+ Car car = new Car("1", "ModelX");
+ when(resultSet.next()).thenReturn(true).thenReturn(false);
+ when(resultSet.getString("id")).thenReturn(car.getId());
+ when(resultSet.getString("model")).thenReturn(car.getModel());
+ Set expectedCars = Collections.singleton(car);
+
+
+ Set result = carDbRepositoryImpl.findAll();
+
+
+ verify(statement, times(1)).executeQuery(CarDbRepositoryImpl.FIND_ALL_CARS);
+ assertEquals(expectedCars, result);
+ }
+ @Test
+ public void testDeleteByIdSuccess() throws SQLException {
+ String id = "someId";
+ when(deleteByIdPreStmt.executeUpdate()).thenReturn(1); //
+ boolean result = carDbRepositoryImpl.deleteById(id);
+ assertTrue(result);
+ verify(deleteByIdPreStmt).setString(1, id); //
+ verify(deleteByIdPreStmt).executeUpdate();
+ }
+ @Test
+ public void testDeleteAllSuccess() throws SQLException {
+ Statement statement = mock(Statement.class);
+ when(connection.createStatement()).thenReturn(statement);
+ when(statement.executeUpdate(DELETE_ALL_CARS)).thenReturn(1);
+ boolean result = carDbRepositoryImpl.deleteAll();
+ assertTrue(result);
+ verify(statement).executeUpdate(anyString());
+ }
+ @Test
+ public void whenFindByModel_thenReturnsSetOfCars() throws SQLException {
+ // Arrange
+ String model = "TestModel";
+ when(findByModelPreStmt.executeQuery()).thenReturn(resultSet);
+ when(resultSet.next()).thenReturn(true, true, false); // Возвращаем два автомобиля и затем завершаем итерацию
+ when(resultSet.getString("id")).thenReturn("1", "2");
+
+ // Act
+ Set result = carDbRepositoryImpl.findByModel(model);
+
+ // Assert
+ assertNotNull(result);
+ assertEquals(2, result.size());
+ assertTrue(result.stream().anyMatch(car -> car.getId().equals("1")));
+ assertTrue(result.stream().anyMatch(car -> car.getId().equals("2")));
+ verify(findByModelPreStmt, times(1)).setString(1, model); // Проверяем, что setString вызывался один раз с корректными параметрами
+ verify(findByModelPreStmt, times(1)).executeQuery(); // Проверяем, что executeQuery вызывался ровно один раз
+ verify(resultSet, atLeastOnce()).close(); // Проверяем, что resultSet был закрыт
+ }
+
+ @Test
+ public void whenFindByModelAndSQLException_thenThrowsRuntimeException() throws SQLException {
+ // Arrange
+ String model = "TestModel";
+ when(findByModelPreStmt.executeQuery()).thenThrow(new SQLException());
+
+ // Act and Assert
+ assertThrows(RuntimeException.class, () -> carDbRepositoryImpl.findByModel(model));
+ }
+
+
+}
\ No newline at end of file
diff --git a/module07/src/main/java/ru/sberbank/edu/WeatherCache.java b/module07/src/main/java/ru/sberbank/edu/WeatherCache.java
index e0a2d02b..cb5e4e01 100644
--- a/module07/src/main/java/ru/sberbank/edu/WeatherCache.java
+++ b/module07/src/main/java/ru/sberbank/edu/WeatherCache.java
@@ -1,40 +1,30 @@
package ru.sberbank.edu;
+import java.time.LocalDateTime;
import java.util.HashMap;
-import java.util.Map;
+
public class WeatherCache {
- private final Map cache = new HashMap<>();
+ private static final int EXPIRY_DURATION_MINUTES = 5;
private final WeatherProvider weatherProvider;
+ private final HashMap cache = new HashMap<>();
- /**
- * Constructor.
- *
- * @param weatherProvider - weather provider
- */
public WeatherCache(WeatherProvider weatherProvider) {
this.weatherProvider = weatherProvider;
}
- /**
- * Get ACTUAL weather info for current city or null if current city not found.
- * If cache doesn't contain weather info OR contains NOT ACTUAL info then we should download info
- * If you download weather info then you should set expiry time now() plus 5 minutes.
- * If you can't download weather info then remove weather info for current city from cache.
- *
- * @param city - city
- * @return actual weather info
- */
- public WeatherInfo getWeatherInfo(String city) {
- // should be implemented
- return null;
+ public synchronized WeatherInfo getWeatherInfo(String city) {
+ WeatherInfo info = cache.get(city);
+ if (info == null || info.getExpiryTime().isBefore(LocalDateTime.now())) {
+ info = weatherProvider.get(city);
+ info.setExpiryTime(LocalDateTime.now().plusMinutes(EXPIRY_DURATION_MINUTES));
+ cache.put(city, info);
+ }
+ return info;
}
- /**
- * Remove weather info from cache.
- **/
- public void removeWeatherInfo(String city) {
- // should be implemented
+ public synchronized void removeWeatherInfo(String city) {
+ cache.remove(city);
}
}
diff --git a/module07/src/main/java/ru/sberbank/edu/WeatherInfo.java b/module07/src/main/java/ru/sberbank/edu/WeatherInfo.java
index 9fcee430..651257d6 100644
--- a/module07/src/main/java/ru/sberbank/edu/WeatherInfo.java
+++ b/module07/src/main/java/ru/sberbank/edu/WeatherInfo.java
@@ -5,42 +5,75 @@
public class WeatherInfo {
private String city;
-
- /**
- * Short weather description
- * Like 'sunny', 'clouds', 'raining', etc
- */
private String shortDescription;
-
- /**
- * Weather description.
- * Like 'broken clouds', 'heavy raining', etc
- */
private String description;
-
- /**
- * Temperature.
- */
private double temperature;
-
- /**
- * Temperature that fells like.
- */
private double feelsLikeTemperature;
-
- /**
- * Wind speed.
- */
private double windSpeed;
-
- /**
- * Pressure.
- */
private double pressure;
-
- /**
- * Expiry time of weather info.
- * If current time is above expiry time then current weather info is not actual!
- */
private LocalDateTime expiryTime;
+
+ public String getCity() {
+ return city;
+ }
+
+ public String getShortDescription() {
+ return shortDescription;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public double getTemperature() {
+ return temperature;
+ }
+
+ public double getFeelsLikeTemperature() {
+ return feelsLikeTemperature;
+ }
+
+ public double getWindSpeed() {
+ return windSpeed;
+ }
+
+ public double getPressure() {
+ return pressure;
+ }
+
+ public LocalDateTime getExpiryTime() {
+ return expiryTime;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public void setShortDescription(String shortDescription) {
+ this.shortDescription = shortDescription;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public void setTemperature(double temperature) {
+ this.temperature = temperature;
+ }
+
+ public void setFeelsLikeTemperature(double feelsLikeTemperature) {
+ this.feelsLikeTemperature = feelsLikeTemperature;
+ }
+
+ public void setWindSpeed(double windSpeed) {
+ this.windSpeed = windSpeed;
+ }
+
+ public void setPressure(double pressure) {
+ this.pressure = pressure;
+ }
+
+ public void setExpiryTime(LocalDateTime expiryTime) {
+ this.expiryTime = expiryTime;
+ }
}
diff --git a/module07/src/main/java/ru/sberbank/edu/WeatherProvider.java b/module07/src/main/java/ru/sberbank/edu/WeatherProvider.java
index 5fc6d989..947e48c9 100644
--- a/module07/src/main/java/ru/sberbank/edu/WeatherProvider.java
+++ b/module07/src/main/java/ru/sberbank/edu/WeatherProvider.java
@@ -1,18 +1,14 @@
package ru.sberbank.edu;
-public class WeatherProvider {
- // private RestTemplate restTemplate = null;
+import org.springframework.web.client.RestTemplate;
+
+public class WeatherProvider {
+ private final RestTemplate restTemplate = new RestTemplate();
+ private static final String API_URL = "http://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}";
+ private static final String API_KEY = "your_api_key_here";
- /**
- * Download ACTUAL weather info from internet.
- * You should call GET http://api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}
- * You should use Spring Rest Template for calling requests
- *
- * @param city - city
- * @return weather info or null
- */
public WeatherInfo get(String city) {
- return null;
+ return restTemplate.getForObject(API_URL, WeatherInfo.class, city, API_KEY);
}
}
diff --git a/module07/src/test/java/ru/sberbank/edu/AppTest.java b/module07/src/test/java/ru/sberbank/edu/AppTest.java
index 895d735c..10c2a471 100644
--- a/module07/src/test/java/ru/sberbank/edu/AppTest.java
+++ b/module07/src/test/java/ru/sberbank/edu/AppTest.java
@@ -1,38 +1,10 @@
package ru.sberbank.edu;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
+
/**
* Unit test for simple App.
*/
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
+public class AppTest {
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
}
diff --git a/module08/pom.xml b/module08/pom.xml
index 5ab321fb..c6f08af2 100644
--- a/module08/pom.xml
+++ b/module08/pom.xml
@@ -24,5 +24,10 @@
3.8.1
test
+
+ org.mortbay.jetty
+ servlet-api
+ 2.5-20081211
+
diff --git a/module08/src/main/java/ru/sberbank/edu/FinancialServlet.java b/module08/src/main/java/ru/sberbank/edu/FinancialServlet.java
index f012968f..f3d68c09 100644
--- a/module08/src/main/java/ru/sberbank/edu/FinancialServlet.java
+++ b/module08/src/main/java/ru/sberbank/edu/FinancialServlet.java
@@ -1,13 +1,53 @@
package ru.sberbank.edu;
-/**
- * Hello world!
- *
- */
-public class FinancialServlet
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+
+public class FinancialServlet extends HttpServlet
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ out.println("");
+ out.println("Расчет доходности вклада
");
+ out.println("");
+ out.println("");
+ }
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ try {
+ double sum = Double.parseDouble(request.getParameter("sum"));
+ double percentage = Double.parseDouble(request.getParameter("percentage"));
+ int years = Integer.parseInt(request.getParameter("years"));
+
+ double finalAmount = sum * Math.pow(1 + (percentage / 100), years);
+ out.println("");
+ out.println("Результат расчета доходности вклада
");
+ out.println("Итоговая сумма после " + years + " лет: " + finalAmount + "
");
+ out.println("");
+ } catch (NumberFormatException e) {
+ out.println("");
+ out.println("Ошибка ввода данных
");
+ out.println("Пожалуйста, введите корректные данные.
");
+ out.println("");
+ } finally {
+ out.close();
+ }
+ }
}
diff --git a/module08/src/main/webapp/WEB-INF/web.xml b/module08/src/main/webapp/WEB-INF/web.xml
index f70f3c67..dbc41f39 100644
--- a/module08/src/main/webapp/WEB-INF/web.xml
+++ b/module08/src/main/webapp/WEB-INF/web.xml
@@ -1,7 +1,15 @@
-
+
-
- Archetype Created Web Application
-
+
+ FinancialServlet
+ ru.sberbank.edu.FinancialServlet
+
+
+
+ FinancialServlet
+ /finance
+
+
+
\ No newline at end of file
diff --git a/module08/src/main/webapp/author.html b/module08/src/main/webapp/author.html
new file mode 100644
index 00000000..35480ab5
--- /dev/null
+++ b/module08/src/main/webapp/author.html
@@ -0,0 +1,22 @@
+
+
+
+
+ Автор работы
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/module08/src/main/webapp/index.html b/module08/src/main/webapp/index.html
new file mode 100644
index 00000000..37ffc3c7
--- /dev/null
+++ b/module08/src/main/webapp/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+ Car market - ГАЗ-24
+
+
+
+
+
+Автомобиль ГАЗ-24
+
+
+Технические характеристики
+
+ - Размеры: длина х ширина х высота
+ - Колея: передняя/задняя
+ - Ширина передней/задней колеи
+ - Размер колес
+
+
+Варианты исполнения
+
+ - Седан
+ - Универсал
+ - Пикап
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/module08/src/main/webapp/style.css b/module08/src/main/webapp/style.css
new file mode 100644
index 00000000..d89bea53
--- /dev/null
+++ b/module08/src/main/webapp/style.css
@@ -0,0 +1,33 @@
+body {
+ font-family: Arial, sans-serif;
+}
+
+header, .author-section, footer {
+ margin: 20px;
+ padding: 10px;
+}
+
+header p, .author-section h2, footer button, footer a {
+ text-align: center;
+}
+
+img {
+ display: block;
+ margin: 0 auto;
+ width: 300px;
+ height: auto;
+}
+
+.author-info p {
+ text-align: left;
+ margin-left: 20px;
+}
+
+button {
+ display: block;
+ margin: 0 auto;
+}
+
+footer {
+ margin-top: 20px;
+}
\ No newline at end of file
diff --git a/module09/pom.xml b/module09/pom.xml
index 59059ad5..1417f541 100644
--- a/module09/pom.xml
+++ b/module09/pom.xml
@@ -15,5 +15,24 @@
UTF-8
+
+
+ org.springframework
+ spring-context
+ 3.0.2.RELEASE
+ compile
+
+
+ org.springframework
+ spring-web
+ 3.0.2.RELEASE
+ compile
+
+
+ cglib
+ cglib-nodep
+ 3.0
+
+
diff --git a/module09/src/main/java/ru/sberbank/edu/App.java b/module09/src/main/java/ru/sberbank/edu/App.java
index 5419c026..3d39a220 100644
--- a/module09/src/main/java/ru/sberbank/edu/App.java
+++ b/module09/src/main/java/ru/sberbank/edu/App.java
@@ -1,13 +1,20 @@
package ru.sberbank.edu;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
/**
* Hello world!
*
*/
-public class App
+public class App
{
- public static void main( String[] args )
- {
- System.out.println( "Hello World!" );
+ public static void main(String[] args) {
+ ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
+
+ WeatherCache cache = context.getBean(WeatherCache.class);
+
+ WeatherInfo weatherInfo = cache.getWeatherInfo("OMSK");
+ System.out.println("GOOD! weather=" + weatherInfo);
}
}
diff --git a/module09/src/main/java/ru/sberbank/edu/AppConfig.java b/module09/src/main/java/ru/sberbank/edu/AppConfig.java
new file mode 100644
index 00000000..494d1a22
--- /dev/null
+++ b/module09/src/main/java/ru/sberbank/edu/AppConfig.java
@@ -0,0 +1,15 @@
+package ru.sberbank.edu;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class AppConfig {
+
+ @Bean
+ public RestTemplate restTemplate() {
+ return new RestTemplate();
+ }
+
+}
\ No newline at end of file
diff --git a/module09/src/main/java/ru/sberbank/edu/WeatherCache.java b/module09/src/main/java/ru/sberbank/edu/WeatherCache.java
index 3f236f72..7102f17e 100644
--- a/module09/src/main/java/ru/sberbank/edu/WeatherCache.java
+++ b/module09/src/main/java/ru/sberbank/edu/WeatherCache.java
@@ -1,40 +1,35 @@
package ru.sberbank.edu;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.time.LocalDateTime;
import java.util.HashMap;
-import java.util.Map;
+
/**
* Weather cache.
*/
public class WeatherCache {
- private final Map cache = new HashMap<>();
- private WeatherProvider weatherProvider;
-
- /**
- * Default constructor.
- */
- public WeatherCache() {
+ private static final int EXPIRY_DURATION_MINUTES = 5;
+ private final WeatherProvider weatherProvider;
+ private final HashMap cache = new HashMap<>();
+ @Autowired
+ public WeatherCache(WeatherProvider weatherProvider) {
+ this.weatherProvider = weatherProvider;
}
- /**
- * Get ACTUAL weather info for current city or null if current city not found.
- * If cache doesn't contain weather info OR contains NOT ACTUAL info then we should download info
- * If you download weather info then you should set expiry time now() plus 5 minutes.
- * If you can't download weather info then remove weather info for current city from cache.
- *
- * @param city - city
- * @return actual weather info
- */
- public WeatherInfo getWeatherInfo(String city) {
- // should be implemented
- return null;
+ public synchronized WeatherInfo getWeatherInfo(String city) {
+ WeatherInfo info = cache.get(city);
+ if (info == null || info.getExpiryTime().isBefore(LocalDateTime.now())) {
+ info = weatherProvider.get(city);
+ info.setExpiryTime(LocalDateTime.now().plusMinutes(EXPIRY_DURATION_MINUTES));
+ cache.put(city, info);
+ }
+ return info;
}
- /**
- * Remove weather info from cache.
- **/
- public void removeWeatherInfo(String city) {
- // should be implemented
+ public synchronized void removeWeatherInfo(String city) {
+ cache.remove(city);
}
}
\ No newline at end of file
diff --git a/module09/src/main/java/ru/sberbank/edu/WeatherInfo.java b/module09/src/main/java/ru/sberbank/edu/WeatherInfo.java
index 06d81ffc..4f72caa1 100644
--- a/module09/src/main/java/ru/sberbank/edu/WeatherInfo.java
+++ b/module09/src/main/java/ru/sberbank/edu/WeatherInfo.java
@@ -8,42 +8,75 @@
public class WeatherInfo {
private String city;
-
- /**
- * Short weather description
- * Like 'sunny', 'clouds', 'raining', etc
- */
private String shortDescription;
-
- /**
- * Weather description.
- * Like 'broken clouds', 'heavy raining', etc
- */
private String description;
-
- /**
- * Temperature.
- */
private double temperature;
-
- /**
- * Temperature that fells like.
- */
private double feelsLikeTemperature;
-
- /**
- * Wind speed.
- */
private double windSpeed;
-
- /**
- * Pressure.
- */
private double pressure;
-
- /**
- * Expiry time of weather info.
- * If current time is above expiry time then current weather info is not actual!
- */
private LocalDateTime expiryTime;
+
+ public String getCity() {
+ return city;
+ }
+
+ public String getShortDescription() {
+ return shortDescription;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public double getTemperature() {
+ return temperature;
+ }
+
+ public double getFeelsLikeTemperature() {
+ return feelsLikeTemperature;
+ }
+
+ public double getWindSpeed() {
+ return windSpeed;
+ }
+
+ public double getPressure() {
+ return pressure;
+ }
+
+ public LocalDateTime getExpiryTime() {
+ return expiryTime;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public void setShortDescription(String shortDescription) {
+ this.shortDescription = shortDescription;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public void setTemperature(double temperature) {
+ this.temperature = temperature;
+ }
+
+ public void setFeelsLikeTemperature(double feelsLikeTemperature) {
+ this.feelsLikeTemperature = feelsLikeTemperature;
+ }
+
+ public void setWindSpeed(double windSpeed) {
+ this.windSpeed = windSpeed;
+ }
+
+ public void setPressure(double pressure) {
+ this.pressure = pressure;
+ }
+
+ public void setExpiryTime(LocalDateTime expiryTime) {
+ this.expiryTime = expiryTime;
+ }
}
diff --git a/module09/src/main/java/ru/sberbank/edu/WeatherProvider.java b/module09/src/main/java/ru/sberbank/edu/WeatherProvider.java
index 02a2fb68..50132f42 100644
--- a/module09/src/main/java/ru/sberbank/edu/WeatherProvider.java
+++ b/module09/src/main/java/ru/sberbank/edu/WeatherProvider.java
@@ -3,20 +3,27 @@
/**
* Weather provider
*/
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+@Service
public class WeatherProvider {
+ private final RestTemplate restTemplate;
+
+ @Value("${app.apiurl}")
+ private String apiUrl;
+
+ @Value("${app.apikey}")
+ private String apiKey;
+
+ @Autowired
+ public WeatherProvider(RestTemplate restTemplate) {
+ this.restTemplate = restTemplate;
+ }
-// private RestTemplate restTemplate;
-// private String appKey;
- /**
- * Download ACTUAL weather info from internet.
- * You should call GET http://api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}
- * You should use Spring Rest Template for calling requests
- *
- * @param city - city
- * @return weather info or null
- */
public WeatherInfo get(String city) {
- return null;
+ return restTemplate.getForObject(apiUrl, WeatherInfo.class, city, apiKey);
}
}
diff --git a/module09/src/main/resources/app.properties b/module09/src/main/resources/app.properties
new file mode 100644
index 00000000..a13e24ce
--- /dev/null
+++ b/module09/src/main/resources/app.properties
@@ -0,0 +1,2 @@
+app.apiurl="http://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}"
+app.apikey="43bb1e9d7e177b6ff0681feb9647b8d4"
\ No newline at end of file
diff --git a/module10/pom.xml b/module10/pom.xml
index 96f5c1b2..e80c6b06 100644
--- a/module10/pom.xml
+++ b/module10/pom.xml
@@ -4,6 +4,7 @@
homework-javareboot-2023-group-06
ru.sberbank.edu
1.0-SNAPSHOT
+
4.0.0
@@ -16,4 +17,26 @@
UTF-8