Merge branch 'DEVELOP' of ssh://git.eclipse.org:29418/openk-usermodules/org.eclipse.openk-usermodules.contactBaseData.backend into KON-199_Sonstiges_RequiredArgs_Declaration
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/controller/CompanyController.java b/src/main/java/org/eclipse/openk/contactbasedata/controller/CompanyController.java
index e455fa3..19c55db 100644
--- a/src/main/java/org/eclipse/openk/contactbasedata/controller/CompanyController.java
+++ b/src/main/java/org/eclipse/openk/contactbasedata/controller/CompanyController.java
@@ -111,5 +111,37 @@
 
         return companyService.findContactPersonsToCompany(contactUuid);
     }
+
+//    @GetMapping("/{contactCompanyUuid}/contact-persons/{contactPersonUuid}")
+//    @Secured({"ROLE_KON-READER", "ROLE_KON-WRITER", "ROLE_KON-ADMIN"})
+//    @ApiOperation(value = "Anzeigen eines bestimmten Ansprechpartners zu einer Firma")
+//    @ApiResponses(value = {
+//            @ApiResponse(code = 404, message = "Ansprechpartner nicht gefunden."),
+//            @ApiResponse(code = 400, message = "Ungültige Anfrage."),
+//            @ApiResponse(code = 200, message = "Ansprechpartner erfolgreich gelesen.")})
+//    public ContactPersonDto findContactPerson(
+//                                    @PathVariable("contactCompanyUuid") UUID contactCompanyUuid,
+//                                    @PathVariable("contactPersonUuid") UUID contactPersonUuid){
+//        return companyService.findContactPersonToCompany(contactCompanyUuid, contactPersonUuid);
+//    }
+//
+//    @PostMapping
+//    @Secured("ROLE_KON-ADMIN")
+//    @ApiOperation(value = "Anlegen einer Kontaktperson")
+//    @ApiResponses(value = {
+//            @ApiResponse(code = 201, message = "Kontaktperson erfolgreich angelegt"),
+//            @ApiResponse(code = 500, message = "Konnte nicht durchgeführt werden")
+//    })
+//    public ResponseEntity<ContactPersonDto> insertContactPerson(
+//            @Validated @RequestBody ContactPersonDto contactPersonDto) {
+//        ContactPersonDto savedContactPersonDto = companyService.insertContactPerson(contactPersonDto);
+//        URI location = ServletUriComponentsBuilder
+//                .fromCurrentRequestUri()
+//                .path("/{uuid}")
+//                .buildAndExpand(savedExternalPersonDto.getContactUuid())
+//                .toUri();
+//        return ResponseEntity.created(location).body(savedExternalPersonDto);
+//    }
+
 }
 
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/controller/ContactPersonController.java b/src/main/java/org/eclipse/openk/contactbasedata/controller/ContactPersonController.java
new file mode 100644
index 0000000..1ace3df
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/contactbasedata/controller/ContactPersonController.java
@@ -0,0 +1,100 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************
+ */
+package org.eclipse.openk.contactbasedata.controller;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import lombok.extern.log4j.Log4j2;
+import org.eclipse.openk.contactbasedata.exceptions.BadRequestException;
+import org.eclipse.openk.contactbasedata.service.ContactPersonService;
+import org.eclipse.openk.contactbasedata.viewmodel.ContactPersonDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
+import java.net.URI;
+import java.util.UUID;
+
+@Log4j2
+@RestController
+@RequestMapping("/contact-persons")
+public class ContactPersonController {
+    @Autowired
+    private ContactPersonService contactPersonService;
+
+    @GetMapping("/{contactUuid}")
+    @Secured({"ROLE_KON-READER", "ROLE_KON-WRITER", "ROLE_KON-ADMIN"})
+    @ApiOperation(value = "Anzeigen eines bestimmten Ansprechpartners zu einer Firma")
+    @ApiResponses(value = {
+            @ApiResponse(code = 404, message = "Ansprechpartner nicht gefunden."),
+            @ApiResponse(code = 400, message = "Ungültige Anfrage."),
+            @ApiResponse(code = 200, message = "Ansprechpartner erfolgreich gelesen.")})
+    public ContactPersonDto findContactPerson(@PathVariable("contactUuid") UUID contactUuid){
+        return contactPersonService.findContactPerson(contactUuid);
+    }
+
+    @PostMapping
+    @Secured("ROLE_KON-ADMIN")
+    @ApiOperation(value = "Anlegen einer Kontaktperson")
+    @ApiResponses(value = {
+            @ApiResponse(code = 201, message = "Kontaktperson erfolgreich angelegt"),
+            @ApiResponse(code = 500, message = "Konnte nicht durchgeführt werden")
+    })
+    public ResponseEntity<ContactPersonDto> insertContactPerson(
+            @Validated @RequestBody ContactPersonDto contactPersonDto) {
+        ContactPersonDto savedContactPersonDto = contactPersonService.insertContactPerson(contactPersonDto);
+        URI location = ServletUriComponentsBuilder
+                .fromCurrentRequestUri()
+                .path("/{uuid}")
+                .buildAndExpand(savedContactPersonDto.getContactUuid())
+                .toUri();
+        return ResponseEntity.created(location).body(savedContactPersonDto);
+    }
+
+    @PutMapping("/{contactUuid}")
+    @Secured("ROLE_KON-ADMIN")
+    @ApiOperation(value = "Ändern einer Kontaktperson")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "Kontaktperson wurde aktualisiert"),
+            @ApiResponse(code = 400, message = "Ungültige Eingabe"),
+            @ApiResponse(code = 404, message = "Nicht gefunden")})
+    public ResponseEntity updateContactPerson(@PathVariable UUID contactUuid, @Validated @RequestBody ContactPersonDto contactPersonDto) {
+
+        if (!contactPersonDto.getContactUuid().equals(contactUuid)) {
+            throw new BadRequestException("invalid.uuid.path.object");
+        }
+
+        contactPersonService.updateContactPerson(contactPersonDto);
+        return ResponseEntity.ok().build();
+    }
+
+    @DeleteMapping("/{contactUuid}")
+    @ResponseStatus(HttpStatus.OK)
+    @ApiOperation(value = "Eine bestimmte Adresse eines bestimmten Kontakts löschen")
+    @ApiResponses(value = {
+            @ApiResponse(code = 204, message = "Erfolgreich gelöscht"),
+            @ApiResponse(code = 400, message = "Ungültige Anfrage"),
+            @ApiResponse(code = 404, message = "Nicht gefunden")})
+    public void deleteAddress(@PathVariable("contactUuid") UUID contactUuid) {
+
+        contactPersonService.deleteContactPerson(contactUuid);
+    }
+
+}
+
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/model/TblContactPerson.java b/src/main/java/org/eclipse/openk/contactbasedata/model/TblContactPerson.java
index 9bcdf66..3529629 100644
--- a/src/main/java/org/eclipse/openk/contactbasedata/model/TblContactPerson.java
+++ b/src/main/java/org/eclipse/openk/contactbasedata/model/TblContactPerson.java
@@ -15,7 +15,6 @@
 package org.eclipse.openk.contactbasedata.model;
 
 import lombok.Data;
