package cz.muni.fi.pa165.core.user;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import cz.muni.fi.pa165.core.company.Company;
import cz.muni.fi.pa165.core.company.CompanyService;
import cz.muni.fi.pa165.core.house.House;
import cz.muni.fi.pa165.core.house.HouseService;
import cz.muni.fi.pa165.core.metrics.Metrics;
import cz.muni.fi.pa165.core.metrics.MetricsService;
import cz.muni.fi.pa165.core.smartmeter.SmartMeter;
import cz.muni.fi.pa165.core.smartmeter.SmartMeterService;
import cz.muni.fi.pa165.core.user.roles.CompanyRole;
import cz.muni.fi.pa165.core.user.roles.HouseRole;
import cz.muni.fi.pa165.core.user.roles.RoleService;
import cz.muni.fi.pa165.model.dto.common.Result;
import cz.muni.fi.pa165.model.dto.house.HouseDto;
import cz.muni.fi.pa165.model.dto.role.enums.RoleTypeEnum;
import cz.muni.fi.pa165.model.dto.user.*;
import jakarta.persistence.EntityNotFoundException;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
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.security.test.context.support.WithMockUser;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;

import java.util.List;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
 * Integration tests for the {@link UserController} class.
 *
 * @author xskacel
 */
@SpringBootTest
@WithMockUser
@AutoConfigureMockMvc(addFilters = false)
@TestPropertySource(locations = "classpath:application-test.properties")
public class UserControllerTest {
	@Autowired
	private MockMvc mockMvc;
	@Autowired
	private ObjectMapper objectMapper;
	@Autowired
	private UserFacade userFacade;
	@Autowired
	private UserService userService;

	@Autowired
	private UserMapper userMapper;

	@Autowired
	private MetricsService metricsService;

	@Autowired
	private SmartMeterService smartMeterService;

	@Autowired
	private HouseService houseService;

	@Autowired
	private CompanyService companyService;

	@Autowired
	private RoleService roleService;

	@Autowired
	private UserRepository userReposiroyMock;

	private final static String URL = "/api/user";
	private final static String CONTENT_TYPE = "application/json";

	@BeforeEach
	void setUp() {
		UserCreateDto createDto1 = new UserCreateDto();
		createDto1.setUsername("skaci");
		createDto1.setPassword("testPassword");
		createDto1.setFirstName("Marek");
		createDto1.setLastName("Bogo");
		createDto1.setEmail("Bozo@test.com");
		userFacade.create(createDto1);

		UserCreateDto createDto2 = new UserCreateDto();
		createDto2.setUsername("paci");
		createDto2.setPassword("asdasd");
		createDto2.setFirstName("eeerrs");
		createDto2.setLastName("lslsls");
		createDto2.setEmail("aeeradfa@cdscsd.cz");
		userFacade.create(createDto2);
	}

	@AfterEach
	void cleanUp() {
		roleService.hardDeleteAll();
		metricsService.hardDeleteAll();
		smartMeterService.hardDeleteAll();
		companyService.hardDeleteAll();
		houseService.hardDeleteAll();
		userService.hardDeleteAll();
	}


	/**
	 * Tests the {@link UserController#create(UserCreateDto)} method with valid input.
	 * Expects the response status code to be <201> (Created).
	 */
	@Test
	void shouldCreateValidUser() throws Exception {
		// Prepare
		UserCreateDto createDto = new UserCreateDto();
		createDto.setUsername("testUser");
		createDto.setPassword("testPassword");
		createDto.setFirstName("John");
		createDto.setLastName("Doe");
		createDto.setEmail("johndoe@test.com");

		// Testing if created user is in Repository (should not be)
		assertNull(userService.findByUsername(createDto.getUsername()));

		// Execute
		String response = mockMvc.perform(post(URL)
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(createDto)))
				.andExpect(status().isCreated())
				.andReturn()
				.getResponse()
				.getContentAsString();

