Backfill user accounts
This commit is contained in:
@@ -4,23 +4,31 @@ import com.petshop.backend.dto.common.BulkDeleteRequest;
|
||||
import com.petshop.backend.dto.customer.CustomerRequest;
|
||||
import com.petshop.backend.dto.customer.CustomerResponse;
|
||||
import com.petshop.backend.entity.Customer;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.exception.ResourceNotFoundException;
|
||||
import com.petshop.backend.repository.CustomerRepository;
|
||||
import com.petshop.backend.repository.UserRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class CustomerService {
|
||||
|
||||
private static final String TEMP_PASSWORD = "TempPass123!";
|
||||
|
||||
private final CustomerRepository customerRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final UserBusinessLinkageService userBusinessLinkageService;
|
||||
|
||||
public CustomerService(CustomerRepository customerRepository, UserRepository userRepository) {
|
||||
public CustomerService(CustomerRepository customerRepository, UserRepository userRepository, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService) {
|
||||
this.customerRepository = customerRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.userBusinessLinkageService = userBusinessLinkageService;
|
||||
}
|
||||
|
||||
public Page<CustomerResponse> getAllCustomers(String query, Pageable pageable) {
|
||||
@@ -47,8 +55,13 @@ public class CustomerService {
|
||||
customer.setEmail(request.getEmail());
|
||||
|
||||
customer = customerRepository.save(customer);
|
||||
syncLinkedUser(customer);
|
||||
return mapToResponse(customer);
|
||||
Customer savedCustomer = customer;
|
||||
User user = userRepository.findByEmail(savedCustomer.getEmail())
|
||||
.orElseGet(() -> createLinkedUser(savedCustomer));
|
||||
|
||||
Customer linkedCustomer = userBusinessLinkageService.ensureLinkedCustomer(user);
|
||||
syncLinkedUser(linkedCustomer);
|
||||
return mapToResponse(linkedCustomer);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -99,4 +112,25 @@ public class CustomerService {
|
||||
userRepository.save(user);
|
||||
});
|
||||
}
|
||||
|
||||
private User createLinkedUser(Customer customer) {
|
||||
User user = new User();
|
||||
user.setUsername(generateUsername(customer));
|
||||
user.setPassword(passwordEncoder.encode(TEMP_PASSWORD));
|
||||
user.setEmail(customer.getEmail());
|
||||
user.setFullName((customer.getFirstName() + " " + customer.getLastName()).trim());
|
||||
user.setPhone(generatePhone(customer));
|
||||
user.setRole(User.Role.CUSTOMER);
|
||||
user.setActive(true);
|
||||
user.setTokenVersion(0);
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
private String generateUsername(Customer customer) {
|
||||
return "customer_" + customer.getCustomerId();
|
||||
}
|
||||
|
||||
private String generatePhone(Customer customer) {
|
||||
return String.format("200-000-%04d", customer.getCustomerId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
INSERT INTO users (username, password, email, fullName, phone, role, active, tokenVersion)
|
||||
SELECT
|
||||
CONCAT('customer_', c.customerId) AS username,
|
||||
'$2a$10$mE0D/HrnCuqFeEqMy0NJwuy2jkoRYjQ7GrKcc/7QQ0r2AqnZTvyGq' AS password,
|
||||
c.email,
|
||||
CONCAT(c.firstName, ' ', c.lastName) AS fullName,
|
||||
CONCAT('200-000-', LPAD(c.customerId, 4, '0')) AS phone,
|
||||
'CUSTOMER' AS role,
|
||||
TRUE AS active,
|
||||
0 AS tokenVersion
|
||||
FROM customer c
|
||||
WHERE c.user_id IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM users u
|
||||
WHERE u.username = CONCAT('customer_', c.customerId)
|
||||
OR u.email = c.email
|
||||
);
|
||||
|
||||
INSERT INTO users (username, password, email, fullName, phone, role, active, tokenVersion)
|
||||
SELECT
|
||||
CONCAT('employee_', e.employeeId) AS username,
|
||||
'$2a$10$mE0D/HrnCuqFeEqMy0NJwuy2jkoRYjQ7GrKcc/7QQ0r2AqnZTvyGq' AS password,
|
||||
e.email,
|
||||
CONCAT(e.firstName, ' ', e.lastName) AS fullName,
|
||||
CONCAT('300-000-', LPAD(e.employeeId, 4, '0')) AS phone,
|
||||
CASE
|
||||
WHEN UPPER(e.role) = 'MANAGER' THEN 'ADMIN'
|
||||
ELSE 'STAFF'
|
||||
END AS role,
|
||||
TRUE AS active,
|
||||
0 AS tokenVersion
|
||||
FROM employee e
|
||||
WHERE e.user_id IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM users u
|
||||
WHERE u.username = CONCAT('employee_', e.employeeId)
|
||||
OR u.email = e.email
|
||||
);
|
||||
|
||||
UPDATE customer c
|
||||
JOIN users u ON u.email = c.email
|
||||
SET c.user_id = u.id
|
||||
WHERE c.user_id IS NULL;
|
||||
|
||||
UPDATE employee e
|
||||
JOIN users u ON u.email = e.email
|
||||
SET e.user_id = u.id
|
||||
WHERE e.user_id IS NULL;
|
||||
|
||||
UPDATE users
|
||||
SET
|
||||
fullName = CASE
|
||||
WHEN fullName IS NULL OR fullName = '' THEN username
|
||||
ELSE fullName
|
||||
END,
|
||||
email = CASE
|
||||
WHEN email IS NULL OR email = '' THEN CONCAT(username, '@petshop.local')
|
||||
ELSE email
|
||||
END,
|
||||
phone = CASE
|
||||
WHEN phone IS NULL OR phone = '' THEN CONCAT('000-000-', LPAD(id, 4, '0'))
|
||||
ELSE phone
|
||||
END,
|
||||
active = COALESCE(active, TRUE),
|
||||
tokenVersion = COALESCE(tokenVersion, 0)
|
||||
WHERE fullName IS NULL
|
||||
OR fullName = ''
|
||||
OR email IS NULL
|
||||
OR email = ''
|
||||
OR phone IS NULL
|
||||
OR phone = ''
|
||||
OR active IS NULL
|
||||
OR tokenVersion IS NULL;
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.petshop.backend.service;
|
||||
|
||||
import com.petshop.backend.dto.customer.CustomerRequest;
|
||||
import com.petshop.backend.entity.Customer;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.repository.CustomerRepository;
|
||||
import com.petshop.backend.repository.UserRepository;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CustomerServiceTest {
|
||||
|
||||
@Mock
|
||||
private CustomerRepository customerRepository;
|
||||
|
||||
@Mock
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Mock
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Mock
|
||||
private UserBusinessLinkageService userBusinessLinkageService;
|
||||
|
||||
@InjectMocks
|
||||
private CustomerService customerService;
|
||||
|
||||
@Test
|
||||
void createCustomerCreatesLinkedUser() {
|
||||
CustomerRequest request = new CustomerRequest();
|
||||
request.setFirstName("Pat");
|
||||
request.setLastName("Owner");
|
||||
request.setEmail("pat@example.com");
|
||||
|
||||
Customer savedCustomer = new Customer();
|
||||
savedCustomer.setCustomerId(7L);
|
||||
savedCustomer.setFirstName("Pat");
|
||||
savedCustomer.setLastName("Owner");
|
||||
savedCustomer.setEmail("pat@example.com");
|
||||
|
||||
when(customerRepository.save(any(Customer.class))).thenReturn(savedCustomer);
|
||||
when(userRepository.findByEmail("pat@example.com")).thenReturn(Optional.empty());
|
||||
when(passwordEncoder.encode(any())).thenReturn("hashed-temp-password");
|
||||
when(userRepository.save(any(User.class))).thenAnswer(invocation -> {
|
||||
User user = invocation.getArgument(0);
|
||||
user.setId(11L);
|
||||
return user;
|
||||
});
|
||||
when(userBusinessLinkageService.ensureLinkedCustomer(any(User.class))).thenAnswer(invocation -> {
|
||||
User user = invocation.getArgument(0);
|
||||
savedCustomer.setUserId(user.getId());
|
||||
return savedCustomer;
|
||||
});
|
||||
|
||||
var response = customerService.createCustomer(request);
|
||||
|
||||
assertNotNull(response);
|
||||
assertEquals("Pat", response.getFirstName());
|
||||
assertEquals("Owner", response.getLastName());
|
||||
assertEquals("pat@example.com", response.getEmail());
|
||||
|
||||
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
|
||||
verify(userRepository).save(userCaptor.capture());
|
||||
User createdUser = userCaptor.getValue();
|
||||
assertEquals("customer_7", createdUser.getUsername());
|
||||
assertEquals("hashed-temp-password", createdUser.getPassword());
|
||||
assertEquals("pat@example.com", createdUser.getEmail());
|
||||
assertEquals("Pat Owner", createdUser.getFullName());
|
||||
assertEquals("200-000-0007", createdUser.getPhone());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user