From 5f74bbf608b2a2159841f892e0334fd238216600 Mon Sep 17 00:00:00 2001 From: Tharre Date: Thu, 24 May 2018 02:43:44 +0200 Subject: Fix and cleanup Operation dao+service #25963 --- .../einsatzverwaltung/dao/DBOperationDAO.java | 371 ++++----------------- .../einsatzverwaltung/dao/OperationDAO.java | 2 - .../service/OperationServiceImpl.java | 219 +++++------- .../service/VehicleServiceImpl.java | 7 +- .../einsatzverwaltung/dao/OperationDAOTest.java | 66 +++- .../dao/OperationPersistenceTest.java | 127 ------- .../service/CarAddTestService.java | 281 ---------------- .../service/OperationServiceTest.java | 56 +++- .../service/OperationServiceUnitTest.java | 156 --------- 9 files changed, 272 insertions(+), 1013 deletions(-) delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationPersistenceTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/CarAddTestService.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceUnitTest.java diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java index 070b3fb..0bb25b8 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java @@ -1,18 +1,12 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.lang.invoke.MethodHandles; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -20,143 +14,71 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.util.EnumSet; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Repository; @Repository public class DBOperationDAO implements OperationDAO { private JDBCConnectionManager jdbcConnectionManager; - private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private VehicleDAO vehicleDAO; - public DBOperationDAO(JDBCConnectionManager j) { - jdbcConnectionManager = j; - try { - - getVehicleId = jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE_ID); - - getVehicle = jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE); - - getVehicleVersion = - jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE_VERSION); - - getRegistrations = - jdbcConnectionManager.getConnection().prepareStatement(GET_REGISTRATIONS); + public DBOperationDAO(JDBCConnectionManager jdbcConnectionManager, VehicleDAO vehicleDAO) { + this.jdbcConnectionManager = jdbcConnectionManager; + this.vehicleDAO = vehicleDAO; + } - getEmployee = jdbcConnectionManager.getConnection().prepareStatement(GET_EMPLOYEE); + @Override + public long add(@NonNull Operation o) throws PersistenceException { + String sql = + "INSERT INTO Operation(opCode, severity, created, destination, additionalInfo," + + " status) VALUES (?, ?, ?, ?, ?, ?)"; + String sql2 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)"; + long operationId; - getEmployeeVersion = - jdbcConnectionManager.getConnection().prepareStatement(GET_EMPLOYEE_VERSION); + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setString(1, o.opCode()); + pstmt.setInt(2, o.severity().ordinal()); + pstmt.setTimestamp(3, Timestamp.from(Objects.requireNonNull(o.created()))); + pstmt.setString(4, o.destination()); + pstmt.setString(5, o.additionalInfo()); + pstmt.setInt(6, o.status().ordinal()); + pstmt.executeUpdate(); - } catch (SQLException e) { + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) throw new PersistenceException("Failed to persist operation"); - LOG.error( - "SQLException occurred while preparing Statements. Error message: {} ", - e.getMessage()); + operationId = rs.getLong(1); + } + } - // TODO: nothing should be thrown here - throw new IllegalStateException("TODO: fix me"); - // throw new PersistenceException(e); - } - } + try (PreparedStatement pstmt = con.prepareStatement(sql2)) { + pstmt.setLong(2, operationId); - @Override - public long add(Operation operation) throws PersistenceException { - if (operation == null) { - throw new PersistenceException("Das der Datenbank übergebene Objekt ist fehlerhaft!"); - } - PreparedStatement pstmt = null; - try { - pstmt = - jdbcConnectionManager - .getConnection() - .prepareStatement( - "INSERT INTO operation(opCode, severity, " - + "created, destination, additionalInfo, status) values (?,?,?,?,?,?)", - java.sql.Statement.RETURN_GENERATED_KEYS); - - if (operation.opCode() == null) { - throw new PersistenceException("Code darf nicht null sein!"); - } else if (operation.opCode().length() > 20) - throw new PersistenceException( - "Länge des OP-Codes überschreitet erlaubte Länge von 100 Zeichen!"); - else pstmt.setString(1, operation.opCode()); - /*switch (operation.severity()) { - case A: - pstmt.setInt(2, 0); - break; - case B: - pstmt.setInt(2, 1); - break; - case C: - pstmt.setInt(2, 2); - break; - case D: - pstmt.setInt(2, 3); - break; - case E: - pstmt.setInt(2, 4); - break; - case O: - pstmt.setInt(2, 5); - break; - default: - throw new PersistenceException( - "Schwere des Einsatzes konnte nicht validiert werden!"); - }*/ - pstmt.setString(2, operation.severity().name()); - if (operation.created() != null) { - pstmt.setTimestamp(3, Timestamp.from(Objects.requireNonNull(operation.created()))); - } else { - throw new PersistenceException("Zeitpunkt der Erstellung darf nicht null sein!"); - } + for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { + pstmt.setLong(1, id); + pstmt.addBatch(); + } - if (operation.destination() == null) { - throw new PersistenceException("Einsatzort darf nicht null sein!"); - } else if (operation.destination().length() > 100) { - throw new PersistenceException( - "Länge der Adresse überschreitet erlaubte Länge von 100 Zeichen!"); - } else { - pstmt.setString(4, operation.destination()); - } - if (operation.additionalInfo().length() > 100) - throw new PersistenceException( - "Länge der zusätzlichen Information überschreitet erlaubte Länge von 100 Zeichen!"); - else pstmt.setString(5, operation.additionalInfo()); - if (operation.status() == null) { - throw new PersistenceException("Status darf nicht null sein!"); - } else if (operation.status().toString().length() > 100) { - throw new PersistenceException( - "Länge des Status überschreitet erlaubte Länge von 100 Zeichen!"); - } else { - pstmt.setString(6, operation.status().toString()); + pstmt.executeBatch(); } - pstmt.executeUpdate(); - ResultSet rs = pstmt.getGeneratedKeys(); - if (rs.next()) return rs.getInt(1); - else throw new PersistenceException("Einsatz konnte nicht gespeichert werden"); + con.commit(); + con.setAutoCommit(true); + return operationId; } catch (SQLException e) { throw new PersistenceException(e); - } finally { - if (pstmt != null) { - try { - pstmt.close(); - } catch (SQLException e) { - throw new PersistenceException( - "Verbindung zur Datenbank konnte nicht geschlossen werden!", e); - } - } } } @Override - public void update(Operation o) throws ElementNotFoundException, PersistenceException { + public void update(@NonNull Operation o) throws ElementNotFoundException, PersistenceException { + // Note this will, by design, not update created String sql = "UPDATE Operation SET opCode = ?, severity = ?, destination = ?," + " additionalInfo = ?, status = ? WHERE id = ?"; @@ -175,7 +97,7 @@ public class DBOperationDAO implements OperationDAO { pstmt.setLong(6, o.id()); if (pstmt.executeUpdate() != 1) - throw new ElementNotFoundException("No such operationId exists: " + pstmt); + throw new ElementNotFoundException("No such operationId exists"); } try (PreparedStatement pstmt = con.prepareStatement(sql2)) { @@ -202,19 +124,21 @@ public class DBOperationDAO implements OperationDAO { @Override public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { - if (operationId <= 0) - throw new ElementNotFoundException("Es wurde eine falsche ID übergeben!"); - String sql = "Select * from operation where id = ?"; - try (PreparedStatement pstmt = - jdbcConnectionManager.getConnection().prepareStatement(sql)) { - pstmt.setLong(1, operationId); - pstmt.execute(); - ResultSet rs = pstmt.getResultSet(); - if (rs.next()) { - return operationFromRS(rs); - } else throw new ElementNotFoundException("No element could be found!"); + try { + Connection con = jdbcConnectionManager.getConnection(); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, operationId); + pstmt.execute(); + + try (ResultSet rs = pstmt.getResultSet()) { + if (!rs.next()) + throw new ElementNotFoundException("No such element could be found"); + + return operationFromRS(rs); + } + } } catch (SQLException e) { throw new PersistenceException(e); } @@ -240,7 +164,6 @@ public class DBOperationDAO implements OperationDAO { // Object[] arr = statuses.stream().map(Enum::ordinal).toArray(); // pstmt.setArray(1, con.createArrayOf("INT", arr)); - // TODO: this should set the vehicles as well try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) operations.add(operationFromRS(rs)); } @@ -253,194 +176,42 @@ public class DBOperationDAO implements OperationDAO { } private Operation operationFromRS(ResultSet rs) throws PersistenceException, SQLException { + Long operationId = rs.getLong("id"); + return Operation.builder() - .id(rs.getLong("id")) + .id(operationId) .opCode(rs.getString("opCode")) .severity(Severity.valueOf(rs.getString("severity"))) .status(Status.valueOf(rs.getString("status"))) - .vehicles(getVehiclesFromOperationId(rs.getLong("id"))) + .vehicles(getVehiclesFromOperationId(operationId)) .created(rs.getTimestamp("created").toInstant()) .destination(rs.getString("destination")) .additionalInfo(rs.getString("additionalInfo")) .build(); } - private static final String GET_VEHICLE_ID = - "SELECT vehicleId FROM VehicleOperation WHERE operationId = ? ;"; - - private final PreparedStatement getVehicleId; - private Set getVehiclesFromOperationId(long operationId) throws PersistenceException { + String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?"; Set vehicles = new HashSet<>(); - try { - getVehicleId.setLong(1, operationId); - try (ResultSet resultSet = getVehicleId.executeQuery()) { - while (resultSet.next()) { - vehicles.add(getVehicle(resultSet.getLong("vehicleId"))); - } - } - } catch (SQLException e) { - LOG.error( - "SQLException occurred while getting VehicleId from OperationId. Error message: {}", - e.getMessage()); - throw new PersistenceException(e); - } - return vehicles; - } - - private static String GET_VEHICLE = "SELECT * FROM Vehicle WHERE id = ? ;"; - private final PreparedStatement getVehicle; - - private Vehicle getVehicle(long vehicleId) throws PersistenceException { try { - getVehicle.setLong(1, vehicleId); - try (ResultSet resultSet = getVehicle.executeQuery()) { - resultSet.next(); - return getVehicleVersion( - resultSet.getLong("id"), - resultSet.getLong("version"), - resultSet.getString("status")); - } - } catch (SQLException e) { - LOG.error( - "SQLException occurred while getting Vehicle by id. Error message: {}", - e.getMessage()); - throw new PersistenceException(e); - } - } - - private static String GET_VEHICLE_VERSION = "SELECT * FROM VehicleVersion WHERE id = ? ;"; - - private final PreparedStatement getVehicleVersion; - - private Vehicle getVehicleVersion(long vehicleId, long versionId, String status) - throws PersistenceException { - try { - getVehicleVersion.setLong(1, versionId); - try (ResultSet resultSet = getVehicleVersion.executeQuery()) { - resultSet.next(); - return Vehicle.builder() - .id(vehicleId) - .name(resultSet.getString("name")) - .constructionType( - ConstructionType.valueOf(resultSet.getString("constructionType"))) - .type(VehicleType.valueOf(resultSet.getString("type"))) - .status(Vehicle.Status.valueOf(status)) - .hasNef(resultSet.getBoolean("hasNef")) - .registrations(getRegistrations(vehicleId)) - .build(); - } - } catch (SQLException e) { - LOG.error( - "SQLException occurred while getting VehicleVersion. Error message: {}", - e.getMessage()); - throw new PersistenceException(e); - } - } - - private static String GET_REGISTRATIONS = "SELECT * FROM Registration WHERE id = ? ;"; - - private final PreparedStatement getRegistrations; + Connection con = jdbcConnectionManager.getConnection(); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, operationId); + pstmt.execute(); - private List getRegistrations(long vehicleId) throws PersistenceException { - List registrations = new LinkedList<>(); - try { - getRegistrations.setLong(1, vehicleId); - try (ResultSet resultSet = getRegistrations.executeQuery()) { - while (resultSet.next()) { - long registrationId = resultSet.getLong("id"); - registrations.add( - Registration.builder() - .id(registrationId) - .start(resultSet.getTimestamp("start").toInstant()) - .end(resultSet.getTimestamp("end").toInstant()) - .employee(getEmployee(resultSet.getLong("employeeId"))) - .build()); + try (ResultSet rs = pstmt.getResultSet()) { + while (rs.next()) { + vehicles.add(vehicleDAO.get(rs.getLong("vehicleId"))); + } } } } catch (SQLException e) { - LOG.error( - "SQLException occurred while getting Registration. Error message: {}", - e.getMessage()); - throw new PersistenceException(e); - } - return registrations; - } - - private static String GET_EMPLOYEE = "SELECT version FROM Employee WHERE id = ? ;"; - - private final PreparedStatement getEmployee; - - private Employee getEmployee(long employeeId) throws PersistenceException { - try { - getEmployee.setLong(1, employeeId); - try (ResultSet resultSet = getEmployee.executeQuery()) { - resultSet.next(); - return getEmployeeVersion(employeeId, resultSet.getLong("version")); - } - } catch (SQLException e) { - LOG.error( - "SQLException occurred while getting Employee. Error message: {}", - e.getMessage()); throw new PersistenceException(e); + } catch (ElementNotFoundException e) { + throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e); } - } - - private static String GET_EMPLOYEE_VERSION = "SELECT * FROM EmployeeVersion WHERE id = ? ;"; - private final PreparedStatement getEmployeeVersion; - - private Employee getEmployeeVersion(long employeeId, long versionId) - throws PersistenceException { - try { - getEmployeeVersion.setLong(1, versionId); - try (ResultSet resultSet = getEmployeeVersion.executeQuery()) { - resultSet.next(); - return Employee.builder() - .id(employeeId) - .name(resultSet.getString("name")) - .birthday(resultSet.getDate("birthday").toLocalDate()) - .educationLevel( - EducationLevel.valueOf(resultSet.getString("educationLevel"))) - .isDriver(resultSet.getBoolean("isDriver")) - .isPilot(resultSet.getBoolean("isPilot")) - .build(); - } - } catch (SQLException e) { - LOG.error( - "SQLException occurred while getting EmployeeVersion. Error message: {}", - e.getMessage()); - throw new PersistenceException(e); - } - } - - @Override - public int connectVehicleToOperation(long vehicleID, long operationID) - throws PersistenceException { - PreparedStatement pstmt = null; - try { - pstmt = - jdbcConnectionManager - .getConnection() - .prepareStatement( - "insert into VehicleOperation(vehicleId, operationId)" - + "values (?,?)"); - pstmt.setLong(1, vehicleID); - pstmt.setLong(2, operationID); - pstmt.executeUpdate(); - } catch (SQLException e) { - throw new PersistenceException("Die Werte konnten nicht gespeichert werden!"); - } finally { - if (pstmt != null) { - try { - pstmt.close(); - } catch (SQLException e) { - throw new PersistenceException( - "Verbindung zur Datenbank konnte nicht geschlossen werden!", e); - } - } - } - return 1; + return vehicles; } } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java index da90cc8..d82f768 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java @@ -45,6 +45,4 @@ public interface OperationDAO { * @throws PersistenceException if loading the stored operations failed */ Set list(EnumSet statuses) throws PersistenceException; - - int connectVehicleToOperation(long vehicleID, long operationID) throws PersistenceException; } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java index 74d6457..4663d76 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java @@ -26,10 +26,9 @@ import org.springframework.stereotype.Service; @Service public class OperationServiceImpl implements OperationService { - // TODO: anders? - private OperationDAO operationDAO; private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private final OperationDAO operationDAO; private final VehicleDAO vehicleDAO; public OperationServiceImpl(OperationDAO operationDAO, VehicleDAO vehicleDAO) { @@ -38,91 +37,30 @@ public class OperationServiceImpl implements OperationService { } @Override - public long add(Operation operation) throws InvalidOperationException, ServiceException { - Set vehicles = operation.vehicles(); - boolean rtw = false; - if (faultyInput(operation.opCode())) { - throw new InvalidOperationException("Code ist ungültig!"); - } - if (faultyInput(operation.destination())) { - throw new InvalidOperationException("Adresse ist ungültig!"); - } - if (operation.vehicles().size() == 0) { - throw new InvalidOperationException( - "Es muss mindestens ein Fahrzeug ausgewählt werden!"); - } - for (Vehicle vehicle : vehicles) { - if (vehicle.status() == Vehicle.Status.ABGEMELDET - || (vehicle.status() != Vehicle.Status.FREI_FUNK - && vehicle.status() != Vehicle.Status.FREI_WACHE)) - throw new InvalidOperationException( - "Abgemeldete Fahrzeuge dürfen nicht zu einem Einsatz geschickt werden!"); - /*if (vehicle.type() == VehicleType.NEF && !rtw) { - for (Vehicle vehicleA : vehicles) { - if (vehicleA.type() == VehicleType.RTW && vehicleA.hasNef()) { - rtw = true; - break; - } - } - if (!rtw) - throw new InvalidOperationException( - "Zu einem Fahrzeug des Typs NEF muss auch ein Fahrzeug des Typs RTW mit NEF-Halterung geschickt werden!"); - }*/ - /* if (vehicle.type() == VehicleType.NAH && !rtw) { - for (Vehicle vehicleA : vehicles) { - if (vehicleA.type() == VehicleType.RTW) { - rtw = true; - break; - } - } - if (!rtw) - throw new InvalidOperationException( - "Zu einem Fahrzeug des Typs NAH muss auch ein Fahrzeug des Typs RTW geschickt werden!"); - }*/ - } - String[] codeParts = operation.opCode().split("-"); - String severity = ""; - for (int i = 0; i < codeParts[1].length(); i++) { - if (((int) (codeParts[1].charAt(i)) >= 65 && (int) (codeParts[1].charAt(i)) <= 79) - || ((int) (codeParts[1].charAt(i)) >= 97 - && (int) (codeParts[1].charAt(i)) <= 111)) { - severity = "" + codeParts[1].charAt(i); - break; - } - } - try { - operation = operation.toBuilder().severity(Severity.valueOf(severity)).build(); - } catch (IllegalArgumentException e) { - throw new InvalidOperationException( - "Der Schweregrad des Einsatzes konnte nicht ausgelesen werden!"); - } - operation = operation.toBuilder().status(Status.ACTIVE).build(); + public long add(Operation o) throws InvalidOperationException, ServiceException { + if (o.created() != null) throw new InvalidOperationException("Created must not be set"); - long operationId; - try { - operationId = operationDAO.add(operation); - } catch (PersistenceException e) { - throw new ServiceException(e); - } + if (o.status() != Status.ACTIVE) + LOG.warn("Status was set but will be overridden"); // TODO: nullable instead?? - for (Vehicle vehicle : vehicles) { - try { - operationDAO.connectVehicleToOperation(vehicle.id(), operationId); - } catch (PersistenceException e) { - throw new ServiceException(e); + try { + for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { + Vehicle v = vehicleDAO.get(id); + VehicleServiceImpl.validateVehicle(v); } - } - return operationId; - } + validateOperation(o); - private boolean faultyInput(String name) { - if (name == null) return true; - else if (name.isEmpty()) return true; - for (int i = 0; i < name.length(); i++) { - if (name.charAt(i) != ' ') return false; + return operationDAO.add( + o.toBuilder().created(Instant.now()).status(Status.ACTIVE).build()); + } catch (PersistenceException e) { + LOG.error("PersistenceException while adding operation: {}", e); + throw new ServiceException(e); + } catch (InvalidVehicleException e) { + throw new InvalidOperationException("Enthaltenes Fahrzeug ist invalid", e); + } catch (ElementNotFoundException e) { + throw new InvalidOperationException("Enthaltenes Fahrzeug existiert nicht", e); } - return true; } @Override @@ -131,28 +69,29 @@ public class OperationServiceImpl implements OperationService { Set vs = new HashSet<>(); try { - if (operationId <= 0) throw new InvalidOperationException("OperationId is invalid"); + if (operationId <= 0) throw new InvalidOperationException("OperationId ist invalid"); Operation o = operationDAO.get(operationId); validateOperation(o); if (o.status() != Status.ACTIVE) - throw new InvalidOperationException( - "Can't request vehicles for a nonactive operation"); + throw new InvalidOperationException("Einsatz ist inaktiv"); - if (!o.status().equals(Status.ACTIVE)) - throw new InvalidOperationException("Can't add vehicles to a nonactive operation"); + if (o.created() == null) + throw new InvalidOperationException("Created darf nicht leer sein"); for (Long id : vehicleIds) { - if (id <= 0) throw new InvalidVehicleException("VehicleId is invalid"); + if (id <= 0) throw new InvalidVehicleException("VehicleId ist invalid"); try { Vehicle v = vehicleDAO.get(id); + VehicleServiceImpl.validateVehicle(v); if (v.status() == Vehicle.Status.ABGEMELDET) - throw new InvalidVehicleException("Can't request nonactive vehicles"); + throw new InvalidVehicleException( + "Kann keine inaktiven Fahrzeuge anfordern"); vs.add(v); } catch (ElementNotFoundException e) { - throw new InvalidVehicleException("VehicleId does not exist"); + throw new InvalidVehicleException("VehicleId ist invalid"); } } @@ -161,55 +100,23 @@ public class OperationServiceImpl implements OperationService { operationDAO.update(o.toBuilder().vehicles(vs).build()); } catch (ElementNotFoundException e) { - throw new InvalidOperationException("No such operationId exists"); + throw new InvalidOperationException("Kein Einsatz mit dieser id existiert"); } catch (PersistenceException e) { + LOG.error("PersistenceException while requesting vehicles: {}", e); throw new ServiceException(e); } } - private static final Pattern opCodePattern = Pattern.compile("(?:\\w{1,3}-\\d{0,2})(.)(?:.*)"); - - private void validateOperation(Operation o) throws InvalidOperationException { - if (o.id() <= 0) throw new InvalidOperationException("Id is invalid"); - - if (o.opCode().trim().isEmpty()) throw new InvalidOperationException("opCode is invalid"); - - Matcher m = opCodePattern.matcher(o.opCode()); - if (!m.matches()) throw new InvalidOperationException("opCode is invalid"); - - if (!m.group(1).equals(o.severity().toString())) - throw new InvalidOperationException("Severity is invalid"); - - if (o.vehicles().isEmpty()) - throw new InvalidOperationException("No vehicles assigned to operation"); - - Instant created = o.created(); - if (created == null) throw new InvalidOperationException("Created can't be empty"); - - if (created.isAfter(Instant.now())) - throw new InvalidOperationException("Vehicle was created in the future"); - - if (o.destination().trim().isEmpty()) - throw new InvalidOperationException("Destination can't be empty"); - } - @Override public void complete(long operationId, Status status) throws InvalidOperationException, ServiceException { - Operation operation; - try { - operation = operationDAO.get(operationId); - } catch (ElementNotFoundException e) { - throw new InvalidOperationException(e); - } catch (PersistenceException e) { - throw new ServiceException(e); - } - operation = operation.toBuilder().status(status).build(); try { - operationDAO.update(operation); + Operation o = operationDAO.get(operationId); + operationDAO.update(o.toBuilder().status(status).build()); } catch (ElementNotFoundException e) { throw new InvalidOperationException(e); } catch (PersistenceException e) { + LOG.error("PersistenceException while completing operation: {}", e); throw new ServiceException(e); } } @@ -217,18 +124,68 @@ public class OperationServiceImpl implements OperationService { @Override public SortedSet rankVehicles(long operationId) throws InvalidOperationException, ServiceException { - return null; + throw new UnsupportedOperationException(); } @Override public Set list(EnumSet statuses) throws ServiceException { try { - return operationDAO.list(statuses); + Set operations = operationDAO.list(statuses); + for (Operation o : operations) validateOperation(o); + + return operations; } catch (PersistenceException e) { - LOG.debug( - "Caught PersistenceException. Throwing ServiceException. Message: {}", - e.getMessage()); + LOG.error("PersistenceException while listing operations", e); throw new ServiceException(e); + } catch (InvalidOperationException e) { + // database returned invalid values + LOG.error("DB returned invalid operation: {}", e); + throw new ServiceException("DB returned invalid operation", e); } } + + private static void validateOperation(Operation o) throws InvalidOperationException { + if (o.id() <= 0) throw new InvalidOperationException("Id is invalid"); + + if (o.opCode().trim().isEmpty()) throw new InvalidOperationException("opCode is invalid"); + + if (extractSeverityFromOpCode(o.opCode()) != o.severity()) + throw new InvalidOperationException("Einsatzcode ist invalid"); + + if (o.vehicles().isEmpty()) + throw new InvalidOperationException( + "Es muss mindestens ein Fahrzeug ausgewählt werden!"); + + for (Vehicle v : o.vehicles()) { + try { + VehicleServiceImpl.validateVehicle(v); + } catch (InvalidVehicleException e) { + throw new InvalidOperationException("Fahrzeug " + v.name() + " ist invalid" + e); + } + + if (v.status() != Vehicle.Status.FREI_FUNK && v.status() != Vehicle.Status.FREI_WACHE) + throw new InvalidOperationException( + "Fahrzeug nicht verfügbar (" + v.status() + ")"); + + // TODO: validate if NEF/RTW/NAH conditions? + } + + Instant created = o.created(); + if (created != null && created.isAfter(Instant.now())) + throw new InvalidOperationException("Fahrzeug wurde in der Zukunft erstellt"); + + if (o.destination().trim().isEmpty()) + throw new InvalidOperationException("Adresse darf nicht leer sein"); + } + + private static final Pattern opCodePattern = Pattern.compile("(?:\\w{1,3}-\\d{0,2})(.)(?:.*)"); + + private static Severity extractSeverityFromOpCode(String opCode) + throws InvalidOperationException { + Matcher m = opCodePattern.matcher(opCode); + + if (!m.matches()) throw new InvalidOperationException("Einsatzcode ist invalid"); + + return Severity.valueOf(m.group(1)); + } } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java index da995c4..8b317ce 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java @@ -12,6 +12,7 @@ import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; @Service public class VehicleServiceImpl implements VehicleService { @@ -23,6 +24,8 @@ public class VehicleServiceImpl implements VehicleService { } public long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException { + if (CollectionUtils.isEmpty(vehicle.registrations())) + throw new InvalidVehicleException("Vehicle can't be created with registrations"); validateVehicle(vehicle); try { @@ -45,7 +48,7 @@ public class VehicleServiceImpl implements VehicleService { return vehicle; } - private void validateVehicle(Vehicle vehicle) throws InvalidVehicleException, ServiceException { + protected static void validateVehicle(Vehicle vehicle) throws InvalidVehicleException { switch (vehicle.type()) { case RTW: if (vehicle.constructionType() == ConstructionType.NORMAL) { @@ -81,7 +84,7 @@ public class VehicleServiceImpl implements VehicleService { case BKTW: break; default: - throw new ServiceException("not a Valid type"); + throw new IllegalStateException("BUG: invalid vehicle type" + vehicle.type()); } } diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java index e62554c..da20030 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java @@ -4,9 +4,13 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; import at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase; import java.time.Instant; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.Set; @@ -19,12 +23,13 @@ public class OperationDAOTest extends JdbcTestCase { private static final String[] COMPARE_TABLES = new String[] {"VehicleOperation", "Operation", "Vehicle", "VehicleVersion"}; - private OperationDAO operationDAO; + private final OperationDAO operationDAO; private final Operation o; public OperationDAOTest() { - this.operationDAO = new DBOperationDAO(getJdbcConnectionManager()); + VehicleDAO vehicleDAO = new VehicleDatabaseDao(getJdbcConnectionManager()); + this.operationDAO = new DBOperationDAO(getJdbcConnectionManager(), vehicleDAO); Vehicle v1 = Vehicle.builder() @@ -87,4 +92,61 @@ public class OperationDAOTest extends JdbcTestCase { // TODO: operations.list() currently doesn't set the vehicles set // assertEquals(Set.of(o), operationSet); } + + @Test + public void testAddOperation() throws Exception { + operationDAO.add(o); + + // TODO: won't work because id won't match + // compareWith("operationDAOUpdateNormal.xml", COMPARE_TABLES); + } + + @Test(expected = PersistenceException.class) + public void testAddFaultyOperation() throws PersistenceException { + Vehicle vehicle = + Vehicle.builder() + .status(Vehicle.Status.FREI_FUNK) + .constructionType(ConstructionType.HOCHDACH) + .name("BKTW_123") + .hasNef(true) + .type(VehicleType.BKTW) + .build(); + + Operation operation = + Operation.builder() + .status(Status.ACTIVE) + .opCode(String.valueOf(Arrays.stream(new int[200]).map(i -> 'a'))) + .created(Instant.now()) + .destination("Wiedner Hauptstraße 35, Wien") + .additionalInfo("HTU Wien") + .severity(Severity.B) + .vehicles(Set.of(vehicle)) + .build(); + operationDAO.add(operation); + } + + @Test(expected = PersistenceException.class) + public void testAddFaultyOperation2() throws PersistenceException { + Vehicle vehicle = + Vehicle.builder() + .status(Vehicle.Status.FREI_FUNK) + .constructionType(ConstructionType.HOCHDACH) + .name("BKTW_123") + .hasNef(true) + .type(VehicleType.BKTW) + .build(); + + Operation operation = + Operation.builder() + .status(Status.ACTIVE) + .opCode("ALP-95E7") + .created(Instant.now()) + .destination( + "Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien ") + .additionalInfo("HTU Wien") + .severity(Severity.B) + .vehicles(Set.of(vehicle)) + .build(); + operationDAO.add(operation); + } } diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationPersistenceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationPersistenceTest.java deleted file mode 100644 index a5e4993..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationPersistenceTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import static junit.framework.TestCase.fail; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.nio.charset.Charset; -import java.sql.SQLException; -import java.time.Instant; -import java.util.Arrays; -import java.util.Set; -import org.h2.tools.RunScript; -import org.junit.BeforeClass; -import org.junit.Test; - -public class OperationPersistenceTest { - - private final OperationDAO operationDAO = - new DBOperationDAO(new JDBCConnectionManager("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")); - - @BeforeClass - public static void createSchema() throws SQLException { - RunScript.execute( - "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", - "", - "", - "classpath:sql/database.sql", - Charset.forName("UTF8"), - false); - } - - @Test - public void addOperationTest() { - Vehicle vehicle = - Vehicle.builder() - .status(Vehicle.Status.FREI_FUNK) - .constructionType(ConstructionType.HOCHDACH) - .name("BKTW_123") - .hasNef(true) - .type(VehicleType.BKTW) - .build(); - - Operation operation = - Operation.builder() - .status(Status.ACTIVE) - .opCode("ALP-95E7") - .created(Instant.now()) - .destination("Wiedner Hauptstraße 35, Wien") - .additionalInfo("HTU Wien") - .severity(Severity.B) - .vehicles(Set.of(vehicle)) - .build(); - try { - operationDAO.add(operation); - } catch (PersistenceException e) { - fail(); - } - } - - @Test(expected = PersistenceException.class) - public void addFaultyOperationTest() throws PersistenceException { - Vehicle vehicle = - Vehicle.builder() - .status(Vehicle.Status.FREI_FUNK) - .constructionType(ConstructionType.HOCHDACH) - .name("BKTW_123") - .hasNef(true) - .type(VehicleType.BKTW) - .build(); - - Operation operation = - Operation.builder() - .status(Status.ACTIVE) - .opCode(String.valueOf(Arrays.stream(new int[200]).map(i -> 'a'))) - .created(Instant.now()) - .destination("Wiedner Hauptstraße 35, Wien") - .additionalInfo("HTU Wien") - .severity(Severity.B) - .vehicles(Set.of(vehicle)) - .build(); - operationDAO.add(operation); - } - - @Test(expected = PersistenceException.class) - public void addFaultyOperation1Test() throws PersistenceException { - operationDAO.add(null); - } - - @Test(expected = PersistenceException.class) - public void addFaultyOperation2Test() throws PersistenceException { - Vehicle vehicle = - Vehicle.builder() - .status(Vehicle.Status.FREI_FUNK) - .constructionType(ConstructionType.HOCHDACH) - .name("BKTW_123") - .hasNef(true) - .type(VehicleType.BKTW) - .build(); - - Operation operation = - Operation.builder() - .status(Status.ACTIVE) - .opCode("ALP-95E7") - .created(Instant.now()) - .destination( - "Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien ") - .additionalInfo("HTU Wien") - .severity(Severity.B) - .vehicles(Set.of(vehicle)) - .build(); - operationDAO.add(operation); - } - - @Test(expected = PersistenceException.class) - public void addConnectionTest() throws PersistenceException { - operationDAO.connectVehicleToOperation(-1, 0); - } - - // TODO: ADD CONNECTION TESTS - // KOMMT ID ZURÜCK?*/ -} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/CarAddTestService.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/CarAddTestService.java deleted file mode 100644 index fd8b43f..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/CarAddTestService.java +++ /dev/null @@ -1,281 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import static junit.framework.TestCase.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDatabaseDao; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import org.junit.Test; - -public class CarAddTestService { - private final VehicleDAO vehicleP = mock(VehicleDatabaseDao.class); - private final VehicleService vehicleService = new VehicleServiceImpl(vehicleP); - - public CarAddTestService() throws PersistenceException { - when(vehicleP.add(any())).thenReturn(1L); - } - - @Test - public void testValidVehicleH() { - Vehicle vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.HOCHDACH) - .type(Vehicle.VehicleType.RTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.HOCHDACH) - .type(Vehicle.VehicleType.KTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.HOCHDACH) - .type(Vehicle.VehicleType.KTW_B) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.HOCHDACH) - .type(Vehicle.VehicleType.BKTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - } - - @Test - public void testValidVehicleM() { - Vehicle vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) - .type(Vehicle.VehicleType.KTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) - .type(Vehicle.VehicleType.KTW_B) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) - .type(Vehicle.VehicleType.BKTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - } - - @Test - public void testValidVehicleN() { - Vehicle vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.NORMAL) - .type(Vehicle.VehicleType.BKTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.NORMAL) - .type(Vehicle.VehicleType.NEF) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.NORMAL) - .type(Vehicle.VehicleType.NAH) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (InvalidVehicleException | ServiceException e) { - fail(); - } - } - - @Test(expected = InvalidVehicleException.class) - public void testInvalidVehicleH() throws InvalidVehicleException { - Vehicle vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.HOCHDACH) - .type(Vehicle.VehicleType.NEF) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.HOCHDACH) - .type(Vehicle.VehicleType.NAH) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (ServiceException e) { - fail(); - } - } - - @Test(expected = InvalidVehicleException.class) - public void testInvalidVehicleM() throws InvalidVehicleException { - Vehicle vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) - .type(Vehicle.VehicleType.NEF) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) - .type(Vehicle.VehicleType.NAH) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) - .type(Vehicle.VehicleType.RTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (ServiceException e) { - fail(); - } - } - - @Test(expected = InvalidVehicleException.class) - public void testInvalidVehicleN() throws InvalidVehicleException { - Vehicle vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.NORMAL) - .type(Vehicle.VehicleType.RTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.NORMAL) - .type(Vehicle.VehicleType.KTW_B) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (ServiceException e) { - fail(); - } - vehicle = - Vehicle.builder() - .constructionType(Vehicle.ConstructionType.NORMAL) - .type(Vehicle.VehicleType.KTW) - .hasNef(true) - .status(Vehicle.Status.ABGEMELDET) - .name("") - .build(); - try { - vehicleService.add(vehicle); - } catch (ServiceException e) { - fail(); - } - } -} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java index 70185d3..f9ec287 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java @@ -1,5 +1,6 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -11,10 +12,10 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; import java.time.Instant; import java.util.Collections; import java.util.Set; @@ -36,14 +37,15 @@ public class OperationServiceTest { private Set vehicles; private Vehicle v1, v2, v3, v4, v5; + private Operation baseOp, o1, o2; @Before - public void setUp() throws ElementNotFoundException, PersistenceException { + public void setUp() throws Exception { v1 = Vehicle.builder() .id(1) .name("RTW-1") - .constructionType(Vehicle.ConstructionType.HOCHDACH) + .constructionType(ConstructionType.HOCHDACH) .type(Vehicle.VehicleType.RTW) .status(Vehicle.Status.FREI_FUNK) .hasNef(true) @@ -53,7 +55,7 @@ public class OperationServiceTest { Vehicle.builder() .id(2) .name("KTW-1") - .constructionType(Vehicle.ConstructionType.HOCHDACH) + .constructionType(ConstructionType.HOCHDACH) .type(Vehicle.VehicleType.KTW) .status(Vehicle.Status.FREI_WACHE) .hasNef(true) @@ -63,7 +65,7 @@ public class OperationServiceTest { Vehicle.builder() .id(3) .name("KTW-2") - .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) + .constructionType(ConstructionType.MITTELHOCHDACH) .type(Vehicle.VehicleType.KTW_B) .status(Vehicle.Status.FREI_FUNK) .hasNef(false) @@ -73,7 +75,7 @@ public class OperationServiceTest { Vehicle.builder() .id(4) .name("BKTW-2") - .constructionType(Vehicle.ConstructionType.HOCHDACH) + .constructionType(ConstructionType.HOCHDACH) .type(Vehicle.VehicleType.BKTW) .status(Vehicle.Status.FREI_FUNK) .hasNef(false) @@ -83,7 +85,7 @@ public class OperationServiceTest { Vehicle.builder() .id(5) .name("NEF-1") - .constructionType(Vehicle.ConstructionType.NORMAL) + .constructionType(ConstructionType.NORMAL) .type(Vehicle.VehicleType.NEF) .status(Vehicle.Status.FREI_WACHE) .hasNef(true) @@ -93,7 +95,7 @@ public class OperationServiceTest { Vehicle.builder() .id(6) .name("NAH-1") - .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) + .constructionType(ConstructionType.MITTELHOCHDACH) .type(Vehicle.VehicleType.NAH) .status(Vehicle.Status.ABGEMELDET) .hasNef(true) @@ -101,24 +103,24 @@ public class OperationServiceTest { vehicles = Set.of(v1, v2, v3, v4, v5, v6); - Operation o = + baseOp = Operation.builder() .id(1) .opCode("ALP-95E7") .severity(Severity.E) .status(Status.ACTIVE) .vehicles(Collections.singleton(v1)) - .created(Instant.now()) .destination("Wiedner Hauptstraße 35, Wien") .build(); - Operation o2 = o.toBuilder().status(Status.CANCELLED).build(); + o1 = baseOp.toBuilder().created(Instant.now()).build(); + o2 = o1.toBuilder().id(5).status(Status.CANCELLED).build(); when(operationDAO.get(anyLong())) .thenAnswer( ans -> { long arg = ans.getArgument(0); - if (arg == 1L) return o; + if (arg == 1L) return o1; else if (arg == 5L) return o2; else throw new ElementNotFoundException(""); }); @@ -172,4 +174,34 @@ public class OperationServiceTest { public void requestInactiveOperation() throws Exception { operationService.requestVehicles(5, Set.of(1L)); } + + @Test + public void addOperation() throws Exception { + operationService.add(baseOp); + + // Operation result = + verify(operationDAO, times(1)) + .add(baseOp.toBuilder().created(any()).status(Status.ACTIVE).build()); + verify(vehicleDAO, times(1)).get(v1.id()); + } + + @Test(expected = InvalidOperationException.class) + public void addInvalidSeverity() throws Exception { + operationService.add(baseOp.toBuilder().severity(Severity.B).build()); + } + + @Test(expected = InvalidOperationException.class) + public void addWithoutVehicles() throws Exception { + operationService.add(baseOp.toBuilder().vehicles(Set.of()).build()); + } + + @Test(expected = InvalidOperationException.class) + public void addInvalidOpcode() throws Exception { + operationService.add(baseOp.toBuilder().opCode("ABC").build()); + } + + @Test(expected = InvalidOperationException.class) + public void addWithSetCreated() throws Exception { + operationService.add(baseOp.toBuilder().created(Instant.now()).build()); + } } diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceUnitTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceUnitTest.java deleted file mode 100644 index 7b574a1..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceUnitTest.java +++ /dev/null @@ -1,156 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import static junit.framework.TestCase.fail; -import static org.hamcrest.CoreMatchers.is; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.OperationDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.time.Instant; -import java.util.Set; -import org.junit.Assert; -import org.junit.Test; - -public class OperationServiceUnitTest { - private final OperationDAO operationDAO = mock(OperationDAO.class); - private final VehicleDAO vehicleDAO = mock(VehicleDAO.class); - private final OperationService operationService = - new OperationServiceImpl(operationDAO, vehicleDAO); - - @Test - public void addOperationTest() { - try { - when(operationDAO.add(any())).thenReturn(1L); - } catch (PersistenceException e) { - fail(); - } - Vehicle vehicle = - Vehicle.builder() - .status(Vehicle.Status.FREI_FUNK) - .constructionType(ConstructionType.HOCHDACH) - .name("BKTW_123") - .hasNef(true) - .type(VehicleType.BKTW) - .build(); - - Operation operation = - Operation.builder() - .status(Status.ACTIVE) - .opCode("ALP-95E7") - .created(Instant.now()) - .destination("Wiedner Hauptstraße 35, Wien") - .additionalInfo("HTU Wien") - .severity(Severity.B) - .vehicles(Set.of(vehicle)) - .build(); - try { - Assert.assertThat(operationService.add(operation), is(1L)); - } catch (InvalidOperationException | ServiceException e) { - fail(); - } - } - - @Test(expected = InvalidOperationException.class) - public void addFaultyOperationTest() throws InvalidOperationException { - Vehicle vehicle = - Vehicle.builder() - .status(Vehicle.Status.FREI_FUNK) - .constructionType(ConstructionType.HOCHDACH) - .name("BKTW_123") - .hasNef(true) - .type(VehicleType.BKTW) - .build(); - Vehicle vehicle1 = - Vehicle.builder() - .status(Vehicle.Status.ABGEMELDET) - .constructionType(ConstructionType.HOCHDACH) - .name("BKTW_123") - .hasNef(true) - .type(VehicleType.BKTW) - .build(); - - Operation operation = - Operation.builder() - .status(Status.ACTIVE) - .opCode("ALP-95E7") - .created(Instant.now()) - .destination("Wiedner Hauptstraße 35, Wien") - .additionalInfo("HTU Wien") - .severity(Severity.B) - .vehicles(Set.of(vehicle, vehicle1)) - .build(); - try { - Assert.assertThat(operationService.add(operation), is(1L)); - } catch (ServiceException e) { - fail(); - } - } - - @Test(expected = InvalidOperationException.class) - public void addFaultyOperation2Test() throws InvalidOperationException { - Operation operation = - Operation.builder() - .status(Status.ACTIVE) - .opCode("ALP-95E7") - .created(Instant.now()) - .destination("Wiedner Hauptstraße 35, Wien") - .additionalInfo("HTU Wien") - .severity(Severity.B) - .vehicles(Set.of()) - .build(); - try { - Assert.assertThat(operationService.add(operation), is(1L)); - } catch (ServiceException e) { - e.printStackTrace(); - } - } - - @Test(expected = InvalidOperationException.class) - public void addFaultyOperation3Test() throws InvalidOperationException { - Operation operation = - Operation.builder() - .status(Status.ACTIVE) - .opCode("ALP-95E7") - .created(Instant.now()) - .destination("") - .additionalInfo("HTU Wien") - .severity(Severity.B) - .vehicles(Set.of()) - .build(); - try { - Assert.assertThat(operationService.add(operation), is(1L)); - } catch (ServiceException e) { - e.printStackTrace(); - } - } - - @Test(expected = InvalidOperationException.class) - public void addFaultyOperation4Test() throws InvalidOperationException { - Operation operation = - Operation.builder() - .status(Status.ACTIVE) - .opCode("") - .created(Instant.now()) - .destination("Römergasse 7, 2500 Baden") - .additionalInfo("HTU Wien") - .severity(Severity.B) - .vehicles(Set.of()) - .build(); - try { - Assert.assertThat(operationService.add(operation), is(1L)); - } catch (ServiceException e) { - e.printStackTrace(); - } - } -} -- cgit v1.2.3-70-g09d2