@ -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 < User > 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,11 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
User foundUser = doGet ( "/api/user/" + savedUser . getId ( ) . getId ( ) . toString ( ) , User . class ) ;
Assert . assertEquals ( foundUser , savedUser ) ;
testNotifyManyEntityManyTimeMsgToEdgeServiceEntityEqAny ( foundUser , foundUser ,
SYSTEM_TENANT , customerNUULId , null , SYS_ADMIN_EMAIL ,
ActionType . ADDED , ActionType . ADDED , 1 , 1 , 1 ) ;
Mockito . reset ( tbClusterService , auditLogService ) ;
logout ( ) ;
doGet ( "/api/noauth/activate?activateToken={activateToken}" , TestMailService . currentActivateToken )
. andExpect ( status ( ) . isSeeOther ( ) )
@ -94,14 +108,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 +133,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 +168,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 +209,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 +254,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 +264,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 +288,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 +362,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 +380,11 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
TenantId tenantId = savedTenant . getId ( ) ;
Mockito . reset ( tbClusterService , auditLogService ) ;
int cntEntity = 64 ;
List < User > 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 +392,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 < User > loadedTenantAdmins = new ArrayList < > ( ) ;
PageLink pageLink = new PageLink ( 33 ) ;
PageData < User > pageData = null ;
do {
pageData = doGetTypedWithPageLink ( "/api/tenant/" + tenantId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
loadedTenantAdmins . addAll ( pageData . getData ( ) ) ;
if ( pageData . hasNext ( ) ) {
@ -333,7 +422,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
pageLink = new PageLink ( 33 ) ;
pageData = doGetTypedWithPageLink ( "/api/tenant/" + tenantId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
Assert . assertFalse ( pageData . hasNext ( ) ) ;
Assert . assertTrue ( pageData . getData ( ) . isEmpty ( ) ) ;
@ -377,7 +466,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
PageData < User > pageData = null ;
do {
pageData = doGetTypedWithPageLink ( "/api/tenant/" + tenantId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
loadedTenantAdminsEmail1 . addAll ( pageData . getData ( ) ) ;
if ( pageData . hasNext ( ) ) {
@ -394,7 +483,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
pageLink = new PageLink ( 16 , 0 , email2 ) ;
do {
pageData = doGetTypedWithPageLink ( "/api/tenant/" + tenantId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
loadedTenantAdminsEmail2 . addAll ( pageData . getData ( ) ) ;
if ( pageData . hasNext ( ) ) {
@ -407,14 +496,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 < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
Assert . assertFalse ( pageData . hasNext ( ) ) ;
Assert . assertEquals ( 0 , pageData . getData ( ) . size ( ) ) ;
@ -426,7 +523,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
pageLink = new PageLink ( 4 , 0 , email2 ) ;
pageData = doGetTypedWithPageLink ( "/api/tenant/" + tenantId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
Assert . assertFalse ( pageData . hasNext ( ) ) ;
Assert . assertEquals ( 0 , pageData . getData ( ) . size ( ) ) ;
@ -443,7 +540,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 +562,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
PageData < User > pageData = null ;
do {
pageData = doGetTypedWithPageLink ( "/api/customer/" + customerId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
loadedCustomerUsers . addAll ( pageData . getData ( ) ) ;
if ( pageData . hasNext ( ) ) {
@ -493,7 +590,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 +628,10 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
List < User > loadedCustomerUsersEmail1 = new ArrayList < > ( ) ;
PageLink pageLink = new PageLink ( 33 , 0 , email1 ) ;
PageData < User > pageData = null ;
PageData < User > pageData ;
do {
pageData = doGetTypedWithPageLink ( "/api/customer/" + customerId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
loadedCustomerUsersEmail1 . addAll ( pageData . getData ( ) ) ;
if ( pageData . hasNext ( ) ) {
@ -551,7 +648,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
pageLink = new PageLink ( 16 , 0 , email2 ) ;
do {
pageData = doGetTypedWithPageLink ( "/api/customer/" + customerId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
loadedCustomerUsersEmail2 . addAll ( pageData . getData ( ) ) ;
if ( pageData . hasNext ( ) ) {
@ -571,7 +668,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
pageLink = new PageLink ( 4 , 0 , email1 ) ;
pageData = doGetTypedWithPageLink ( "/api/customer/" + customerId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
Assert . assertFalse ( pageData . hasNext ( ) ) ;
Assert . assertEquals ( 0 , pageData . getData ( ) . size ( ) ) ;
@ -583,7 +680,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
pageLink = new PageLink ( 4 , 0 , email2 ) ;
pageData = doGetTypedWithPageLink ( "/api/customer/" + customerId . getId ( ) . toString ( ) + "/users?" ,
new TypeReference < PageData < User > > ( ) {
new TypeReference < > ( ) {
} , pageLink ) ;
Assert . assertFalse ( pageData . hasNext ( ) ) ;
Assert . assertEquals ( 0 , pageData . getData ( ) . size ( ) ) ;
@ -591,5 +688,4 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest {
doDelete ( "/api/customer/" + customerId . getId ( ) . toString ( ) )
. andExpect ( status ( ) . isOk ( ) ) ;
}
}