-
 import javax.persistence.*;
 
 @Data
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/repository/ContactPersonRepository.java b/src/main/java/org/eclipse/openk/contactbasedata/repository/ContactPersonRepository.java
new file mode 100644
index 0000000..cdb48e6
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/contactbasedata/repository/ContactPersonRepository.java
@@ -0,0 +1,29 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************
+ */
+package org.eclipse.openk.contactbasedata.repository;
+
+import org.eclipse.openk.contactbasedata.model.TblContactPerson;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.Optional;
+import java.util.UUID;
+
+public interface ContactPersonRepository extends JpaRepository<TblContactPerson, Long > {
+
+    @Query("select cp from TblContactPerson cp where cp.contact.uuid = ?1")
+    Optional< TblContactPerson > findByTblContactUuid(final UUID contactUuid);
+
+}
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/CompanyService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/CompanyService.java
index 663e2ff..bed5d07 100644
--- a/src/main/java/org/eclipse/openk/contactbasedata/service/CompanyService.java
+++ b/src/main/java/org/eclipse/openk/contactbasedata/service/CompanyService.java
@@ -16,16 +16,15 @@
 
 import lombok.extern.log4j.Log4j2;
 import org.eclipse.openk.contactbasedata.constants.Constants;
+import org.eclipse.openk.contactbasedata.exceptions.BadRequestException;
 import org.eclipse.openk.contactbasedata.exceptions.NotFoundException;
 import org.eclipse.openk.contactbasedata.mapper.CompanyMapper;
 import org.eclipse.openk.contactbasedata.mapper.ContactMapper;
 import org.eclipse.openk.contactbasedata.mapper.ContactPersonMapper;
 import org.eclipse.openk.contactbasedata.model.TblCompany;
 import org.eclipse.openk.contactbasedata.model.TblContact;
-import org.eclipse.openk.contactbasedata.repository.CompanyRepository;
-import org.eclipse.openk.contactbasedata.repository.ContactRepository;
-import org.eclipse.openk.contactbasedata.repository.PersonTypeRepository;
-import org.eclipse.openk.contactbasedata.repository.SalutationRepository;
+import org.eclipse.openk.contactbasedata.model.TblContactPerson;
+import org.eclipse.openk.contactbasedata.repository.*;
 import org.eclipse.openk.contactbasedata.viewmodel.CompanyDto;
 import org.eclipse.openk.contactbasedata.viewmodel.ContactPersonDto;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -48,6 +47,9 @@
     private ContactRepository contactRepository;
 
     @Autowired
+    private ContactPersonRepository contactPersonRepository;
+
+    @Autowired
     private SalutationRepository salutationRepository;
 
     @Autowired
@@ -96,7 +98,6 @@
     public CompanyDto updateCompany(CompanyDto companyDto){
         TblCompany companyUpdated;
 
-        //Interne Person holen
         TblCompany existingCompany = companyRepository
                 .findByTblContactUuid(companyDto.getContactUuid())
                 .orElseThrow(() -> new NotFoundException("contact.uuid.not.existing"));
diff --git a/src/main/java/org/eclipse/openk/contactbasedata/service/ContactPersonService.java b/src/main/java/org/eclipse/openk/contactbasedata/service/ContactPersonService.java
new file mode 100644
index 0000000..f1b2521
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/contactbasedata/service/ContactPersonService.java
@@ -0,0 +1,141 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************
+ */
+package org.eclipse.openk.contactbasedata.service;
+
+import lombok.extern.log4j.Log4j2;
+import org.eclipse.openk.contactbasedata.constants.Constants;
+import org.eclipse.openk.contactbasedata.exceptions.NotFoundException;
+import org.eclipse.openk.contactbasedata.mapper.ContactMapper;
+import org.eclipse.openk.contactbasedata.mapper.ContactPersonMapper;
+import org.eclipse.openk.contactbasedata.model.TblContact;
+import org.eclipse.openk.contactbasedata.model.TblContactPerson;
+import org.eclipse.openk.contactbasedata.repository.*;
+import org.eclipse.openk.contactbasedata.viewmodel.ContactPersonDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.UUID;
+
+@Log4j2
+@Service
+public class ContactPersonService {
+
+    @Autowired
+    private ContactRepository contactRepository;
+
+    @Autowired
+    private ContactPersonRepository contactPersonRepository;
+
+    @Autowired
+    private CompanyRepository companyRepository;
+
+    @Autowired
+    private SalutationRepository salutationRepository;
+
+    @Autowired
+    private PersonTypeRepository personTypeRepository;
+
+    @Autowired
+    private ContactPersonMapper contactPersonMapper;
+
+    @Autowired
+    private ContactMapper contactMapper;
+
+
+    public ContactPersonDto findContactPerson(UUID contactPersonUuid) {
+        TblContactPerson tblContactPerson = contactPersonRepository
+                                                            .findByTblContactUuid(contactPersonUuid)
+                                                            .orElseThrow(() -> new NotFoundException("contact.uuid.not.existing"));
+       return contactPersonMapper.toContactPersonDto(tblContactPerson);
+    }
+
+    @Transactional
+    public ContactPersonDto insertContactPerson(ContactPersonDto contactPersonDto) {
+        TblContact contactToSave = new TblContact();
+        contactToSave.setUuid(UUID.randomUUID());
+        contactToSave.setContactType(Constants.CONTACT_TYPE_CONTACT_PERSON);
+
+        TblContactPerson contactPersonToSave = contactPersonMapper.toTblContactPerson(contactPersonDto);
+        contactPersonToSave.setContact(contactToSave);
+        contactRepository.save(contactPersonToSave.getContact());
+
+        setFromContactPersonDto( contactPersonToSave, contactPersonDto );
+
+        // Then save dependent Model-Object
+        return contactPersonMapper.toContactPersonDto(contactPersonRepository.save(contactPersonToSave));
+    }
+
+    @Transactional
+    public ContactPersonDto updateContactPerson(ContactPersonDto contactPersonDto){
+        TblContactPerson contactPersonUpdated;
+
+        TblContactPerson existingContactPerson = contactPersonRepository
+                .findByTblContactUuid(contactPersonDto.getContactUuid())
+                .orElseThrow(() -> new NotFoundException("contact.uuid.not.existing"));
+
+        existingContactPerson.setLastName(contactPersonDto.getLastName());
+        existingContactPerson.setFirstName(contactPersonDto.getFirstName());
+        existingContactPerson.setTitle(contactPersonDto.getTitle());
+
+        setFromContactPersonDto( existingContactPerson, contactPersonDto );
+        contactPersonUpdated = contactPersonRepository.save(existingContactPerson);
+
+        return contactPersonMapper.toContactPersonDto(contactPersonUpdated);
+    }
+
+    @Transactional
+    public void deleteContactPerson(UUID contactUuid) {
+        TblContact tblContact = contactRepository.findByUuid(contactUuid)
+                .orElseThrow(() -> new NotFoundException("contact.uuid.not.existing"));
+        TblContactPerson tblContactPerson = contactPersonRepository.findByTblContactUuid(contactUuid)
+                .orElseThrow(() -> new NotFoundException("contact.person.uuid.not.existing"));
+
+        contactPersonRepository.delete(tblContactPerson);
+        contactRepository.delete(tblContact);
+    }
+
+    private void setFromContactPersonDto( TblContactPerson destTblContactPerson, ContactPersonDto sourceDto ) {
+
+        if( sourceDto.getSalutationUuid() != null ) {
+            destTblContactPerson.setSalutation( salutationRepository
+                    .findByUuid(sourceDto.getSalutationUuid())
+                    .orElseThrow(() -> new NotFoundException("salutation.uuid.not.existing")));
+        }
+        else {
+            destTblContactPerson.setSalutation(null);
+        }
+
+        if( sourceDto.getPersonTypeUuid() != null ) {
+            destTblContactPerson.setRefPersonType( personTypeRepository
+                    .findByUuid(sourceDto.getPersonTypeUuid())
+                    .orElseThrow(() -> new NotFoundException("person.type.uuid.not.existing")));
+        }
+        else {
+            destTblContactPerson.setRefPersonType(null);
+        }
+
+        if( sourceDto.getCompanyContactUuid() != null ) {
+            destTblContactPerson.setCompany( companyRepository
+                    .findByTblContactUuid(sourceDto.getCompanyContactUuid())
+                    .orElseThrow(() -> new NotFoundException("company.contact.uuid.not.existing")));
+        }
+        else {
+            destTblContactPerson.setRefPersonType(null);
+        }
+
+        destTblContactPerson.getContact().setNote(sourceDto.getContactNote());
+    }
+}
diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties
index 120096c..5396952 100644
--- a/src/main/resources/messages.properties
+++ b/src/main/resources/messages.properties
@@ -14,3 +14,6 @@
 
 main.address.already.existing= F\u00fcdiesen Kontakt existiert bereits eine Hauptadresse
 communication.type.already.existing.for.contact= F\u00fcdiesen Kontakt existiert bereits dieser Kommunikationstyp
+company.contact.person.not.matching= Die \u00fcbergebenen UUIDs einer Firma und einer Kontaktperson passen nicht zueinander 
+company.contact.uuid.not.existing= Die \u00fcbergebene UUID einer Firma existiert nicht
+contact.person.uuid.not.existing= Die \u00fcbergebene UUID einer Kontaktperson existiert nicht
diff --git a/src/test/java/org/eclipse/openk/contactbasedata/config/TestConfiguration.java b/src/test/java/org/eclipse/openk/contactbasedata/config/TestConfiguration.java
index 1366b4a..fad5538 100644
--- a/src/test/java/org/eclipse/openk/contactbasedata/config/TestConfiguration.java
+++ b/src/test/java/org/eclipse/openk/contactbasedata/config/TestConfiguration.java
@@ -83,6 +83,9 @@
     public InternalPersonService myInternalPersonService() { return new InternalPersonService(); }
 
     @Bean
+    public ContactPersonService myContactPersonService() { return new ContactPersonService(); }
+
+    @Bean
     public CompanyService myCompanyService() { return new CompanyService(); }
 
     @Bean
diff --git a/src/test/java/org/eclipse/openk/contactbasedata/controller/ContactPersonControllerTest.java b/src/test/java/org/eclipse/openk/contactbasedata/controller/ContactPersonControllerTest.java
new file mode 100644
index 0000000..6a78eb7
--- /dev/null
+++ b/src/test/java/org/eclipse/openk/contactbasedata/controller/ContactPersonControllerTest.java
@@ -0,0 +1,110 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************
+ */
+package org.eclipse.openk.contactbasedata.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.eclipse.openk.contactbasedata.ContactBaseDataApplication;
+import org.eclipse.openk.contactbasedata.service.ContactPersonService;
+import org.eclipse.openk.contactbasedata.support.MockDataHelper;
+import org.eclipse.openk.contactbasedata.viewmodel.ContactPersonDto;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.web.servlet.MockMvc;
+import java.util.UUID;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+
+@SpringBootTest(classes = ContactBaseDataApplication.class)
+@AutoConfigureMockMvc
+@ActiveProfiles("test") // Todo: Find a better way to configure the tests
+public class ContactPersonControllerTest {
+
+    @MockBean
+    private ContactPersonService contactPersonService;
+
+    @Autowired
+    private MockMvc mockMvc;
+
+
+    @Test
+    public void shouldReturnARequestedContactPerson() throws Exception {
+        ContactPersonDto cp = MockDataHelper.mockContactPersonDto();
+
+        when(contactPersonService.findContactPerson(any(UUID.class))).thenReturn(cp);
+
+        mockMvc.perform(get("/contact-persons/"+UUID.randomUUID().toString()))
+                .andExpect(status().is2xxSuccessful())
+                .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+                .andExpect(jsonPath("firstName", is(  cp.getFirstName())));
+    }
+
+    @Test
+    public void shouldUpdateContactPerson() throws Exception {
+        ContactPersonDto cp = MockDataHelper.mockContactPersonDto();
+
+        when( contactPersonService.updateContactPerson(any(ContactPersonDto.class))).thenReturn(cp);
+
+        mockMvc.perform(put("/contact-persons/{uuid}", cp.getContactUuid().toString())
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(new ObjectMapper().writeValueAsString(cp)))
+                .andExpect(status().is2xxSuccessful());
+    }
+
+    @Test
+    public void shouldNotUpdateContactPersonDueToException() throws Exception {
+        ContactPersonDto cp = MockDataHelper.mockContactPersonDto();
+
+        when( contactPersonService.updateContactPerson(any(ContactPersonDto.class))).thenReturn(cp);
+
+        // provide different uuid in url and object
+        mockMvc.perform(put("/contact-persons/{uuid}", UUID.randomUUID().toString())
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(new ObjectMapper().writeValueAsString(cp)))
+                .andExpect(status().isBadRequest());
+    }
+
+    @Test
+    public void shouldInsertContactPerson() throws Exception {
+        ContactPersonDto cp = MockDataHelper.mockContactPersonDto();
+
+        when( contactPersonService.insertContactPerson(any(ContactPersonDto.class))).thenReturn(cp);
+
+        mockMvc.perform(post("/contact-persons")
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(new ObjectMapper().writeValueAsString(cp)))
+                .andExpect(jsonPath("$.lastName", is(cp.getLastName())))
+                .andExpect(jsonPath("$.contactId", not(cp.getContactUuid())))
+                .andExpect(jsonPath("$.contactNote", is(cp.getContactNote())))
+                .andExpect(status().is2xxSuccessful());
+    }
+
+    @Test
+    public void shouldDeleteAddress() throws Exception {
+        mockMvc.perform(delete("/contact-persons/{contactUuid}", UUID.randomUUID(), UUID.randomUUID())
+                .contentType(MediaType.APPLICATION_JSON))
+                .andExpect(status().is2xxSuccessful());
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/eclipse/openk/contactbasedata/service/ContactPersonServiceTest.java b/src/test/java/org/eclipse/openk/contactbasedata/service/ContactPersonServiceTest.java
new file mode 100644
index 0000000..ef3a722
--- /dev/null
+++ b/src/test/java/org/eclipse/openk/contactbasedata/service/ContactPersonServiceTest.java
@@ -0,0 +1,199 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2019 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************
+ */
+package org.eclipse.openk.contactbasedata.service;
+
+import org.eclipse.openk.contactbasedata.config.TestConfiguration;
+import org.eclipse.openk.contactbasedata.exceptions.NotFoundException;
+import org.eclipse.openk.contactbasedata.model.*;
+import org.eclipse.openk.contactbasedata.repository.*;
+import org.eclipse.openk.contactbasedata.support.MockDataHelper;
+import org.eclipse.openk.contactbasedata.viewmodel.ContactPersonDto;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.mockito.stubbing.Answer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.ContextConfiguration;
+import java.util.Optional;
+import java.util.UUID;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+
+@DataJpaTest
+@ContextConfiguration(classes = {TestConfiguration.class})
+
+public class ContactPersonServiceTest {
+    @Qualifier("myContactPersonService")
+    @Autowired
+    private ContactPersonService contactPersonService;
+
+    @MockBean
+    private ContactPersonRepository contactPersonRepository;
+
+    @MockBean
+    private ContactRepository contactRepository;
+
+    @MockBean
+    private SalutationRepository salutationRepository;
+
+    @MockBean
+    private PersonTypeRepository personTypeRepository;
+
+    @MockBean
+    private CompanyRepository companyRepository;
+
+    @Test
+    public void shouldFindAContactPersonProperly() {
+        TblContactPerson cp = MockDataHelper.mockTblContactPerson();
+        when(contactPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(cp));
+        ContactPersonDto dto = contactPersonService.findContactPerson(UUID.randomUUID());
+
+        assertEquals(cp.getContact().getUuid(), dto.getContactUuid());
+    }
+
+    @Test
+    public void shouldThrowNotFoundErrorContactPerson() {
+        TblContactPerson cp = MockDataHelper.mockTblContactPerson();
+        when(contactPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.empty());
+        assertThrows(NotFoundException.class, () -> contactPersonService.findContactPerson(UUID.randomUUID()));
+    }
+
+    @Test
+    public void shouldUpdateContactPerson() {
+        ContactPersonDto cpDto = MockDataHelper.mockContactPersonDto();
+        TblContactPerson cpTbl = MockDataHelper.mockTblContactPerson();
+
+        when(contactPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(cpTbl));
+        when(salutationRepository.findByUuid(any(UUID.class)))
+                .thenReturn(Optional.of(MockDataHelper.mockRefSalutation()));
+        when(personTypeRepository.findByUuid(any(UUID.class)))
+                .thenReturn(Optional.of(MockDataHelper.mockRefPersonType()));
+        when(companyRepository.findByTblContactUuid(any(UUID.class)))
+                .thenReturn(Optional.of(MockDataHelper.mockCompany()));
+//        when(contactPersonRepository.save(any(TblContactPerson.class)))
+//                .thenReturn(cpTbl);
+        when(contactPersonRepository.save(any(TblContactPerson.class)))
+                .then((Answer<TblContactPerson>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (TblContactPerson) args[0];
+                });
+
+        ContactPersonDto savedDto = contactPersonService.updateContactPerson(cpDto);
+
+        assertEquals(cpTbl.getContact().getUuid(), savedDto.getContactUuid());
+        assertEquals(cpTbl.getContact().getNote(), savedDto.getContactNote());
+        assertEquals(cpTbl.getContact().getContactType(), savedDto.getContactType());
+        assertEquals(cpTbl.getFirstName(), savedDto.getFirstName());
+        assertEquals(cpTbl.getLastName(), savedDto.getLastName());
+        assertEquals(cpTbl.getTitle(), savedDto.getTitle());
+        assertEquals(cpTbl.getRefPersonType().getUuid(), savedDto.getPersonTypeUuid());
+        assertEquals(cpTbl.getSalutation().getUuid(), savedDto.getSalutationUuid());
+    }
+
+
+    @Test
+    public void shouldNotUpdateContactPerson_Exception1() {
+        ContactPersonDto epDto = MockDataHelper.mockContactPersonDto();
+        TblContactPerson cpTbl = MockDataHelper.mockTblContactPerson();
+        when(contactPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.empty());
+        when(salutationRepository.findByUuid(any(UUID.class)))
+                .thenReturn(Optional.of(MockDataHelper.mockRefSalutation()));
+        when(personTypeRepository.findByUuid(any(UUID.class)))
+                .thenReturn(Optional.of(MockDataHelper.mockRefPersonType()));
+
+        when(contactPersonRepository.save(any(TblContactPerson.class)))
+                .then((Answer<TblContactPerson>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (TblContactPerson) args[0];
+                });
+
+        assertThrows( NotFoundException.class, () -> contactPersonService.updateContactPerson(epDto));
+    }
+
+    @Test
+    public void shouldNotUpdateContactPerson_Exception2() {
+        ContactPersonDto cpDto = MockDataHelper.mockContactPersonDto();
+        TblContactPerson cpTbl = MockDataHelper.mockTblContactPerson();
+        when(contactPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(cpTbl));
+        when(salutationRepository.findByUuid(any(UUID.class)))
+                .thenReturn(Optional.empty());
+        when(personTypeRepository.findByUuid(any(UUID.class)))
+                .thenReturn(Optional.of(MockDataHelper.mockRefPersonType()));
+
+        when(contactPersonRepository.save(any(TblContactPerson.class)))
+                .then((Answer<TblContactPerson>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (TblContactPerson) args[0];
+                });
+
+        assertThrows( NotFoundException.class, () -> contactPersonService.updateContactPerson(cpDto));
+    }
+
+
+    @Test
+    public void shouldInsertContactPerson() {
+        ContactPersonDto cpDto = MockDataHelper.mockContactPersonDto();
+        cpDto.setContactUuid(null);
+        RefSalutation refSalutation = MockDataHelper.mockRefSalutation();
+        when(salutationRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(refSalutation));
+        RefPersonType refPersonType = MockDataHelper.mockRefPersonType();
+        when(personTypeRepository.findByUuid(any(UUID.class))).thenReturn(Optional.of(refPersonType));
+        TblCompany tblCompany = MockDataHelper.mockCompany();
+        when(companyRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(tblCompany));
+
+        when(contactRepository.save(any(TblContact.class)))
+                .then((Answer<TblContact>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (TblContact) args[0];
+                });
+        when(contactPersonRepository.save(any(TblContactPerson.class)))
+                .then((Answer<TblContactPerson>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (TblContactPerson) args[0];
+                });
+
+        ContactPersonDto savedDto = contactPersonService.insertContactPerson(cpDto);
+        assertNotNull(savedDto.getContactUuid());
+        assertEquals(cpDto.getContactNote(), savedDto.getContactNote());
+        assertEquals(cpDto.getContactType(), savedDto.getContactType());
+        assertEquals(cpDto.getFirstName(), savedDto.getFirstName());
+        assertEquals(cpDto.getLastName(), savedDto.getLastName());
+        assertEquals(cpDto.getTitle(), savedDto.getTitle());
+        assertEquals(refPersonType.getUuid(), savedDto.getPersonTypeUuid());
+        assertEquals(refSalutation.getUuid(), savedDto.getSalutationUuid());
+    }
+    
+    @Test
+    public void shouldDeleteContactPerson() {
+        TblContactPerson tblContactPerson = MockDataHelper.mockTblContactPerson();
+        TblContact tblContact = MockDataHelper.mockTblContact();
+        tblContactPerson.setContact(tblContact);
+
+        when (contactRepository.findByUuid( any(UUID.class))).thenReturn(Optional.of(tblContact));
+        when(contactPersonRepository.findByTblContactUuid(any(UUID.class))).thenReturn(Optional.of(tblContactPerson));
+        Mockito.doNothing().when(contactPersonRepository).delete( isA( TblContactPerson.class ));
+        Mockito.doNothing().when(contactRepository).delete( isA( TblContact.class ));
+
+        contactPersonService.deleteContactPerson(tblContact.getUuid());
+
+        Mockito.verify(contactPersonRepository, times(1)).delete( tblContactPerson );
+        Mockito.verify(contactRepository, times(1)).delete( tblContact );
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/eclipse/openk/contactbasedata/support/MockDataHelper.java b/src/test/java/org/eclipse/openk/contactbasedata/support/MockDataHelper.java
index 7a413f8..cb64457 100644
--- a/src/test/java/org/eclipse/openk/contactbasedata/support/MockDataHelper.java
+++ b/src/test/java/org/eclipse/openk/contactbasedata/support/MockDataHelper.java
@@ -487,6 +487,9 @@
         cp.setContact(mockTblContact());
         cp.setFirstName("Prober");
         cp.setLastName("Cottwick");
+        cp.setRefPersonType(mockRefPersonType());
+        cp.setSalutation(mockRefSalutation());
+        cp.setContact(mockTblContact());
         return cp;
     }
 
@@ -504,6 +507,11 @@
         contactPersonDto.setLastName("Cottwick");
         contactPersonDto.setCompanyType(Constants.CONTACT_TYPE_CONTACT_PERSON);
         contactPersonDto.setTitle("Prof. Dr.");
+        contactPersonDto.setContactUuid(UUID.randomUUID());
+        contactPersonDto.setContactType("C_P");
+        contactPersonDto.setContactNote("eine Notiz");
+        contactPersonDto.setSalutationUuid(UUID.randomUUID());
+        contactPersonDto.setPersonTypeUuid(UUID.randomUUID());
         return contactPersonDto;
     }