		// Verify
		UserDto userDto = objectMapper.readValue(response, UserDto.class);
		assertThat(userDto.getId()).isNotNull();
		assertThat(userDto.getUsername()).isEqualTo(createDto.getUsername());
		assertThat(userDto.getEmail()).isEqualTo(createDto.getEmail());
		assertThat(userDto.getFirstName()).isEqualTo(createDto.getFirstName());
		assertThat(userDto.getLastName()).isEqualTo(createDto.getLastName());
		assertDoesNotThrow(() -> userService.findById(userDto.getId()));
	}

	/**
	 * Tests attempting to create a user with a username that already exists.
	 * Expects the response status code to be <409> (Conflict).
	 */
	@Test
	void shouldNotCreateUserThatAlreadyExists() throws Exception {
		// Prepare
		UserCreateDto createDto = new UserCreateDto();
		createDto.setUsername("skaci");
		createDto.setPassword("testPassword");
		createDto.setFirstName("John");
		createDto.setLastName("Doe");
		createDto.setEmail("johndoe@test.com");
		assertNotNull(userService.findByUsername(createDto.getUsername()));
		mockMvc.perform(post(URL)
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(createDto)))
				.andExpect(status().isConflict())
				.andExpect(content().string("User with given username already exists"));

		assertNotNull(userService.findByUsername(createDto.getUsername()));
	}

	/**
	 * Tests the deletion of an existing user.
	 * Expects the response status code to be <200>.
	 */
	@Test
	void shouldDeleteExistingUser() throws Exception {
		List<UserDto> userDtoList = userFacade.findAll();
		assertTrue(userDtoList.size() > 0);
		UserDto userToDelete = userDtoList.get(0);
		assertDoesNotThrow(() -> userService.findById(userToDelete.getId()));

		// Execute
		String response = mockMvc.perform(delete(
						URL + "/{id}", userToDelete.getId())
						.contentType(CONTENT_TYPE))
				.andExpect(status().isOk())
				.andReturn()
				.getResponse()
				.getContentAsString();

		// Verify
		UserDto userDto = objectMapper.readValue(response, UserDto.class);
		assertThat(userDto.getId()).isEqualTo(userToDelete.getId());
		assertThat(userDto.getUsername()).isEqualTo(userToDelete.getUsername());
		assertThat(userDto.getEmail()).isEqualTo(userToDelete.getEmail());
		assertThat(userDto.getFirstName()).isEqualTo(userToDelete.getFirstName());
		assertThat(userDto.getLastName()).isEqualTo(userToDelete.getLastName());
		assertThrows(EntityNotFoundException.class, () -> userService.findById(userToDelete.getId()));
	}

	/**
	 * Tests the deletion of an existing user.
	 * Expects the response status code to be <200>.
	 */
	@Test
	void shouldNotDeleteUserThatDoesNotExists() throws Exception {
		// nonsense ID
		final String id = "0000xxxx1111";
		assertThrows(EntityNotFoundException.class, () -> userService.findById(id));

		// Execute
		mockMvc.perform(delete(
						URL + "/{id}", id)
						.contentType(CONTENT_TYPE))
				.andExpect(status().isNotFound())
				.andExpect(content().string("Entity with '" + id + "' not found."));
	}

	/**
	 * Tests the {@link UserController#updateById(String, UserUpdateDto)} method with valid input.
	 * Expects the response status code to be <200>.
	 */
	@Test
	void shouldUpdateValidUser() throws Exception {
		// Prepare
		List<UserDto> userDtoList = userFacade.findAll();
		assertTrue(userDtoList.size() > 0);
		UserDto userToUpdate = userDtoList.get(0);

		UserUpdateDto userUpdateDto = new UserUpdateDto();
		userUpdateDto.setUsername("newSkaci");
		userUpdateDto.setPassword("password");
		userUpdateDto.setFirstName("Goku");
		userUpdateDto.setLastName("KidBuu");
		userUpdateDto.setEmail("goku@test.com");

		// Testing if updated user is in Repository (should not be)
		assertNull(userService.findByUsername(userUpdateDto.getUsername()));
		assertNotNull(userService.findByUsername(userToUpdate.getUsername()));

		// Execute
		String response = mockMvc.perform(put(URL + "/{id}", userToUpdate.getId())
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(userUpdateDto)))
				.andExpect(status().isOk())
				.andReturn()
				.getResponse()
				.getContentAsString();

		// Verify
		UserDto userDto = objectMapper.readValue(response, UserDto.class);
		assertThat(userDto.getId()).isEqualTo(userToUpdate.getId());
		assertThat(userDto.getUsername()).isEqualTo(userUpdateDto.getUsername());
		assertThat(userDto.getEmail()).isEqualTo(userUpdateDto.getEmail());
		assertThat(userDto.getFirstName()).isEqualTo(userUpdateDto.getFirstName());
		assertThat(userDto.getLastName()).isEqualTo(userUpdateDto.getLastName());

		assertDoesNotThrow(() -> userService.findById(userDto.getId()));

		assertNotNull(userService.findByUsername(userUpdateDto.getUsername()));
		assertNull(userService.findByUsername(userToUpdate.getUsername()));
		assertEquals(userService.findAll().size(), userDtoList.size());
	}

	/**
	 * Tests the {@link UserController#updateById(String, UserUpdateDto)} method with valid input
	 * But with username that already exists in the database.
	 * Expects the response status code to be <409>.
	 */
	@Test
	void shouldNotUpdateUserUsernameThatAlreadyExists() throws Exception {
		List<UserDto> userDtoList = userFacade.findAll();
		assertTrue(userDtoList.size() > 0);
		UserDto userToUpdate = userDtoList.get(0);

		UserUpdateDto userUpdateDto = new UserUpdateDto();
		userUpdateDto.setUsername("paci");
		userUpdateDto.setPassword("password");
		userUpdateDto.setFirstName("Goku");
		userUpdateDto.setLastName("KidBuu");
		userUpdateDto.setEmail("goku@test.com");

		// Testing if updated user is in Repository (in this case it should)
		assertNotNull(userService.findByUsername(userUpdateDto.getUsername()));
		assertNotNull(userService.findByUsername(userToUpdate.getUsername()));

		// Execute
		mockMvc.perform(put(URL + "/{id}", userToUpdate.getId())
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(userUpdateDto)))
				.andExpect(status().isConflict())
				.andExpect(content().string("User with given username already exists"));

		// Verify (nothing changed)
		assertDoesNotThrow(() -> userService.findById(userToUpdate.getId()));
		UserDto userDto = userFacade.findById(userToUpdate.getId());
		assertThat(userDto.getId()).isEqualTo(userToUpdate.getId());
		assertThat(userDto.getUsername()).isEqualTo(userToUpdate.getUsername());
		assertThat(userDto.getEmail()).isEqualTo(userToUpdate.getEmail());
		assertThat(userDto.getFirstName()).isEqualTo(userToUpdate.getFirstName());
		assertThat(userDto.getLastName()).isEqualTo(userToUpdate.getLastName());

		assertNotNull(userService.findByUsername(userUpdateDto.getUsername()));
		assertNotNull(userService.findByUsername(userToUpdate.getUsername()));
		assertEquals(userService.findAll().size(), userDtoList.size());
	}

	/**
	 * Tests the {@link UserController#updateById(String, UserUpdateDto)} with ID
	 * that does not exist in the db.
	 * Expects the response status code to be <409>.
	 */
	@Test
	void shouldNotUpdateUserThatDoesNotExist() throws Exception {
		// nonsense ID
		final String id = "0000xxxx1111";
		assertThrows(EntityNotFoundException.class, () -> userService.findById(id));

		UserUpdateDto userUpdateDto = new UserUpdateDto();
		userUpdateDto.setUsername("ooo");
		userUpdateDto.setPassword("Password");
		userUpdateDto.setFirstName("Goku");
		userUpdateDto.setLastName("KidBuu");
		userUpdateDto.setEmail("goku@test.com");

		// Execute
		mockMvc.perform(put(URL + "/{id}", id)
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(userUpdateDto)))
				.andExpect(status().isNotFound())
				.andExpect(content().string("Entity with '" + id + "' not found."));

	}

	@Test
	void shouldLogout() throws Exception {
		// Execute
		mockMvc.perform(post(URL + "/logout")
						.contentType(CONTENT_TYPE))
				.andExpect(status().isOk())
				.andExpect(content().string("Logged out successfully."));
	}

	@Test
	void shouldLoginSuccessfully() throws Exception {
		final LoginInfoDto loginInfoDto = new LoginInfoDto();
		loginInfoDto.setUsername("skaci");
		loginInfoDto.setPassword("testPassword");


		// Execute
		mockMvc.perform(post(URL + "/login")
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(loginInfoDto)))
				.andExpect(status().isOk())
				.andExpect(content().string("Login successful."));
	}


	@Test
	void shouldNotLoginSuccessfullyBecauseOfBadPassword() throws Exception {
		final LoginInfoDto loginInfoDto = new LoginInfoDto();
		loginInfoDto.setUsername("skaci");
		loginInfoDto.setPassword("wrongPassword");

		// Execute
		mockMvc.perform(post(URL + "/login")
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(loginInfoDto)))
				.andExpect(status().isUnauthorized())
				.andExpect(content().string("Invalid username or password."));
	}

	@Test
	void shouldNotLoginSuccessfullyBecauseOfBadUsername() throws Exception {
		final LoginInfoDto loginInfoDto = new LoginInfoDto();
		loginInfoDto.setUsername("blabla");
		loginInfoDto.setPassword("testPassword");

		// Execute
		mockMvc.perform(post(URL + "/login")
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(loginInfoDto)))
				.andExpect(status().isUnauthorized())
				.andExpect(content().string("Invalid username or password."));
	}

	@Test
	void shouldChangePassword() throws Exception {
		final ChangePasswordDto changePasswordDto = new ChangePasswordDto();
		changePasswordDto.setOldPassword("SomeIrrelevantDataAtm");
		changePasswordDto.setNewPassword("blablaBla");
		changePasswordDto.setNewPasswordConfirmation("blablaBla");

		// Execute
		mockMvc.perform(put(URL + "/password")
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(changePasswordDto)))
				.andExpect(status().isOk())
				.andExpect(content().string("Password changed successfully."));
	}

	@Test
	void shouldNotChangePasswordSincePasswordsDoNotEqual() throws Exception {
		final ChangePasswordDto changePasswordDto = new ChangePasswordDto();
		changePasswordDto.setOldPassword("SomeIrrelevantDataAtm");
		changePasswordDto.setNewPassword("onePassword");
		changePasswordDto.setNewPasswordConfirmation("secondPassword");

		// Execute
		mockMvc.perform(put(URL + "/password")
						.contentType(CONTENT_TYPE)
						.content(objectMapper.writeValueAsString(changePasswordDto)))
				.andExpect(status().isBadRequest())
				.andExpect(content().string("New password and confirmation password do not match."));
	}

	@Test
	void shouldFindValidUserById() throws Exception {
		List<UserDto> userDtoList = userFacade.findAll();
		assertTrue(userDtoList.size() > 0);
		UserDto userToFind = userDtoList.get(0);
		assertDoesNotThrow(() -> userService.findById(userToFind.getId()));

		// Execute
		String response = mockMvc.perform(get(URL + "/{id}", userToFind.getId())
						.contentType(CONTENT_TYPE))
				.andExpect(status().isOk())
				.andReturn()
				.getResponse()
				.getContentAsString();

		// Verify
		UserDto userDto = objectMapper.readValue(response, UserDto.class);
		assertThat(userDto.getId()).isEqualTo(userToFind.getId());
		assertThat(userDto.getUsername()).isEqualTo(userToFind.getUsername());
		assertThat(userDto.getEmail()).isEqualTo(userToFind.getEmail());
		assertThat(userDto.getFirstName()).isEqualTo(userToFind.getFirstName());
		assertThat(userDto.getLastName()).isEqualTo(userToFind.getLastName());
	}

	@Test
	void shouldNotFindUserByNonExistingId() throws Exception {
		// nonsense ID
		final String id = "0000xxxx1111";
		assertThrows(EntityNotFoundException.class, () -> userService.findById(id));

		// Execute
		mockMvc.perform(get(URL + "/{id}", id)
						.contentType(CONTENT_TYPE))
				.andExpect(status().isNotFound())
				.andExpect(content().string("Entity with '" + id + "' not found."));
	}

	@Test
	void shouldFindAllUsers() throws Exception {
		// Execute
		String response = mockMvc.perform(get(URL + "?page=0")
						.contentType(CONTENT_TYPE))
				.andExpect(status().isOk())
				.andReturn()
				.getResponse()
				.getContentAsString();

		Result<UserDto> userDtoResult = objectMapper.readValue(response, new TypeReference<>() {
		});
		assertThat(userDtoResult.getPage()).isEqualTo(0);
		assertThat(userDtoResult.getPageSize()).isEqualTo(10);
		assertThat(userDtoResult.getTotal()).isEqualTo(2);

		final UserDto firstUserFromResponse = userDtoResult.getItems().get(0);
		UserDto userDto1 = new UserDto();
		userDto1.setUsername("skaci");
		userDto1.setFirstName("Marek");
		userDto1.setLastName("Bogo");
		userDto1.setEmail("Bozo@test.com");
		assertThat(firstUserFromResponse.getUsername()).isEqualTo(userDto1.getUsername());
		assertThat(firstUserFromResponse.getFirstName()).isEqualTo(userDto1.getFirstName());
		assertThat(firstUserFromResponse.getLastName()).isEqualTo(userDto1.getLastName());
		assertThat(firstUserFromResponse.getEmail()).isEqualTo(userDto1.getEmail());

		final UserDto secondUserFromResponse = userDtoResult.getItems().get(1);
		UserDto userDto2 = new UserDto();
		userDto2.setUsername("paci");
		userDto2.setFirstName("eeerrs");
		userDto2.setLastName("lslsls");
		userDto2.setEmail("aeeradfa@cdscsd.cz");

		assertThat(secondUserFromResponse.getUsername()).isEqualTo(userDto2.getUsername());
		assertThat(secondUserFromResponse.getFirstName()).isEqualTo(userDto2.getFirstName());
		assertThat(secondUserFromResponse.getLastName()).isEqualTo(userDto2.getLastName());
		assertThat(secondUserFromResponse.getEmail()).isEqualTo(userDto2.getEmail());
	}

	@Test
	void onDeleteHouseRoleUserAllEntitiesShouldBeDeleted() {

		// arrange
		User user = User.builder()
				.username("username")
				.lastName("lastname")
				.password("passwd")
				.email("mail@gmail.com").build();
		user = userService.create(user);

		House house = House.builder()
				.address("house123").build();
		house = houseService.create(house);

		HouseRole role = HouseRole.builder().build();
		role.setUser(user);
		role.setHouse(house);
		role.setRoleType(RoleTypeEnum.HouseRole);
		roleService.create(role);

		SmartMeter smartMeter = SmartMeter.builder()
				.name("smartMeterTest")
				.house(house).build();
		smartMeter = smartMeterService.create(smartMeter);

		Metrics metrics = Metrics.builder()
				.smartMeter(smartMeter)
				.consumptionKWH(5)
				.build();
		Metrics metricsv2 = metricsService.create(metrics);

		// act
		try {
			userFacade.deleteHouseUserById(user.getId());
		} catch (Exception e) {
			Assertions.assertThat(false).isTrue();
		}

		// assert
		assertThrows(Exception.class, () -> {
			metricsService.findById(metricsv2.getId());
		});

		SmartMeter finalSmartMeter = smartMeter;
		assertThrows(Exception.class, () -> {
			smartMeterService.findById(finalSmartMeter.getId());
		});

		assertThrows(Exception.class, () -> {
			roleService.findById(role.getId());
		});

		House finalHouse = house;
		assertThrows(Exception.class, () -> {
			houseService.findById(finalHouse.getId());
		});

		User finalUser = user;
		assertThrows(Exception.class, () -> {
			userService.findById(finalUser.getId());
		});
	}


	@Test
	void findAllCustomers() throws Exception {
		userService.hardDeleteAll();
		User user1 = User.builder()
				.username("username")
				.lastName("lastname")
				.password("passwd")
				.email("mail@gmail.com").build();
		user1 = userService.create(user1);

		House house1 = House.builder()
				.address("house123").build();
		house1 = houseService.create(house1);

		HouseRole role1 = HouseRole.builder().build();
		role1.setUser(user1);
		role1.setHouse(house1);
		role1.setRoleType(RoleTypeEnum.HouseRole);
		roleService.create(role1);

		House house2 = House.builder()
				.address("house2").build();
		house2 = houseService.create(house2);

		HouseRole role2 = HouseRole.builder().build();
		role2.setUser(user1);
		role2.setHouse(house2);
		role2.setRoleType(RoleTypeEnum.HouseRole);
		roleService.create(role2);

		User user2 = User.builder()
				.username("username2")
				.lastName("lastname")
				.password("passwd")
				.email("mail@gmail.com").build();
		user2 = userService.create(user2);

		Company company1 = Company.builder().name("company1").build();
		company1 = companyService.create(company1);

		CompanyRole role3 = CompanyRole.builder().build();
		role3.setUser(user2);
		role3.setCompany(company1);
		role3.setRoleType(RoleTypeEnum.CompanyRole);
		roleService.create(role3);

		String response = mockMvc.perform(get(URL + "/customers")
						.contentType(CONTENT_TYPE))
				.andExpect(status().isOk())
				.andReturn()
				.getResponse()
				.getContentAsString();

		List<UserDto> customers = objectMapper.readValue(response, new TypeReference<>() {
		});
		assertThat(customers.size()).isEqualTo(1);
	}

	@Test
	void findAllEmployees() throws Exception {
		userService.hardDeleteAll();
		User user1 = User.builder()
				.username("username")
				.lastName("lastname")
				.password("passwd")
				.email("mail@gmail.com").build();
		user1 = userService.create(user1);

		House house1 = House.builder()
				.address("house123").build();
		house1 = houseService.create(house1);

		HouseRole role1 = HouseRole.builder().build();
		role1.setUser(user1);
		role1.setHouse(house1);
		role1.setRoleType(RoleTypeEnum.HouseRole);
		roleService.create(role1);

		Company company1 = Company.builder().name("company1").build();
		company1 = companyService.create(company1);

		CompanyRole role2 = CompanyRole.builder().build();
		role2.setUser(user1);
		role2.setCompany(company1);
		role2.setRoleType(RoleTypeEnum.CompanyRole);
		roleService.create(role2);

		User user2 = User.builder()
				.username("username2")
				.lastName("lastname")
				.password("passwd")
				.email("mail@gmail.com").build();
		user2 = userService.create(user2);

		CompanyRole role3 = CompanyRole.builder().build();
		role3.setUser(user2);
		role3.setCompany(company1);
		role3.setRoleType(RoleTypeEnum.CompanyRole);
		roleService.create(role3);

		String response = mockMvc.perform(get(URL + "/employees")
						.contentType(CONTENT_TYPE))
				.andExpect(status().isOk())
				.andReturn()
				.getResponse()
				.getContentAsString();

		List<UserDto> customers = objectMapper.readValue(response, new TypeReference<>() {
		});
		assertThat(customers.size()).isEqualTo(2);
	}

	@Test
	void findHousesById() throws Exception {
		userService.hardDeleteAll();
		User user1 = User.builder()
				.username("username")
				.lastName("lastname")
				.password("passwd")
				.email("mail@gmail.com").build();
		user1 = userService.create(user1);

		House house1 = House.builder()
				.address("house123").build();
		house1 = houseService.create(house1);

		HouseRole role1 = HouseRole.builder().build();
		role1.setUser(user1);
		role1.setHouse(house1);
		role1.setRoleType(RoleTypeEnum.HouseRole);
		roleService.create(role1);

		House house2 = House.builder()
				.address("house2").build();
		house2 = houseService.create(house2);

		HouseRole role2 = HouseRole.builder().build();
		role2.setUser(user1);
		role2.setHouse(house2);
		role2.setRoleType(RoleTypeEnum.HouseRole);
		roleService.create(role2);

		String response = mockMvc.perform(get(URL + "/houses/{id}", user1.getId())
						.contentType(CONTENT_TYPE))
				.andExpect(status().isOk())
				.andReturn()
				.getResponse()
				.getContentAsString();

		List<HouseDto> houses = objectMapper.readValue(response, new TypeReference<>() {
		});
		assertThat(houses.size()).isEqualTo(2);
	}
}
