diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index c75425c870..86a4fa174a 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -20,9 +20,10 @@ import org.mockito.ArgumentMatcher; import org.mockito.Mockito; import org.springframework.boot.test.mock.mockito.SpyBean; import org.thingsboard.server.cluster.TbClusterService; -import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.HasTenantId; +import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; @@ -37,7 +38,6 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; import java.util.ArrayList; import java.util.List; @@ -58,9 +58,6 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { @SpyBean protected AuditLogService auditLogService; - @SpyBean - protected GatewayNotificationsService gatewayNotificationsService; - protected final String msgErrorPermission = "You don't have permission to perform this operation!"; protected final String msgErrorShouldBeSpecified = "should be specified"; protected final String msgErrorNotFound = "Requested item wasn't found!"; @@ -73,7 +70,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -114,7 +111,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { argument -> argument.getClass().equals(UserId.class) : argument -> argument.equals(userId); testLogEntityActionAdditionalInfoAny(matcherEntityClassEquals, matcherOriginatorId, tenantId, matcherCustomerId, matcherUserId, userName, actionType, cntTime * 2, 1); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, new Tenant(), cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -125,7 +122,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testLogEntityActionEntityEqClass(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -147,7 +144,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { if (ActionType.RELATIONS_DELETED.equals(actionType)) { testPushMsgToRuleEngineNever(originatorId); } else { - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime); } Mockito.reset(tbClusterService, auditLogService); } @@ -166,7 +163,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { argument -> argument.getClass().equals(UserId.class) : argument -> argument.equals(userId); testLogEntityActionAdditionalInfo(matcherEntityClassEquals, matcherOriginatorId, tenantId, matcherCustomerId, matcherUserId, userName, actionType, cntTime, extractMatcherAdditionalInfo(additionalInfo)); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -184,7 +181,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { argument -> argument.getClass().equals(UserId.class) : argument -> argument.equals(userId); testLogEntityActionAdditionalInfo(matcherEntityClassEquals, matcherOriginatorId, tenantId, matcherCustomerId, matcherUserId, userName, actionType, cntTime, extractMatcherAdditionalInfoClass(additionalInfo)); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTimeRuleEngine); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTimeRuleEngine); } protected void testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAnyAdditionalInfoAny(HasName entity, HasName originator, @@ -200,7 +197,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { argument -> argument.getClass().equals(UserId.class) : argument -> argument.equals(userId); testLogEntityActionAdditionalInfoAny(matcherEntityClassEquals, matcherOriginatorId, tenantId, matcherCustomerId, matcherUserId, userName, actionType, cntTime, cntAdditionalInfo); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTimeEdge); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTimeEdge); Mockito.reset(tbClusterService, auditLogService); } @@ -218,7 +215,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { argument -> argument.getClass().equals(UserId.class) : argument -> argument.equals(userId); testLogEntityActionAdditionalInfoAny(matcherEntityClassEquals, matcherOriginatorId, tenantId, matcherCustomerId, matcherUserId, userName, actionType, cntTime, cntAdditionalInfo); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -229,7 +226,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { testNotificationMsgToEdgeServiceTime(entityId, tenantId, actionType, cntTime); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime); testBroadcastEntityStateChangeEventTime(entityId, tenantId, cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -241,7 +238,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { testNotificationMsgToEdgeServiceNeverWithActionType(entityId, actionType); testLogEntityAction(entity, originatorId, tenantId, customerId, userId, userName, actionType, cntTime, additionalInfo); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(originatorId); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTime); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTime); testBroadcastEntityStateChangeEventTime(entityId, tenantId, cntTime); Mockito.reset(tbClusterService, auditLogService); } @@ -263,7 +260,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { argument -> argument.getClass().equals(UserId.class) : argument -> argument.equals(userId); testLogEntityActionAdditionalInfoAny(matcherEntityClassEquals, matcherOriginatorId, tenantId, matcherCustomerId, matcherUserId, userName, actionType, cntTime, cntAdditionalInfo); - testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, cntTimeRuleEngine); + testPushMsgToRuleEngineTime(matcherOriginatorId, tenantId, entity, cntTimeRuleEngine); testBroadcastEntityStateChangeEventTime(entityId, tenantId, cntTime); } @@ -313,22 +310,6 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.reset(tbClusterService, auditLogService); } - protected void testNotificationUpdateGatewayOneTime(Device device, Device oldDevice) { - Mockito.verify(gatewayNotificationsService, times(1)).onDeviceUpdated(Mockito.eq(device), Mockito.eq(oldDevice)); - } - - protected void testNotificationUpdateGatewayNever() { - Mockito.verify(gatewayNotificationsService, never()).onDeviceUpdated(Mockito.any(Device.class), Mockito.any(Device.class)); - } - - protected void testNotificationDeleteGatewayOneTime(Device device) { - Mockito.verify(gatewayNotificationsService, times(1)).onDeviceDeleted(device); - } - - protected void testNotificationDeleteGatewayNever() { - Mockito.verify(gatewayNotificationsService, never()).onDeviceDeleted(Mockito.any(Device.class)); - } - private void testNotificationMsgToEdgeServiceNeverWithActionType(EntityId entityId, ActionType actionType) { EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ? EdgeEventActionType.CREDENTIALS_UPDATED : edgeTypeByActionType(actionType); @@ -359,7 +340,8 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.any(entityId.getClass()), Mockito.any(ComponentLifecycleEvent.class)); } - private void testPushMsgToRuleEngineTime(ArgumentMatcher matcherOriginatorId, TenantId tenantId, int cntTime) { + private void testPushMsgToRuleEngineTime(ArgumentMatcher matcherOriginatorId, TenantId tenantId, HasName entity, int cntTime) { + tenantId = tenantId.isNullUid() ? ((HasTenantId) entity).getTenantId() : tenantId; Mockito.verify(tbClusterService, times(cntTime)).pushMsgToRuleEngine(Mockito.eq(tenantId), Mockito.argThat(matcherOriginatorId), Mockito.any(TbMsg.class), Mockito.isNull()); } @@ -535,12 +517,14 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { CustomerId customerId, UserId userId, String userName, ActionType actionType, int cntTime, ArgumentMatcher matcherError, List> matcherAdditionalInfos) { + ArgumentMatcher matcherUserId = userId == null ? argument -> argument.getClass().equals(UserId.class) : + argument -> argument.equals(userId); switch (matcherAdditionalInfos.size()) { case 1: Mockito.verify(auditLogService, times(cntTime)) .logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), - Mockito.eq(userId), + Mockito.argThat(matcherUserId), Mockito.eq(userName), Mockito.eq(originatorId), Mockito.argThat(matcherEntity), @@ -552,7 +536,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.verify(auditLogService, times(cntTime)) .logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), - Mockito.eq(userId), + Mockito.argThat(matcherUserId), Mockito.eq(userName), Mockito.eq(originatorId), Mockito.argThat(matcherEntity), @@ -564,7 +548,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.verify(auditLogService, times(cntTime)) .logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), - Mockito.eq(userId), + Mockito.argThat(matcherUserId), Mockito.eq(userName), Mockito.eq(originatorId), Mockito.argThat(matcherEntity), @@ -578,7 +562,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.verify(auditLogService, times(cntTime)) .logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), - Mockito.eq(userId), + Mockito.argThat(matcherUserId), Mockito.eq(userName), Mockito.eq(originatorId), Mockito.argThat(matcherEntity), diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java index 8ea89960d7..0f5ea5084f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java @@ -27,6 +27,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; @@ -52,6 +53,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; import java.util.ArrayList; import java.util.List; @@ -59,14 +61,15 @@ import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; public abstract class BaseDeviceControllerTest extends AbstractControllerTest { - static final TypeReference> PAGE_DATA_DEVICE_TYPE_REF = new TypeReference<>() { - }; + static final TypeReference> PAGE_DATA_DEVICE_TYPE_REF = new TypeReference<>() {}; ListeningExecutorService executor; @@ -76,6 +79,9 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { private Tenant savedTenant; private User tenantAdmin; + @SpyBean + private GatewayNotificationsService gatewayNotificationsService; + @Before public void beforeTest() throws Exception { executor = MoreExecutors.listeningDecorator(ThingsBoardExecutors.newWorkStealingPool(8, getClass())); @@ -1181,4 +1187,21 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { Assert.assertEquals(0, pageData.getData().size()); } + + + protected void testNotificationUpdateGatewayOneTime(Device device, Device oldDevice) { + Mockito.verify(gatewayNotificationsService, times(1)).onDeviceUpdated(Mockito.eq(device), Mockito.eq(oldDevice)); + } + + protected void testNotificationUpdateGatewayNever() { + Mockito.verify(gatewayNotificationsService, never()).onDeviceUpdated(Mockito.any(Device.class), Mockito.any(Device.class)); + } + + protected void testNotificationDeleteGatewayOneTime(Device device) { + Mockito.verify(gatewayNotificationsService, times(1)).onDeviceDeleted(device); + } + + protected void testNotificationDeleteGatewayNever() { + Mockito.verify(gatewayNotificationsService, never()).onDeviceDeleted(Mockito.any(Device.class)); + } } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java index 5b917ea8fa..3467a6f7a5 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java @@ -21,15 +21,18 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.RandomStringUtils; import org.junit.Assert; import org.junit.Test; +import org.mockito.Mockito; import org.springframework.http.HttpHeaders; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; 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 org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.service.mail.TestMailService; import java.util.ArrayList; @@ -42,11 +45,14 @@ import static org.hamcrest.Matchers.is; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.dao.model.ModelConstants.SYSTEM_TENANT; public abstract class BaseUserControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); + private CustomerId customerNUULId = (CustomerId) createEntityId_NULL_UUID(new Customer()); + @Test public void testSaveUser() throws Exception { loginSysAdmin(); @@ -58,6 +64,9 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { user.setEmail(email); user.setFirstName("Joe"); user.setLastName("Downs"); + + Mockito.reset(tbClusterService, auditLogService); + User savedUser = doPost("/api/user", user, User.class); Assert.assertNotNull(savedUser); Assert.assertNotNull(savedUser.getId()); @@ -67,6 +76,10 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { User foundUser = doGet("/api/user/" + savedUser.getId().getId().toString(), User.class); Assert.assertEquals(foundUser, savedUser); + testNotifyEntityAllOneTime(savedUser, savedUser.getId(), savedUser.getId(), + SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL, + ActionType.ADDED); + logout(); doGet("/api/noauth/activate?activateToken={activateToken}", TestMailService.currentActivateToken) .andExpect(status().isSeeOther()) @@ -94,14 +107,24 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { .andExpect(jsonPath("$.email", is(email))); loginSysAdmin(); + foundUser = doGet("/api/user/" + savedUser.getId().getId().toString(), User.class); + + Mockito.reset(tbClusterService, auditLogService); + doDelete("/api/user/" + savedUser.getId().getId().toString()) .andExpect(status().isOk()); + + testNotifyEntityOneTimeMsgToEdgeServiceNever(foundUser, foundUser.getId(), foundUser.getId(), + SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL, + ActionType.DELETED, foundUser.getId().getId().toString()); } @Test public void testSaveUserWithViolationOfFiledValidation() throws Exception { loginSysAdmin(); + Mockito.reset(tbClusterService, auditLogService); + String email = "tenant2@thingsboard.org"; User user = new User(); user.setAuthority(Authority.TENANT_ADMIN); @@ -109,10 +132,26 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { user.setEmail(email); user.setFirstName(RandomStringUtils.randomAlphabetic(300)); user.setLastName("Downs"); - doPost("/api/user", user).andExpect(statusReason(containsString("Validation error: length of first name must be equal or less than 255"))); + String msgError = msgErrorFieldLength("first name"); + doPost("/api/user", user) + .andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeServiceNeverError(user, + SYSTEM_TENANT, null, SYS_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); + Mockito.reset(tbClusterService, auditLogService); + user.setFirstName("Normal name"); + msgError = msgErrorFieldLength("last name"); user.setLastName(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/user", user).andExpect(statusReason(containsString("length of last name must be equal or less than 255"))); + doPost("/api/user", user) + .andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeServiceNeverError(user, + SYSTEM_TENANT, null, SYS_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); } @Test @@ -128,9 +167,16 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); loginDifferentTenant(); - doPost("/api/user", tenantAdmin, User.class, status().isForbidden()); - deleteDifferentTenant(); + Mockito.reset(tbClusterService, auditLogService); + + doPost("/api/user", tenantAdmin) + .andExpect(status().isForbidden()) + .andExpect(statusReason(containsString(msgErrorPermission))); + + testNotifyEntityNever(tenantAdmin.getId(), tenantAdmin); + + deleteDifferentTenant(); } @Test @@ -162,7 +208,9 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { .put("resetToken", TestMailService.currentResetPasswordToken) .put("password", "testPassword2"); - JsonNode tokenInfo = readResponse(doPost("/api/noauth/resetPassword", resetPasswordRequest).andExpect(status().isOk()), JsonNode.class); + JsonNode tokenInfo = readResponse( + doPost("/api/noauth/resetPassword", resetPasswordRequest) + .andExpect(status().isOk()), JsonNode.class); validateAndSetJwtToken(tokenInfo, email); doGet("/api/auth/user") @@ -205,6 +253,8 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { public void testSaveUserWithSameEmail() throws Exception { loginSysAdmin(); + Mockito.reset(tbClusterService, auditLogService); + String email = TENANT_ADMIN_EMAIL; User user = new User(); user.setAuthority(Authority.TENANT_ADMIN); @@ -213,15 +263,22 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { user.setFirstName("Joe"); user.setLastName("Downs"); + String msgError = "User with email '" + email + "' already present in database"; doPost("/api/user", user) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("User with email '" + email + "' already present in database"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeServiceNeverError(user, + SYSTEM_TENANT, null, SYS_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); } @Test public void testSaveUserWithInvalidEmail() throws Exception { loginSysAdmin(); + Mockito.reset(tbClusterService, auditLogService); + String email = "tenant_thingsboard.org"; User user = new User(); user.setAuthority(Authority.TENANT_ADMIN); @@ -230,39 +287,59 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { user.setFirstName("Joe"); user.setLastName("Downs"); + String msgError = "Invalid email address format '" + email + "'"; doPost("/api/user", user) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Invalid email address format '" + email + "'"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeServiceNeverError(user, + SYSTEM_TENANT, null, SYS_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); } @Test public void testSaveUserWithEmptyEmail() throws Exception { loginSysAdmin(); + Mockito.reset(tbClusterService, auditLogService); + User user = new User(); user.setAuthority(Authority.TENANT_ADMIN); user.setTenantId(tenantId); user.setFirstName("Joe"); user.setLastName("Downs"); + String msgError = "User email " + msgErrorShouldBeSpecified; doPost("/api/user", user) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("User email should be specified"))); + .andExpect(statusReason(containsString("User email " + msgErrorShouldBeSpecified))); + + testNotifyEntityEqualsOneTimeServiceNeverError(user, + SYSTEM_TENANT, null, SYS_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); } @Test public void testSaveUserWithoutTenant() throws Exception { loginSysAdmin(); + Mockito.reset(tbClusterService, auditLogService); + User user = new User(); user.setAuthority(Authority.TENANT_ADMIN); user.setEmail("tenant2@thingsboard.org"); user.setFirstName("Joe"); user.setLastName("Downs"); + String msgError = "Tenant administrator should be assigned to tenant"; doPost("/api/user", user) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Tenant administrator should be assigned to tenant"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityEqualsOneTimeServiceNeverError(user, + SYSTEM_TENANT, null, SYS_ADMIN_EMAIL, + ActionType.ADDED, new DataValidationException(msgError)); + } @Test @@ -284,8 +361,10 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { doDelete("/api/user/" + savedUser.getId().getId().toString()) .andExpect(status().isOk()); - doGet("/api/user/" + savedUser.getId().getId().toString()) - .andExpect(status().isNotFound()); + String userIdStr = savedUser.getId().getId().toString(); + doGet("/api/user/" + userIdStr) + .andExpect(status().isNotFound()) + .andExpect(statusReason(containsString( msgErrorNoFound("User",userIdStr)))); } @Test @@ -300,8 +379,11 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { TenantId tenantId = savedTenant.getId(); + Mockito.reset(tbClusterService, auditLogService); + + int cntEntity = 64; List tenantAdmins = new ArrayList<>(); - for (int i = 0; i < 64; i++) { + for (int i = 0; i < cntEntity; i++) { User user = new User(); user.setAuthority(Authority.TENANT_ADMIN); user.setTenantId(tenantId); @@ -309,12 +391,18 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { tenantAdmins.add(doPost("/api/user", user, User.class)); } + User testManyUser = new User(); + testManyUser.setTenantId(tenantId); + testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(testManyUser, testManyUser, + SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL, + ActionType.ADDED, ActionType.ADDED, cntEntity, cntEntity, cntEntity); + List loadedTenantAdmins = new ArrayList<>(); PageLink pageLink = new PageLink(33); PageData pageData = null; do { pageData = doGetTypedWithPageLink("/api/tenant/" + tenantId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); loadedTenantAdmins.addAll(pageData.getData()); if (pageData.hasNext()) { @@ -333,7 +421,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { pageLink = new PageLink(33); pageData = doGetTypedWithPageLink("/api/tenant/" + tenantId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertTrue(pageData.getData().isEmpty()); @@ -377,7 +465,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { PageData pageData = null; do { pageData = doGetTypedWithPageLink("/api/tenant/" + tenantId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); loadedTenantAdminsEmail1.addAll(pageData.getData()); if (pageData.hasNext()) { @@ -394,7 +482,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { pageLink = new PageLink(16, 0, email2); do { pageData = doGetTypedWithPageLink("/api/tenant/" + tenantId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); loadedTenantAdminsEmail2.addAll(pageData.getData()); if (pageData.hasNext()) { @@ -407,14 +495,22 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { Assert.assertEquals(tenantAdminsEmail2, loadedTenantAdminsEmail2); + Mockito.reset(tbClusterService, auditLogService); + + int cntEntity = loadedTenantAdminsEmail1.size(); for (User user : loadedTenantAdminsEmail1) { doDelete("/api/user/" + user.getId().getId().toString()) .andExpect(status().isOk()); } + User testManyUser = new User(); + testManyUser.setTenantId(tenantId); + testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny(testManyUser, testManyUser, + SYSTEM_TENANT, customerNUULId, null, SYS_ADMIN_EMAIL, + ActionType.DELETED, ActionType.DELETED, cntEntity, 0, cntEntity, new String()); pageLink = new PageLink(4, 0, email1); pageData = doGetTypedWithPageLink("/api/tenant/" + tenantId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(0, pageData.getData().size()); @@ -426,7 +522,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { pageLink = new PageLink(4, 0, email2); pageData = doGetTypedWithPageLink("/api/tenant/" + tenantId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(0, pageData.getData().size()); @@ -443,7 +539,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { tenantAdmin.setFirstName("Joe"); tenantAdmin.setLastName("Downs"); - tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); + createUserAndLogin(tenantAdmin, "testPassword1"); Customer customer = new Customer(); customer.setTitle("My customer"); @@ -465,7 +561,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { PageData pageData = null; do { pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); loadedCustomerUsers.addAll(pageData.getData()); if (pageData.hasNext()) { @@ -493,7 +589,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { tenantAdmin.setFirstName("Joe"); tenantAdmin.setLastName("Downs"); - tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); + createUserAndLogin(tenantAdmin, "testPassword1"); Customer customer = new Customer(); customer.setTitle("My customer"); @@ -531,10 +627,10 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { List loadedCustomerUsersEmail1 = new ArrayList<>(); PageLink pageLink = new PageLink(33, 0, email1); - PageData pageData = null; + PageData pageData; do { pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); loadedCustomerUsersEmail1.addAll(pageData.getData()); if (pageData.hasNext()) { @@ -551,7 +647,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { pageLink = new PageLink(16, 0, email2); do { pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); loadedCustomerUsersEmail2.addAll(pageData.getData()); if (pageData.hasNext()) { @@ -571,7 +667,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { pageLink = new PageLink(4, 0, email1); pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(0, pageData.getData().size()); @@ -583,7 +679,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { pageLink = new PageLink(4, 0, email2); pageData = doGetTypedWithPageLink("/api/customer/" + customerId.getId().toString() + "/users?", - new TypeReference>() { + new TypeReference<>() { }, pageLink); Assert.assertFalse(pageData.hasNext()); Assert.assertEquals(0, pageData.getData().size()); @@ -591,5 +687,4 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { doDelete("/api/customer/" + customerId.getId().toString()) .andExpect(status().isOk()); } - }