18 changed files with 816 additions and 29 deletions
@ -0,0 +1,384 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.controller; |
|||
|
|||
import com.fasterxml.jackson.core.type.TypeReference; |
|||
import com.fasterxml.jackson.databind.JsonNode; |
|||
import com.fasterxml.jackson.databind.node.TextNode; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.junit.After; |
|||
import org.junit.Assert; |
|||
import org.junit.Before; |
|||
import org.junit.Test; |
|||
import org.mockito.AdditionalAnswers; |
|||
import org.mockito.Mockito; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Primary; |
|||
import org.springframework.test.context.ContextConfiguration; |
|||
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.Device; |
|||
import org.thingsboard.server.common.data.alarm.Alarm; |
|||
import org.thingsboard.server.common.data.alarm.AlarmComment; |
|||
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo; |
|||
import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
|||
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
|||
import org.thingsboard.server.common.data.audit.ActionType; |
|||
import org.thingsboard.server.common.data.id.AlarmId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.dao.alarm.AlarmDao; |
|||
|
|||
import java.util.LinkedList; |
|||
import java.util.List; |
|||
|
|||
import static org.hamcrest.Matchers.containsString; |
|||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
|||
|
|||
@Slf4j |
|||
@ContextConfiguration(classes = {BaseAlarmCommentControllerTest.Config.class}) |
|||
public abstract class BaseAlarmCommentControllerTest extends AbstractControllerTest { |
|||
|
|||
protected Device customerDevice; |
|||
protected Alarm alarm; |
|||
|
|||
static class Config { |
|||
@Bean |
|||
@Primary |
|||
public AlarmDao alarmDao(AlarmDao alarmDao) { |
|||
return Mockito.mock(AlarmDao.class, AdditionalAnswers.delegatesTo(alarmDao)); |
|||
} |
|||
} |
|||
|
|||
@Before |
|||
public void setup() throws Exception { |
|||
loginTenantAdmin(); |
|||
|
|||
Device device = new Device(); |
|||
device.setTenantId(tenantId); |
|||
device.setName("Test device"); |
|||
device.setLabel("Label"); |
|||
device.setType("Type"); |
|||
device.setCustomerId(customerId); |
|||
customerDevice = doPost("/api/device", device, Device.class); |
|||
|
|||
alarm = Alarm.builder() |
|||
.tenantId(tenantId) |
|||
.customerId(customerId) |
|||
.originator(customerDevice.getId()) |
|||
.status(AlarmStatus.ACTIVE_UNACK) |
|||
.severity(AlarmSeverity.CRITICAL) |
|||
.type("test alarm type") |
|||
.build(); |
|||
|
|||
alarm = doPost("/api/alarm", alarm, Alarm.class); |
|||
|
|||
resetTokens(); |
|||
} |
|||
|
|||
@After |
|||
public void teardown() throws Exception { |
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
loginSysAdmin(); |
|||
deleteDifferentTenant(); |
|||
} |
|||
|
|||
@Test |
|||
public void testCreateAlarmCommentViaCustomer() throws Exception { |
|||
loginCustomerUser(); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
AlarmComment createdComment = createAlarmComment(alarm.getId()); |
|||
|
|||
testLogEntityAction(createdComment, createdComment.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED, 1); |
|||
testPushMsgToRuleEngineTime(createdComment.getId(), tenantId, createdComment, 1); |
|||
} |
|||
|
|||
@Test |
|||
public void testCreateAlarmCommentViaTenant() throws Exception { |
|||
loginTenantAdmin(); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
AlarmComment createdComment = createAlarmComment(alarm.getId()); |
|||
Assert.assertEquals("OTHER", createdComment.getType()); |
|||
|
|||
testLogEntityAction(createdComment, createdComment.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED, 1); |
|||
testPushMsgToRuleEngineTime(createdComment.getId(), tenantId, createdComment, 1); |
|||
} |
|||
|
|||
@Test |
|||
public void testUpdateAlarmCommentViaCustomer() throws Exception { |
|||
loginCustomerUser(); |
|||
AlarmComment savedComment = createAlarmComment(alarm.getId()); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
JsonNode newComment = JacksonUtil.newObjectNode().set("text", new TextNode("Updated comment")); |
|||
savedComment.setComment(newComment); |
|||
AlarmComment updatedAlarmComment = saveAlarmComment(alarm.getId(), savedComment); |
|||
|
|||
Assert.assertNotNull(updatedAlarmComment); |
|||
Assert.assertEquals(newComment.get("text"), updatedAlarmComment.getComment().get("text")); |
|||
Assert.assertEquals("true", updatedAlarmComment.getComment().get("edited").asText()); |
|||
Assert.assertNotNull(updatedAlarmComment.getComment().get("editedOn")); |
|||
|
|||
testNotifyEntityAllOneTime(updatedAlarmComment, updatedAlarmComment.getId(), updatedAlarmComment.getId(), |
|||
tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.UPDATED); |
|||
} |
|||
|
|||
@Test |
|||
public void testUpdateAlarmViaTenant() throws Exception { |
|||
loginTenantAdmin(); |
|||
AlarmComment savedComment = createAlarmComment(alarm.getId()); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
JsonNode newComment = JacksonUtil.newObjectNode().set("text", new TextNode("Updated comment")); |
|||
savedComment.setComment(newComment); |
|||
AlarmComment updatedAlarmComment = saveAlarmComment(alarm.getId(), savedComment); |
|||
|
|||
Assert.assertNotNull(updatedAlarmComment); |
|||
Assert.assertEquals(newComment.get("text"), updatedAlarmComment.getComment().get("text")); |
|||
Assert.assertEquals("true", updatedAlarmComment.getComment().get("edited").asText()); |
|||
Assert.assertNotNull(updatedAlarmComment.getComment().get("editedOn")); |
|||
|
|||
testNotifyEntityAllOneTime(updatedAlarmComment, updatedAlarmComment.getId(), updatedAlarmComment.getId(), |
|||
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.UPDATED); |
|||
} |
|||
|
|||
@Test |
|||
public void testUpdateAlarmViaDifferentTenant() throws Exception { |
|||
loginTenantAdmin(); |
|||
AlarmComment savedComment = createAlarmComment(alarm.getId()); |
|||
|
|||
loginDifferentTenant(); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
JsonNode newComment = JacksonUtil.newObjectNode().set("text", new TextNode("Updated comment")); |
|||
savedComment.setComment(newComment); |
|||
|
|||
doPost("/api/alarm/" + alarm.getId() + "/comment", savedComment) |
|||
.andExpect(status().isForbidden()) |
|||
.andExpect(statusReason(containsString(msgErrorPermission))); |
|||
|
|||
testNotifyEntityNever(savedComment.getId(), savedComment); |
|||
} |
|||
|
|||
@Test |
|||
public void testUpdateAlarmViaDifferentCustomer() throws Exception { |
|||
loginCustomerUser(); |
|||
AlarmComment savedComment = createAlarmComment(alarm.getId()); |
|||
|
|||
loginDifferentCustomer(); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
JsonNode newComment = JacksonUtil.newObjectNode().set("text", new TextNode("Updated comment")); |
|||
savedComment.setComment(newComment); |
|||
|
|||
doPost("/api/alarm/" + alarm.getId() + "/comment", savedComment) |
|||
.andExpect(status().isForbidden()) |
|||
.andExpect(statusReason(containsString(msgErrorPermission))); |
|||
|
|||
testNotifyEntityNever(savedComment.getId(), savedComment); |
|||
} |
|||
|
|||
@Test |
|||
public void testDeleteAlarmViaCustomer() throws Exception { |
|||
loginCustomerUser(); |
|||
AlarmComment alarmComment = createAlarmComment(alarm.getId()); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
doDelete("/api/alarm/" + alarm.getId() + "/comment/" + alarmComment.getId()) |
|||
.andExpect(status().isOk()); |
|||
|
|||
testNotifyEntityOneTimeMsgToEdgeServiceNever(alarmComment, alarmComment.getId(), alarmComment.getId(), |
|||
tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED); |
|||
} |
|||
|
|||
@Test |
|||
public void testDeleteAlarmViaTenant() throws Exception { |
|||
loginTenantAdmin(); |
|||
AlarmComment alarmComment = createAlarmComment(alarm.getId()); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
doDelete("/api/alarm/" + alarm.getId() + "/comment/" + alarmComment.getId()) |
|||
.andExpect(status().isOk()); |
|||
|
|||
testNotifyEntityOneTimeMsgToEdgeServiceNever(alarmComment, alarmComment.getId(), alarmComment.getId(), |
|||
tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED); |
|||
} |
|||
|
|||
@Test |
|||
public void testDeleteAlarmViaDifferentTenant() throws Exception { |
|||
loginTenantAdmin(); |
|||
AlarmComment alarmComment = createAlarmComment(alarm.getId()); |
|||
|
|||
loginDifferentTenant(); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
doDelete("/api/alarm/" + alarm.getId() + "/comment/" + alarmComment.getId()) |
|||
.andExpect(status().isForbidden()) |
|||
.andExpect(statusReason(containsString(msgErrorPermission))); |
|||
|
|||
testNotifyEntityNever(alarm.getId(), alarm); |
|||
} |
|||
|
|||
@Test |
|||
public void testDeleteAlarmViaDifferentCustomer() throws Exception { |
|||
loginCustomerUser(); |
|||
AlarmComment alarmComment = createAlarmComment(alarm.getId()); |
|||
|
|||
loginDifferentCustomer(); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
doDelete("/api/alarm/" + alarm.getId() + "/comment/" + alarmComment.getId()) |
|||
.andExpect(status().isForbidden()) |
|||
.andExpect(statusReason(containsString(msgErrorPermission))); |
|||
|
|||
testNotifyEntityNever(alarm.getId(), alarm); |
|||
} |
|||
|
|||
@Test |
|||
public void testClearAlarmViaCustomer() throws Exception { |
|||
loginCustomerUser(); |
|||
AlarmComment alarmComment = createAlarmComment(alarm.getId()); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
|
|||
doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isOk()); |
|||
|
|||
Alarm foundAlarm = doGet("/api/alarm/" + alarm.getId(), Alarm.class); |
|||
Assert.assertNotNull(foundAlarm); |
|||
Assert.assertEquals(AlarmStatus.CLEARED_UNACK, foundAlarm.getStatus()); |
|||
|
|||
} |
|||
|
|||
@Test |
|||
public void testFindAlarmCommentsViaCustomerUser() throws Exception { |
|||
loginCustomerUser(); |
|||
|
|||
List<AlarmComment> createdAlarmComments = new LinkedList<>(); |
|||
|
|||
final int size = 10; |
|||
for (int i = 0; i < size; i++) { |
|||
createdAlarmComments.add( |
|||
createAlarmComment(alarm.getId(), RandomStringUtils.randomAlphanumeric(10)) |
|||
); |
|||
} |
|||
|
|||
var response = doGetTyped( |
|||
"/api/alarm/" + alarm.getId() + "/comment?page=0&pageSize=" + size, |
|||
new TypeReference<PageData<AlarmCommentInfo>>() {} |
|||
); |
|||
var foundAlarmCommentInfos = response.getData(); |
|||
Assert.assertNotNull("Found pageData is null", foundAlarmCommentInfos); |
|||
Assert.assertNotEquals( |
|||
"Expected alarms are not found!", |
|||
0, foundAlarmCommentInfos.size() |
|||
); |
|||
|
|||
boolean allMatch = createdAlarmComments.stream() |
|||
.allMatch(alarmComment -> foundAlarmCommentInfos.stream() |
|||
.map(AlarmCommentInfo::getComment) |
|||
.anyMatch(comment -> alarmComment.getComment().equals(comment)) |
|||
); |
|||
Assert.assertTrue("Created alarm comment doesn't match any found!", allMatch); |
|||
} |
|||
|
|||
@Test |
|||
public void testFindAlarmsViaDifferentCustomerUser() throws Exception { |
|||
loginCustomerUser(); |
|||
|
|||
final int size = 10; |
|||
List<AlarmComment> createdAlarmComments = new LinkedList<>(); |
|||
for (int i = 0; i < size; i++) { |
|||
createdAlarmComments.add( |
|||
createAlarmComment(alarm.getId(), RandomStringUtils.randomAlphanumeric(10)) |
|||
); |
|||
} |
|||
|
|||
loginDifferentCustomer(); |
|||
doGet("/api/alarm/" + alarm.getId() + "/comment?page=0&pageSize=" + size) |
|||
.andExpect(status().isForbidden()) |
|||
.andExpect(statusReason(containsString(msgErrorPermission))); |
|||
} |
|||
|
|||
@Test |
|||
public void testFindAlarmCommentsViaPublicCustomer() throws Exception { |
|||
loginTenantAdmin(); |
|||
|
|||
Device device = new Device(); |
|||
device.setName("Test Public Device"); |
|||
device.setLabel("Label"); |
|||
device.setCustomerId(customerId); |
|||
device = doPost("/api/device", device, Device.class); |
|||
device = doPost("/api/customer/public/device/" + device.getUuidId(), Device.class); |
|||
|
|||
String publicId = device.getCustomerId().toString(); |
|||
|
|||
Alarm alarm = Alarm.builder() |
|||
.originator(device.getId()) |
|||
.status(AlarmStatus.ACTIVE_UNACK) |
|||
.severity(AlarmSeverity.CRITICAL) |
|||
.type("Test") |
|||
.build(); |
|||
|
|||
alarm = doPost("/api/alarm", alarm, Alarm.class); |
|||
|
|||
Mockito.reset(tbClusterService, auditLogService); |
|||
AlarmComment alarmComment = createAlarmComment(alarm.getId()); |
|||
|
|||
resetTokens(); |
|||
|
|||
JsonNode publicLoginRequest = JacksonUtil.toJsonNode("{\"publicId\": \"" + publicId + "\"}"); |
|||
JsonNode tokens = doPost("/api/auth/login/public", publicLoginRequest, JsonNode.class); |
|||
this.token = tokens.get("token").asText(); |
|||
|
|||
PageData<AlarmCommentInfo> pageData = doGetTyped( |
|||
"/api/alarm/" + alarm.getId() + "/comment" + "?page=0&pageSize=1", new TypeReference<PageData<AlarmCommentInfo>>() {} |
|||
); |
|||
|
|||
Assert.assertNotNull("Found pageData is null", pageData); |
|||
Assert.assertNotEquals("Expected alarms are not found!", 0, pageData.getTotalElements()); |
|||
|
|||
AlarmCommentInfo alarmCommentInfo = pageData.getData().get(0); |
|||
boolean equals = alarmComment.getId().equals(alarmCommentInfo.getId()) && alarmComment.getComment().equals(alarmCommentInfo.getComment()); |
|||
Assert.assertTrue("Created alarm doesn't match the found one!", equals); |
|||
} |
|||
|
|||
private AlarmComment createAlarmComment(AlarmId alarmId, String text) { |
|||
AlarmComment alarmComment = AlarmComment.builder() |
|||
.comment(JacksonUtil.newObjectNode().set("text", new TextNode(text))) |
|||
.build(); |
|||
|
|||
return saveAlarmComment(alarmId, alarmComment); |
|||
} |
|||
private AlarmComment createAlarmComment(AlarmId alarmId) { |
|||
return createAlarmComment(alarmId, "Please take a look"); |
|||
} |
|||
private AlarmComment saveAlarmComment(AlarmId alarmId, AlarmComment alarmComment) { |
|||
alarmComment = doPost("/api/alarm/" + alarmId + "/comment", alarmComment, AlarmComment.class); |
|||
Assert.assertNotNull(alarmComment); |
|||
|
|||
return alarmComment; |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.controller.sql; |
|||
|
|||
import org.thingsboard.server.controller.BaseAlarmCommentControllerTest; |
|||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|||
|
|||
@DaoSqlTest |
|||
public class AlarmCommentControllerSqlTest extends BaseAlarmCommentControllerTest { |
|||
} |
|||
@ -0,0 +1,96 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.entitiy.alarmComment; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.junit.Test; |
|||
import org.junit.runner.RunWith; |
|||
import org.mockito.Mockito; |
|||
import org.springframework.boot.test.mock.mockito.MockBean; |
|||
import org.springframework.boot.test.mock.mockito.SpyBean; |
|||
import org.springframework.test.context.ContextConfiguration; |
|||
import org.springframework.test.context.TestPropertySource; |
|||
import org.springframework.test.context.junit4.SpringRunner; |
|||
import org.thingsboard.server.cluster.TbClusterService; |
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.alarm.Alarm; |
|||
import org.thingsboard.server.common.data.alarm.AlarmComment; |
|||
import org.thingsboard.server.common.data.exception.ThingsboardException; |
|||
import org.thingsboard.server.common.data.id.AlarmCommentId; |
|||
import org.thingsboard.server.common.data.id.AlarmId; |
|||
import org.thingsboard.server.dao.alarm.AlarmCommentOperationResult; |
|||
import org.thingsboard.server.dao.alarm.AlarmCommentService; |
|||
import org.thingsboard.server.dao.alarm.AlarmService; |
|||
import org.thingsboard.server.dao.customer.CustomerService; |
|||
import org.thingsboard.server.service.entitiy.TbNotificationEntityService; |
|||
import org.thingsboard.server.service.entitiy.alarm.DefaultTbAlarmCommentService; |
|||
import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
|||
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
import static org.mockito.ArgumentMatchers.any; |
|||
import static org.mockito.ArgumentMatchers.eq; |
|||
import static org.mockito.Mockito.times; |
|||
import static org.mockito.Mockito.verify; |
|||
import static org.mockito.Mockito.when; |
|||
|
|||
@Slf4j |
|||
@RunWith(SpringRunner.class) |
|||
@ContextConfiguration(classes = DefaultTbAlarmCommentService.class) |
|||
@TestPropertySource(properties = { |
|||
"server.log_controller_error_stack_trace=false" |
|||
}) |
|||
public class DefaultTbAlarmCommentServiceTest { |
|||
|
|||
@MockBean |
|||
protected DbCallbackExecutorService dbExecutor; |
|||
@MockBean |
|||
protected TbNotificationEntityService notificationEntityService; |
|||
@MockBean |
|||
protected AlarmService alarmService; |
|||
@MockBean |
|||
protected AlarmCommentService alarmCommentService; |
|||
@MockBean |
|||
protected AlarmSubscriptionService alarmSubscriptionService; |
|||
@MockBean |
|||
protected CustomerService customerService; |
|||
@MockBean |
|||
protected TbClusterService tbClusterService; |
|||
@SpyBean |
|||
DefaultTbAlarmCommentService service; |
|||
|
|||
@Test |
|||
public void testSave() throws ThingsboardException { |
|||
var alarm = new Alarm(); |
|||
var alarmComment = new AlarmComment(); |
|||
when(alarmCommentService.createOrUpdateAlarmComment(Mockito.any(), eq(alarmComment))).thenReturn(new AlarmCommentOperationResult(alarmComment, true)); |
|||
service.saveAlarmComment(alarm, alarmComment, new User()); |
|||
|
|||
verify(notificationEntityService, times(1)).notifyCreateOrUpdateAlarmComment(any(), any(), any(), any()); |
|||
} |
|||
|
|||
@Test |
|||
public void testDelete() { |
|||
var alarmId = new AlarmId(UUID.randomUUID()); |
|||
var alarmCommentId = new AlarmCommentId(UUID.randomUUID()); |
|||
|
|||
when(alarmCommentService.deleteAlarmComment(Mockito.any(), eq(alarmCommentId))).thenReturn(new AlarmCommentOperationResult(new AlarmComment(), true)); |
|||
service.deleteAlarmComment(new Alarm(alarmId), new AlarmComment(alarmCommentId), new User()); |
|||
|
|||
verify(notificationEntityService, times(1)).notifyDeleteAlarmComment(any(), any(), any()); |
|||
} |
|||
} |
|||
@ -0,0 +1,160 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.service; |
|||
|
|||
import com.datastax.oss.driver.api.core.uuid.Uuids; |
|||
import org.junit.After; |
|||
import org.junit.Assert; |
|||
import org.junit.Before; |
|||
import org.junit.Test; |
|||
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.Tenant; |
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.alarm.Alarm; |
|||
import org.thingsboard.server.common.data.alarm.AlarmComment; |
|||
import org.thingsboard.server.common.data.alarm.AlarmCommentInfo; |
|||
import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
|||
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
|||
import org.thingsboard.server.common.data.id.AssetId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.id.UserId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.common.data.security.Authority; |
|||
|
|||
import java.util.UUID; |
|||
import java.util.concurrent.ExecutionException; |
|||
|
|||
public abstract class BaseAlarmCommentServiceTest extends AbstractServiceTest { |
|||
|
|||
public static final String TEST_ALARM = "TEST_ALARM"; |
|||
private TenantId tenantId; |
|||
private Alarm alarm; |
|||
private User user; |
|||
|
|||
@Before |
|||
public void before() { |
|||
Tenant tenant = new Tenant(); |
|||
tenant.setTitle("My tenant"); |
|||
Tenant savedTenant = tenantService.saveTenant(tenant); |
|||
Assert.assertNotNull(savedTenant); |
|||
tenantId = savedTenant.getId(); |
|||
|
|||
alarm = Alarm.builder().tenantId(tenantId).originator(new AssetId(Uuids.timeBased())) |
|||
.type(TEST_ALARM) |
|||
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK) |
|||
.startTs(System.currentTimeMillis()).build(); |
|||
alarm = alarmService.createOrUpdateAlarm(alarm).getAlarm(); |
|||
|
|||
user = new User(); |
|||
user.setAuthority(Authority.TENANT_ADMIN); |
|||
user.setTenantId(tenantId); |
|||
user.setEmail("tenant@thingsboard.org"); |
|||
user = userService.saveUser(user); |
|||
} |
|||
|
|||
@After |
|||
public void after() { |
|||
alarmService.deleteAlarm(tenantId, alarm.getId()); |
|||
tenantService.deleteTenant(tenantId); |
|||
} |
|||
|
|||
|
|||
@Test |
|||
public void testSaveAndFetchAlarmComment() throws ExecutionException, InterruptedException { |
|||
AlarmComment alarmComment = AlarmComment.builder().alarmId(alarm.getId()) |
|||
.userId(user.getId()) |
|||
.type("OTHER") |
|||
.comment(JacksonUtil.newObjectNode().put("text", RandomStringUtils.randomAlphanumeric(10))) |
|||
.build(); |
|||
|
|||
AlarmComment createdComment = alarmCommentService.createOrUpdateAlarmComment(tenantId, alarmComment).getAlarmComment(); |
|||
|
|||
Assert.assertNotNull(createdComment); |
|||
Assert.assertNotNull(createdComment.getId()); |
|||
|
|||
Assert.assertEquals(alarm.getId(), createdComment.getAlarmId()); |
|||
Assert.assertEquals(user.getId(), createdComment.getUserId()); |
|||
Assert.assertEquals("OTHER", createdComment.getType()); |
|||
Assert.assertTrue(createdComment.getCreatedTime() > 0); |
|||
|
|||
AlarmComment fetched = alarmCommentService.findAlarmCommentByIdAsync(tenantId, createdComment.getId()).get(); |
|||
Assert.assertEquals(createdComment, fetched); |
|||
|
|||
PageData<AlarmCommentInfo> alarmComments = alarmCommentService.findAlarmComments(tenantId, alarm.getId(), new PageLink(10, 0)).get(); |
|||
Assert.assertNotNull(alarmComments.getData()); |
|||
Assert.assertEquals(1, alarmComments.getData().size()); |
|||
Assert.assertEquals(createdComment, alarmComments.getData().get(0)); |
|||
} |
|||
|
|||
@Test |
|||
public void testUpdateAlarmComment() throws ExecutionException, InterruptedException { |
|||
UserId userId = new UserId(UUID.randomUUID()); |
|||
AlarmComment alarmComment = AlarmComment.builder().alarmId(alarm.getId()) |
|||
.userId(userId) |
|||
.type("OTHER") |
|||
.comment(JacksonUtil.newObjectNode().put("text", RandomStringUtils.randomAlphanumeric(10))) |
|||
.build(); |
|||
|
|||
AlarmComment createdComment = alarmCommentService.createOrUpdateAlarmComment(tenantId, alarmComment).getAlarmComment(); |
|||
|
|||
Assert.assertNotNull(createdComment); |
|||
Assert.assertNotNull(createdComment.getId()); |
|||
|
|||
//update comment
|
|||
String newComment = "new comment"; |
|||
createdComment.setComment(JacksonUtil.newObjectNode().put("text", newComment)); |
|||
AlarmComment updatedComment = alarmCommentService.createOrUpdateAlarmComment(tenantId, createdComment).getAlarmComment(); |
|||
|
|||
Assert.assertEquals(alarm.getId(), updatedComment.getAlarmId()); |
|||
Assert.assertEquals(userId, updatedComment.getUserId()); |
|||
Assert.assertEquals("OTHER", updatedComment.getType()); |
|||
Assert.assertTrue(updatedComment.getCreatedTime() > 0); |
|||
Assert.assertEquals(newComment, updatedComment.getComment().get("text").asText()); |
|||
Assert.assertEquals("true", updatedComment.getComment().get("edited").asText()); |
|||
Assert.assertNotNull(updatedComment.getComment().get("editedOn").asText()); |
|||
|
|||
AlarmComment fetched = alarmCommentService.findAlarmCommentByIdAsync(tenantId, createdComment.getId()).get(); |
|||
Assert.assertEquals(updatedComment, fetched); |
|||
|
|||
PageData<AlarmCommentInfo> alarmComments = alarmCommentService.findAlarmComments(tenantId, alarm.getId(), new PageLink(10, 0)).get(); |
|||
Assert.assertNotNull(alarmComments.getData()); |
|||
Assert.assertEquals(1, alarmComments.getData().size()); |
|||
Assert.assertEquals(new AlarmCommentInfo(updatedComment), alarmComments.getData().get(0)); |
|||
} |
|||
|
|||
@Test |
|||
public void testDeleteAlarmComment() throws ExecutionException, InterruptedException { |
|||
UserId userId = new UserId(UUID.randomUUID()); |
|||
AlarmComment alarmComment = AlarmComment.builder().alarmId(alarm.getId()) |
|||
.userId(userId) |
|||
.type("OTHER") |
|||
.comment(JacksonUtil.newObjectNode().put("text", RandomStringUtils.randomAlphanumeric(10))) |
|||
.build(); |
|||
|
|||
AlarmComment createdComment = alarmCommentService.createOrUpdateAlarmComment(tenantId, alarmComment).getAlarmComment(); |
|||
|
|||
Assert.assertNotNull(createdComment); |
|||
Assert.assertNotNull(createdComment.getId()); |
|||
|
|||
Assert.assertTrue("Alarm comment was not deleted when expected", alarmCommentService.deleteAlarmComment(tenantId, createdComment.getId()).isSuccessful()); |
|||
|
|||
AlarmComment fetched = alarmCommentService.findAlarmCommentByIdAsync(tenantId, createdComment.getId()).get(); |
|||
|
|||
Assert.assertNull("Alarm comment was returned when it was expected to be null", fetched); |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.service.sql; |
|||
|
|||
import org.thingsboard.server.dao.service.BaseAlarmCommentServiceTest; |
|||
import org.thingsboard.server.dao.service.DaoSqlTest; |
|||
|
|||
@DaoSqlTest |
|||
public class AlarmCommentServiceSqlTest extends BaseAlarmCommentServiceTest { |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.dao.sql.alarm; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.junit.Test; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.alarm.Alarm; |
|||
import org.thingsboard.server.common.data.alarm.AlarmComment; |
|||
import org.thingsboard.server.common.data.alarm.AlarmStatus; |
|||
import org.thingsboard.server.common.data.id.AlarmCommentId; |
|||
import org.thingsboard.server.common.data.id.AlarmId; |
|||
import org.thingsboard.server.common.data.id.DeviceId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.id.UserId; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.dao.AbstractJpaDaoTest; |
|||
import org.thingsboard.server.dao.alarm.AlarmCommentDao; |
|||
import org.thingsboard.server.dao.alarm.AlarmDao; |
|||
|
|||
import java.util.UUID; |
|||
import static org.junit.Assert.assertEquals; |
|||
|
|||
@Slf4j |
|||
public class JpaAlarmCommentDaoTest extends AbstractJpaDaoTest { |
|||
|
|||
@Autowired |
|||
private AlarmCommentDao alarmCommentDao; |
|||
@Autowired |
|||
private AlarmDao alarmDao; |
|||
|
|||
|
|||
@Test |
|||
public void testFindAlarmCommentsByAlarmId() { |
|||
log.info("Current system time in millis = {}", System.currentTimeMillis()); |
|||
UUID tenantId = UUID.randomUUID(); |
|||
UUID userId = UUID.randomUUID(); |
|||
UUID alarmId1 = UUID.randomUUID(); |
|||
UUID alarmId2 = UUID.randomUUID(); |
|||
UUID commentId1 = UUID.randomUUID(); |
|||
UUID commentId2 = UUID.randomUUID(); |
|||
UUID commentId3 = UUID.randomUUID(); |
|||
saveAlarm(alarmId1, UUID.randomUUID(), UUID.randomUUID(), "TEST_ALARM"); |
|||
saveAlarm(alarmId2, UUID.randomUUID(), UUID.randomUUID(), "TEST_ALARM"); |
|||
|
|||
saveAlarmComment(commentId1, alarmId1, userId, "OTHER"); |
|||
saveAlarmComment(commentId2, alarmId1, userId, "OTHER"); |
|||
saveAlarmComment(commentId3, alarmId2, userId, "OTHER"); |
|||
|
|||
int count = alarmCommentDao.findAlarmComments(TenantId.fromUUID(tenantId), new AlarmId(alarmId1), new PageLink(10, 0)).getData().size(); |
|||
assertEquals(2, count); |
|||
} |
|||
|
|||
private void saveAlarm(UUID id, UUID tenantId, UUID deviceId, String type) { |
|||
Alarm alarm = new Alarm(); |
|||
alarm.setId(new AlarmId(id)); |
|||
alarm.setTenantId(TenantId.fromUUID(tenantId)); |
|||
alarm.setOriginator(new DeviceId(deviceId)); |
|||
alarm.setType(type); |
|||
alarm.setPropagate(true); |
|||
alarm.setStartTs(System.currentTimeMillis()); |
|||
alarm.setEndTs(System.currentTimeMillis()); |
|||
alarm.setStatus(AlarmStatus.ACTIVE_UNACK); |
|||
alarmDao.save(TenantId.fromUUID(tenantId), alarm); |
|||
} |
|||
private void saveAlarmComment(UUID id, UUID alarmId, UUID userId, String type) { |
|||
AlarmComment alarmComment = new AlarmComment(); |
|||
alarmComment.setId(new AlarmCommentId(id)); |
|||
alarmComment.setAlarmId(TenantId.fromUUID(alarmId)); |
|||
alarmComment.setUserId(new UserId(userId)); |
|||
alarmComment.setType(type); |
|||
alarmComment.setComment(JacksonUtil.newObjectNode().put("text", RandomStringUtils.randomAlphanumeric(10))); |
|||
alarmCommentDao.createAlarmComment(TenantId.fromUUID(UUID.randomUUID()), alarmComment); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue