aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java46
-rw-r--r--src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java79
-rw-r--r--src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java81
-rw-r--r--src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceComponentTest.java16
-rw-r--r--src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java175
-rw-r--r--src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceUnitTest.java5
-rw-r--r--src/test/resources/operationDAOUpdateNormal.xml19
-rw-r--r--src/test/resources/operationDAOUpdateRemoveVehicles.xml17
-rw-r--r--src/test/resources/operationDAOUpdateSetup.xml17
9 files changed, 447 insertions, 8 deletions
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 476f968..68185d6 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
@@ -2,9 +2,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao;
import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation;
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.exception.ElementNotFoundException;
import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException;
import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager;
+import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -112,7 +114,49 @@ public class DBOperationDAO implements OperationDAO {
}
@Override
- public void update(Operation operation) throws ElementNotFoundException, PersistenceException {}
+ public void update(Operation o) throws ElementNotFoundException, PersistenceException {
+ String sql =
+ "UPDATE Operation SET opCode = ?, severity = ?, destination = ?,"
+ + " additionalInfo = ?, status = ? WHERE id = ?";
+ String sql2 = "DELETE FROM VehicleOperation WHERE operationId = ?";
+ String sql3 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)";
+
+ 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.setString(3, o.destination());
+ pstmt.setString(4, o.additionalInfo());
+ pstmt.setInt(5, o.status().ordinal());
+ pstmt.setLong(6, o.id());
+
+ if (pstmt.executeUpdate() != 1)
+ throw new ElementNotFoundException("No such operationId exists: " + pstmt);
+ }
+
+ try (PreparedStatement pstmt = con.prepareStatement(sql2)) {
+ pstmt.setLong(1, o.id());
+ pstmt.executeUpdate();
+ }
+
+ try (PreparedStatement pstmt = con.prepareStatement(sql3)) {
+ pstmt.setLong(2, o.id());
+
+ for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) {
+ pstmt.setLong(1, id);
+ pstmt.addBatch();
+ }
+
+ pstmt.executeBatch();
+ }
+ con.commit();
+ con.setAutoCommit(true);
+ } catch (SQLException e) {
+ throw new PersistenceException(e);
+ }
+ }
@Override
public Operation get(long operationId) throws ElementNotFoundException, 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 a6be111..ba4eb7f 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
@@ -1,17 +1,23 @@
package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;
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.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 at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException;
+import java.time.Instant;
import java.util.EnumSet;
+import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.springframework.stereotype.Service;
@Service
@@ -20,8 +26,11 @@ public class OperationServiceImpl implements OperationService {
// TODO: anders?
private OperationDAO operationDAO;
- public OperationServiceImpl(OperationDAO dao) {
- this.operationDAO = dao;
+ private final VehicleDAO vehicleDAO;
+
+ public OperationServiceImpl(OperationDAO operationDAO, VehicleDAO vehicleDAO) {
+ this.operationDAO = operationDAO;
+ this.vehicleDAO = vehicleDAO;
}
@Override
@@ -114,7 +123,71 @@ public class OperationServiceImpl implements OperationService {
@Override
public void requestVehicles(long operationId, Set<Long> vehicleIds)
- throws InvalidOperationException, InvalidVehicleException, ServiceException {}
+ throws InvalidOperationException, InvalidVehicleException, ServiceException {
+ Set<Vehicle> vs = new HashSet<>();
+
+ try {
+ if (operationId <= 0) throw new InvalidOperationException("OperationId is invalid");
+ Operation o = operationDAO.get(operationId);
+ validateOperation(o);
+
+ if (o.status() != Status.ACTIVE)
+ throw new InvalidOperationException(
+ "Can't request vehicles for a nonactive operation");
+
+ if (!o.status().equals(Status.ACTIVE))
+ throw new InvalidOperationException("Can't add vehicles to a nonactive operation");
+
+ for (Long id : vehicleIds) {
+ if (id <= 0) throw new InvalidVehicleException("VehicleId is invalid");
+
+ try {
+ Vehicle v = vehicleDAO.get(id);
+ if (v.status() == Vehicle.Status.ABGEMELDET)
+ throw new InvalidVehicleException("Can't request nonactive vehicles");
+
+ vs.add(v);
+ } catch (ElementNotFoundException e) {
+ throw new InvalidVehicleException("VehicleId does not exist");
+ }
+ }
+
+ vs.addAll(o.vehicles());
+ if (vs.equals(o.vehicles())) return;
+
+ operationDAO.update(o.toBuilder().vehicles(vs).build());
+ } catch (ElementNotFoundException e) {
+ throw new InvalidOperationException("No such operationId exists");
+ } catch (PersistenceException 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)
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
new file mode 100644
index 0000000..726735d
--- /dev/null
+++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java
@@ -0,0 +1,81 @@
+package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao;
+
+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.exception.ElementNotFoundException;
+import at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase;
+import java.time.Instant;
+import java.util.Collections;
+import java.util.Set;
+import org.dbunit.dataset.DataSetException;
+import org.dbunit.dataset.IDataSet;
+import org.junit.Test;
+
+public class OperationDAOTest extends JdbcTestCase {
+
+ private static final String[] COMPARE_TABLES =
+ new String[] {"VehicleOperation", "Operation", "Vehicle", "VehicleVersion"};
+
+ private OperationDAO operationDAO;
+
+ private final Operation o;
+
+ public OperationDAOTest() {
+ this.operationDAO = new DBOperationDAO(getJdbcConnectionManager());
+
+ Vehicle v1 =
+ Vehicle.builder()
+ .id(1)
+ .name("RTW-1")
+ .constructionType(Vehicle.ConstructionType.HOCHDACH)
+ .type(Vehicle.VehicleType.RTW)
+ .status(Vehicle.Status.FREI_FUNK)
+ .hasNef(true)
+ .build();
+
+ Vehicle v2 = v1.toBuilder().id(2).build();
+ Vehicle v3 = v1.toBuilder().id(3).build();
+
+ o =
+ Operation.builder()
+ .id(1)
+ .opCode("RD-2B0M")
+ .severity(Severity.B)
+ .status(Status.ACTIVE)
+ .vehicles(Set.of(v1, v2, v3))
+ .created(Instant.now())
+ .destination("New description")
+ .additionalInfo("Test")
+ .build();
+ }
+
+ @Override
+ protected IDataSet getDataSet() throws DataSetException {
+ return getDataSet("operationDAOUpdateSetup.xml");
+ }
+
+ @Test
+ public void testUpdateNormal() throws Exception {
+ operationDAO.update(o);
+
+ compareWith("operationDAOUpdateNormal.xml", COMPARE_TABLES);
+ }
+
+ @Test(expected = ElementNotFoundException.class)
+ public void testUpdateMissing() throws Exception {
+ Operation op = o.toBuilder().id(73).build();
+
+ operationDAO.update(op);
+ }
+
+ @Test
+ public void testUpdateRemoveVehicles() throws Exception {
+ Operation op = o.toBuilder().vehicles(Collections.emptySet()).build();
+
+ operationDAO.update(op);
+
+ compareWith("operationDAOUpdateRemoveVehicles.xml", COMPARE_TABLES);
+ }
+}
diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceComponentTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceComponentTest.java
index 8e13d0e..9754b2d 100644
--- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceComponentTest.java
+++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceComponentTest.java
@@ -5,6 +5,7 @@ import static org.hamcrest.CoreMatchers.is;
import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.DBOperationDAO;
import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.OperationDAO;
+import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDatabaseDao;
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;
@@ -21,9 +22,18 @@ import org.junit.Test;
public class OperationServiceComponentTest {
- private final OperationDAO operationDAO =
- new DBOperationDAO(new JDBCConnectionManager("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"));
- private final OperationService operationService = new OperationServiceImpl(operationDAO);
+ // TODO: dependency injection
+
+ private final JDBCConnectionManager jdbcConnectionManager =
+ new JDBCConnectionManager("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
+
+ private final OperationDAO operationDAO = new DBOperationDAO(jdbcConnectionManager);
+
+ private final VehicleDatabaseDao vehicleDatabaseDao =
+ new VehicleDatabaseDao(jdbcConnectionManager);
+
+ private final OperationService operationService =
+ new OperationServiceImpl(operationDAO, vehicleDatabaseDao);
/*@Test
public void testaddOperationTest() {
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
new file mode 100644
index 0000000..70185d3
--- /dev/null
+++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java
@@ -0,0 +1,175 @@
+package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+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.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;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class OperationServiceTest {
+
+ @Mock private OperationDAO operationDAO;
+
+ @Mock private VehicleDAO vehicleDAO;
+
+ @InjectMocks private OperationServiceImpl operationService;
+
+ private Set<Vehicle> vehicles;
+ private Vehicle v1, v2, v3, v4, v5;
+
+ @Before
+ public void setUp() throws ElementNotFoundException, PersistenceException {
+ v1 =
+ Vehicle.builder()
+ .id(1)
+ .name("RTW-1")
+ .constructionType(Vehicle.ConstructionType.HOCHDACH)
+ .type(Vehicle.VehicleType.RTW)
+ .status(Vehicle.Status.FREI_FUNK)
+ .hasNef(true)
+ .build();
+
+ v2 =
+ Vehicle.builder()
+ .id(2)
+ .name("KTW-1")
+ .constructionType(Vehicle.ConstructionType.HOCHDACH)
+ .type(Vehicle.VehicleType.KTW)
+ .status(Vehicle.Status.FREI_WACHE)
+ .hasNef(true)
+ .build();
+
+ v3 =
+ Vehicle.builder()
+ .id(3)
+ .name("KTW-2")
+ .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH)
+ .type(Vehicle.VehicleType.KTW_B)
+ .status(Vehicle.Status.FREI_FUNK)
+ .hasNef(false)
+ .build();
+
+ v4 =
+ Vehicle.builder()
+ .id(4)
+ .name("BKTW-2")
+ .constructionType(Vehicle.ConstructionType.HOCHDACH)
+ .type(Vehicle.VehicleType.BKTW)
+ .status(Vehicle.Status.FREI_FUNK)
+ .hasNef(false)
+ .build();
+
+ v5 =
+ Vehicle.builder()
+ .id(5)
+ .name("NEF-1")
+ .constructionType(Vehicle.ConstructionType.NORMAL)
+ .type(Vehicle.VehicleType.NEF)
+ .status(Vehicle.Status.FREI_WACHE)
+ .hasNef(true)
+ .build();
+
+ Vehicle v6 =
+ Vehicle.builder()
+ .id(6)
+ .name("NAH-1")
+ .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH)
+ .type(Vehicle.VehicleType.NAH)
+ .status(Vehicle.Status.ABGEMELDET)
+ .hasNef(true)
+ .build();
+
+ vehicles = Set.of(v1, v2, v3, v4, v5, v6);
+
+ Operation o =
+ 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();
+
+ when(operationDAO.get(anyLong()))
+ .thenAnswer(
+ ans -> {
+ long arg = ans.getArgument(0);
+ if (arg == 1L) return o;
+ else if (arg == 5L) return o2;
+ else throw new ElementNotFoundException("");
+ });
+
+ when(vehicleDAO.get(anyLong()))
+ .thenAnswer(
+ ans -> {
+ int arg = ((Long) ans.getArgument(0)).intValue();
+ return vehicles.stream()
+ .filter(v -> v.id() == arg)
+ .findFirst()
+ .orElseThrow(() -> new ElementNotFoundException(""));
+ });
+ }
+
+ @Test
+ public void requestNormal() throws Exception {
+ Set<Long> vehicleIds = Set.of(2L, 3L, 4L, 5L);
+ operationService.requestVehicles(1, vehicleIds);
+
+ Operation result =
+ operationDAO.get(1).toBuilder().vehicles(Set.of(v1, v2, v3, v4, v5)).build();
+ verify(operationDAO, times(1)).update(result);
+ verify(operationDAO, times(0)).get(6L);
+ }
+
+ @Test
+ public void requestExistingVehicle() throws Exception {
+ operationService.requestVehicles(1, Set.of(1L));
+
+ Operation result = operationDAO.get(1);
+ verify(operationDAO, times(0)).update(result);
+ }
+
+ @Test(expected = InvalidVehicleException.class)
+ public void requestInvalidVehicle() throws Exception {
+ operationService.requestVehicles(1, Set.of(5L, 6L));
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void requestInvalidOperation() throws Exception {
+ operationService.requestVehicles(2, Set.of(1L));
+ }
+
+ @Test(expected = InvalidVehicleException.class)
+ public void requestInactiveVehicle() throws Exception {
+ operationService.requestVehicles(1, Set.of(6L));
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void requestInactiveOperation() throws Exception {
+ operationService.requestVehicles(5, Set.of(1L));
+ }
+}
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
index 29a840b..7b574a1 100644
--- 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
@@ -7,6 +7,7 @@ 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;
@@ -23,7 +24,9 @@ import org.junit.Test;
public class OperationServiceUnitTest {
private final OperationDAO operationDAO = mock(OperationDAO.class);
- private final OperationService operationService = new OperationServiceImpl(operationDAO);
+ private final VehicleDAO vehicleDAO = mock(VehicleDAO.class);
+ private final OperationService operationService =
+ new OperationServiceImpl(operationDAO, vehicleDAO);
@Test
public void addOperationTest() {
diff --git a/src/test/resources/operationDAOUpdateNormal.xml b/src/test/resources/operationDAOUpdateNormal.xml
new file mode 100644
index 0000000..025cdc2
--- /dev/null
+++ b/src/test/resources/operationDAOUpdateNormal.xml
@@ -0,0 +1,19 @@
+<dataset>
+ <Operation id="1" opCode="RD-2B0M" severity="B" created="2000-01-01"
+ destination="New description" status="ACTIVE" additionalInfo="Test"/>
+
+ <VehicleVersion id="1" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNef="true"/>
+ <VehicleVersion id="2" name="KTW-1" constructionType="HOCHDACH" type="KTW" hasNef="true"/>
+ <VehicleVersion id="3" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW_B" hasNef="false"/>
+ <VehicleVersion id="4" name="BKTW-2" constructionType="HOCHDACH" type="BKTW" hasNef="false"/>
+ <VehicleVersion id="5" name="NEF-1" constructionType="NORMAL" type="NEF" hasNef="true"/>
+
+ <Vehicle id="1" version="1" status="FREI_FUNK"/>
+ <Vehicle id="2" version="2" status="FREI_WACHE"/>
+ <Vehicle id="3" version="3" status="FREI_FUNK"/>
+ <Vehicle id="4" version="4" status="FREI_WACHE"/>
+
+ <VehicleOperation vehicleId="1" operationId="1"/>
+ <VehicleOperation vehicleId="2" operationId="1"/>
+ <VehicleOperation vehicleId="3" operationId="1"/>
+</dataset>
diff --git a/src/test/resources/operationDAOUpdateRemoveVehicles.xml b/src/test/resources/operationDAOUpdateRemoveVehicles.xml
new file mode 100644
index 0000000..6f171b4
--- /dev/null
+++ b/src/test/resources/operationDAOUpdateRemoveVehicles.xml
@@ -0,0 +1,17 @@
+<dataset>
+ <Operation id="1" opCode="RD-2B0M" severity="B" created="2000-01-01"
+ destination="New description" status="ACTIVE" additionalInfo="Test"/>
+
+ <VehicleVersion id="1" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNef="true"/>
+ <VehicleVersion id="2" name="KTW-1" constructionType="HOCHDACH" type="KTW" hasNef="true"/>
+ <VehicleVersion id="3" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW_B" hasNef="false"/>
+ <VehicleVersion id="4" name="BKTW-2" constructionType="HOCHDACH" type="BKTW" hasNef="false"/>
+ <VehicleVersion id="5" name="NEF-1" constructionType="NORMAL" type="NEF" hasNef="true"/>
+
+ <Vehicle id="1" version="1" status="FREI_FUNK"/>
+ <Vehicle id="2" version="2" status="FREI_WACHE"/>
+ <Vehicle id="3" version="3" status="FREI_FUNK"/>
+ <Vehicle id="4" version="4" status="FREI_WACHE"/>
+
+ <VehicleOperation />
+</dataset>
diff --git a/src/test/resources/operationDAOUpdateSetup.xml b/src/test/resources/operationDAOUpdateSetup.xml
new file mode 100644
index 0000000..23d1a25
--- /dev/null
+++ b/src/test/resources/operationDAOUpdateSetup.xml
@@ -0,0 +1,17 @@
+<dataset>
+ <Operation id="1" opCode="ALP-95E7" severity="E" created="2000-01-01"
+ destination="Wiedner Hauptstraße 35, Wien" status="ACTIVE"/>
+
+ <VehicleVersion id="1" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNef="true"/>
+ <VehicleVersion id="2" name="KTW-1" constructionType="HOCHDACH" type="KTW" hasNef="true"/>
+ <VehicleVersion id="3" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW_B" hasNef="false"/>
+ <VehicleVersion id="4" name="BKTW-2" constructionType="HOCHDACH" type="BKTW" hasNef="false"/>
+ <VehicleVersion id="5" name="NEF-1" constructionType="NORMAL" type="NEF" hasNef="true"/>
+
+ <Vehicle id="1" version="1" status="FREI_FUNK"/>
+ <Vehicle id="2" version="2" status="FREI_WACHE"/>
+ <Vehicle id="3" version="3" status="FREI_FUNK"/>
+ <Vehicle id="4" version="4" status="FREI_WACHE"/>
+
+ <VehicleOperation />
+</dataset>