Skip to content

Commit

Permalink
New feature to add chat link to user (#1566)
Browse files Browse the repository at this point in the history
  • Loading branch information
KizerovDmitriy authored Dec 20, 2024
1 parent 0093b1b commit 98ee056
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
git fetch --unshallow
mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install sonar:sonar -Dsonar.projectKey=ita-social-projects-green-ubs -Dsonar.organization=ita-social-projects -Dsonar.host.url=https://sonarcloud.io -Dsonar.binaries=target/classes -Dsonar.dynamicAnalysis=reuseReports -Dsonar.exclusions=**/EncryptionUtil.java -Dsonar.coverage.exclusions=**/configuration/*,**/entity/*,**/exceptions/*,**/exceptions/**,**/enums/NotificationType.java,**/BigOrderTableRepository.java
mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install sonar:sonar -Dsonar.projectKey=ita-social-projects-green-ubs -Dsonar.organization=ita-social-projects -Dsonar.host.url=https://sonarcloud.io -Dsonar.binaries=target/classes -Dsonar.dynamicAnalysis=reuseReports -Dsonar.exclusions=**/EncryptionUtil.java -Dsonar.coverage.exclusions=**/configuration/*,**/entity/*,**/exceptions/*,**/exceptions/**,**/enums/NotificationType.java,**/BigOrderTableRepository.java,**/ChatLinkDto.java
- name: Test Reporter
uses: dorny/[email protected]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.hasAnyRole(ADMIN, UBS_EMPLOYEE)
.requestMatchers(HttpMethod.PATCH,
SUPER_ADMIN_LINK + "/deactivateCourier/{id}",
SUPER_ADMIN_LINK + "/switchTariffStatus/{tariffId}")
SUPER_ADMIN_LINK + "/switchTariffStatus/{tariffId}",
UBS_MANAG_LINK + "/addChatLink")
.hasAnyRole(ADMIN, UBS_EMPLOYEE)
.requestMatchers(HttpMethod.PATCH,
UBS_MANAG_LINK + "/update-order-page-admin-info/{id}",
Expand Down
15 changes: 15 additions & 0 deletions core/src/main/java/greencity/controller/AdminUbsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import greencity.dto.pageble.PageableDto;
import greencity.dto.table.ColumnWidthDto;
import greencity.dto.table.TableParamsDto;
import greencity.dto.user.ChatLinkDto;
import greencity.dto.violation.UserViolationsWithUserName;
import greencity.enums.SortingOrder;
import greencity.filters.CustomerPage;
Expand Down Expand Up @@ -270,4 +271,18 @@ public ResponseEntity<HttpStatus> saveIsFreeze(@CurrentUserUuid String uuid,
bigOrderTableServiceView.changeIsFreezeStatus(uuid, value);
return ResponseEntity.status(HttpStatus.OK).body(HttpStatus.OK);
}

@Operation(summary = "Add chat link to user")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = HttpStatuses.OK),
@ApiResponse(responseCode = "401", description = HttpStatuses.UNAUTHORIZED, content = @Content),
@ApiResponse(responseCode = "400", description = HttpStatuses.BAD_REQUEST, content = @Content),
@ApiResponse(responseCode = "403", description = HttpStatuses.FORBIDDEN, content = @Content)
})
@PreAuthorize("@preAuthorizer.hasAuthority('SEE_CLIENTS_PAGE', authentication)")
@PatchMapping("/addChatLink")
public ResponseEntity<HttpStatus> addChatLink(@RequestBody @Valid ChatLinkDto chatLink) {
ordersAdminsPageService.addChatLinkToUser(chatLink);
return ResponseEntity.status(HttpStatus.OK).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import greencity.dto.order.ChangeOrderResponseDTO;
import greencity.dto.order.RequestToChangeOrdersDataDto;
import greencity.dto.table.ColumnWidthDto;
import greencity.dto.user.ChatLinkDto;
import greencity.service.ubs.OrdersAdminsPageService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -25,6 +26,7 @@
import static greencity.ModelUtils.getUuid;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
Expand Down Expand Up @@ -154,4 +156,15 @@ void getAllLocations() throws Exception {
.principal(principal))
.andExpect(status().isOk());
}

@Test
void addChatLinkTest() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
mockMvc.perform(patch(management + "/addChatLink")
.principal(principal)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper
.writeValueAsString(new ChatLinkDto(1L, "https://my.binotel.ua/f/chat/#/visitor/21269249.12893974"))))
.andExpect(status().isOk());
}
}
3 changes: 3 additions & 0 deletions dao/src/main/java/greencity/entity/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,7 @@ public class User {

@Column(name = "date_of_registration")
private LocalDate dateOfRegistration;

@Column(name = "chat_link")
private String chatLink;
}
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,5 @@
<include file="db/changelog/logs/2024-11-28-change-add-column-isTableFreeze-to-column_width_for_employee-Warded120.xml"/>
<include file="db/changelog/logs/2024-12-18-update-column_width_for_employee-Kizerov.xml"/>
<include file="db/changelog/logs/ch-add-column-reason-into-change-of-points-table-Chernenko.xml"/>
<include file="db/changelog/logs/2024-12-18-add-new-column-to-user-table-Kizerov.xml"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">

<changeSet id="add-new-column-to-user" author="Kizerov Dmytro">
<addColumn tableName="users">
<column name="chat_link" type="VARCHAR(500)">
<constraints nullable="true"/>
</column>
</addColumn>
</changeSet>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ public class UserWithSomeOrderDetailDto {
private int violation;
@JsonProperty("currentPoints")
private String userBonuses;
private String chatLink;
}
12 changes: 12 additions & 0 deletions service-api/src/main/java/greencity/dto/user/ChatLinkDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package greencity.dto.user;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Length;

public record ChatLinkDto(
Long userId,
@JsonProperty("link") @Length(max = 255) @NotBlank @Pattern(regexp = "^https://my\\.binotel\\.ua.*",
message = "Link must start with 'https://my.binotel.ua'") String link) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import greencity.dto.order.RequestToChangeOrdersDataDto;
import greencity.dto.table.ColumnWidthDto;
import greencity.dto.table.TableParamsDto;
import greencity.dto.user.ChatLinkDto;
import greencity.entity.user.employee.Employee;
import java.util.List;

Expand Down Expand Up @@ -136,4 +137,12 @@ ChangeOrderResponseDTO chooseOrdersDataSwitcher(String email,
* regions, cities, and districts in the system
*/
List<RegionInfoDto> getAllLocationsInfo();

/**
* Adds a chat link to a user.
*
* @param chatLinkDto the chat link to add
* @author Kizerov Dmytro
*/
void addChatLinkToUser(ChatLinkDto chatLinkDto);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import greencity.dto.table.ColumnDTO;
import greencity.dto.table.ColumnWidthDto;
import greencity.dto.table.TableParamsDto;
import greencity.dto.user.ChatLinkDto;
import greencity.entity.table.TableColumnWidthForEmployee;
import greencity.entity.user.Region;
import greencity.entity.user.employee.Employee;
Expand Down Expand Up @@ -89,6 +90,7 @@
import static greencity.constant.ErrorMessage.ORDER_STATUS_NOT_FOUND;
import static greencity.constant.ErrorMessage.ORDER_WITH_CURRENT_ID_DOES_NOT_EXIST;
import static greencity.constant.ErrorMessage.POSITION_NOT_FOUND_BY_ID;
import static greencity.constant.ErrorMessage.USER_WITH_CURRENT_ID_DOES_NOT_EXIST;
import static greencity.constant.ErrorMessage.USER_WITH_CURRENT_UUID_DOES_NOT_EXIST;
import static greencity.constant.OrderHistory.UBS_ADMIN;
import static java.util.Objects.isNull;
Expand Down Expand Up @@ -447,6 +449,17 @@ public List<RegionInfoDto> getAllLocationsInfo() {
.toList();
}

/**
* {@inheritDoc}
*/
@Override
public void addChatLinkToUser(ChatLinkDto chatLinkDto) {
User user = userRepository.findById(chatLinkDto.userId())
.orElseThrow(() -> new NotFoundException(USER_WITH_CURRENT_ID_DOES_NOT_EXIST));
user.setChatLink(chatLinkDto.link());
userRepository.save(user);
}

private RegionInfoDto toRegionInfoDto(Region region) {
return RegionInfoDto.builder()
.id(region.getId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import greencity.repository.EmployeeRepository;
import greencity.repository.UserRepository;
import greencity.repository.UserTableRepo;
import java.util.Objects;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -89,6 +90,9 @@ private UserWithSomeOrderDetailDto mapToDto(User u) {
.setLastOrderDate(optional
.get().getOrderDate().toLocalDate().format(DateTimeFormatter.ofPattern(DATE_FORMAT)));
}
if (Objects.nonNull(u.getChatLink())) {
allFieldsFromTableDto.setChatLink(u.getChatLink());
}
return allFieldsFromTableDto;
}
}
27 changes: 27 additions & 0 deletions service/src/test/java/greencity/ModelUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5675,4 +5675,31 @@ public static RequestToChangeOrdersDataDto getChangeRequest(String columnName) {
.newValue("Test comment")
.build();
}

public static User createTestUser(Long id, String firstName, String lastName, String email, String phone) {
User user = new User();
user.setId(id);
user.setRecipientName(firstName);
user.setRecipientSurname(lastName);
user.setRecipientEmail(email);
user.setRecipientPhone(phone);
user.setDateOfRegistration(LocalDate.now());
user.setOrders(List.of(createTestOrder()));
user.setCurrentPoints(100);
user.setViolations(1);
return user;
}

public static Order createTestOrder() {
Order order = new Order();
order.setOrderDate(LocalDateTime.now().minusDays(1));
return order;
}

public static Employee createTestEmployee(Long id) {
Employee employee = new Employee();
employee.setId(id);
employee.setEmail("[email protected]");
return employee;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import greencity.dto.order.ChangeOrderResponseDTO;
import greencity.dto.order.RequestToChangeOrdersDataDto;
import greencity.dto.table.ColumnWidthDto;
import greencity.dto.user.ChatLinkDto;
import greencity.entity.order.Event;
import greencity.entity.table.TableColumnWidthForEmployee;
import greencity.entity.user.ubs.OrderAddress;
Expand Down Expand Up @@ -1355,4 +1356,15 @@ void addNewCommentWithNotExistingOrderTest() {
verify(employeeRepository).findByEmail(anyString());
verify(orderRepository).findById(anyLong());
}

@Test
void addChatLinkToUserTest() {
when(userRepository.findById(anyLong())).thenReturn(Optional.ofNullable(ModelUtils.getUser()));

ordersAdminsPageService
.addChatLinkToUser(new ChatLinkDto(1L, "https://my.binotel.ua/f/chat/#/visitor/21269249.12893974"));

verify(userRepository).findById(anyLong());
verify(userRepository).save(any(User.class));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package greencity.service.ubs;

import greencity.ModelUtils;
import greencity.dto.order.UserWithSomeOrderDetailDto;
import greencity.dto.pageble.PageableDto;
import greencity.entity.user.User;
import greencity.enums.SortingOrder;
import greencity.filters.CustomerPage;
import greencity.filters.UserFilterCriteria;
import greencity.repository.EmployeeRepository;
import greencity.repository.UserRepository;
import greencity.repository.UserTableRepo;
import jakarta.persistence.EntityNotFoundException;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

@ExtendWith(MockitoExtension.class)
class ValuesForUserTableServiceImplTest {
@Mock
private UserRepository userRepository;

@Mock
private UserTableRepo userTableRepo;

@Mock
private EmployeeRepository employeeRepository;

@InjectMocks
private ValuesForUserTableServiceImpl service;

private static final String TEST_EMAIL = "[email protected]";

@Test
void getAllFieldsShouldReturnPageableDtoWhenDataIsValidTest() {
Long employeeId = 1L;
List<Long> tariffsInfoIds = List.of(2L, 3L);
List<Long> userIds = List.of(4L, 5L, 4L, 5L);
User user1 = ModelUtils.createTestUser(4L, "John", "Doe", "[email protected]", "+380123456789");
User user2 = ModelUtils.createTestUser(5L, "Jane", "Smith", "[email protected]", "+380987654321");
Page<User> mockPage = new PageImpl<>(List.of(user1, user2), PageRequest.of(0, 2), 2);

CustomerPage page = new CustomerPage(0, 2);
String columnName = "name";
SortingOrder sortingOrder = SortingOrder.ASC;
UserFilterCriteria filterCriteria = new UserFilterCriteria();

Mockito.when(employeeRepository.findByEmail(TEST_EMAIL))
.thenReturn(Optional.of(ModelUtils.createTestEmployee(employeeId)));
Mockito.when(employeeRepository.findTariffsInfoForEmployee(employeeId))
.thenReturn(tariffsInfoIds);
Mockito.when(userRepository.getAllUsersByTariffsInfoId(Mockito.anyLong()))
.thenReturn(List.of(4L, 5L));
Mockito.when(userTableRepo.findAll(
Mockito.eq(filterCriteria),
Mockito.eq(columnName),
Mockito.eq(sortingOrder),
Mockito.eq(page),
Mockito.anyList()))
.thenReturn(mockPage);

PageableDto<UserWithSomeOrderDetailDto> result =
service.getAllFields(page, columnName, sortingOrder, filterCriteria, TEST_EMAIL);

assertThat(result).isNotNull();
assertThat(result.getPage()).hasSize(2);
assertThat(result.getPage())
.extracting("clientName")
.containsExactly("John Doe", "Jane Smith");
Mockito.verify(employeeRepository).findByEmail(TEST_EMAIL);
Mockito.verify(employeeRepository).findTariffsInfoForEmployee(employeeId);
Mockito.verify(userRepository, Mockito.times(tariffsInfoIds.size()))
.getAllUsersByTariffsInfoId(Mockito.anyLong());
Mockito.verify(userTableRepo).findAll(filterCriteria, columnName, sortingOrder, page, userIds);
}

@Test
void getAllFieldsShouldThrowExceptionWhenEmployeeNotFoundTest() {
Mockito.when(employeeRepository.findByEmail(TEST_EMAIL))
.thenReturn(Optional.empty());

CustomerPage page = new CustomerPage(0, 2);
String columnName = "name";
SortingOrder sortingOrder = SortingOrder.ASC;
UserFilterCriteria filterCriteria = new UserFilterCriteria();

assertThatThrownBy(() -> service.getAllFields(page, columnName, sortingOrder, filterCriteria, TEST_EMAIL))
.isInstanceOf(EntityNotFoundException.class)
.hasMessage("Employee with current id doesn't exist: ");

Mockito.verify(employeeRepository).findByEmail(TEST_EMAIL);
Mockito.verifyNoInteractions(userRepository, userTableRepo);
}
}

0 comments on commit 98ee056

Please sign in to comment.