diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java
index 7bc6f9876c..51d77bd134 100644
--- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java
+++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java
@@ -38,8 +38,6 @@ import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.http.HttpHeaders;
@@ -53,6 +51,8 @@ import org.springframework.mock.http.MockHttpInputMessage;
import org.springframework.mock.http.MockHttpOutputMessage;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.mock.web.MockPart;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
@@ -167,6 +167,7 @@ import org.thingsboard.server.service.entitiy.tenant.profile.TbTenantProfileServ
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRequest;
import org.thingsboard.server.service.security.auth.rest.LoginRequest;
import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
+import org.thingsboard.server.service.system.SystemPatchApplier;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@@ -295,18 +296,21 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
@Autowired
private JwtTokenFactory jwtTokenFactory;
- @SpyBean
- protected MailService mailService;
-
@Autowired
protected InMemoryStorage storage;
@Autowired
protected JdbcTemplate jdbcTemplate;
- @MockBean
+ @MockitoSpyBean
+ protected MailService mailService;
+
+ @MockitoBean
protected CfRocksDb cfRocksDb;
+ @MockitoBean
+ protected SystemPatchApplier systemPatchApplier;
+
@Rule
public TestRule watcher = new TestWatcher() {
protected void starting(Description description) {
diff --git a/ui-ngx/src/app/core/interceptors/global-http-interceptor.ts b/ui-ngx/src/app/core/interceptors/global-http-interceptor.ts
index dccda985b4..af204fc99b 100644
--- a/ui-ngx/src/app/core/interceptors/global-http-interceptor.ts
+++ b/ui-ngx/src/app/core/interceptors/global-http-interceptor.ts
@@ -125,6 +125,10 @@ export class GlobalHttpInterceptor implements HttpInterceptor {
this.showError(req.method + ': ' + req.url + '
' +
errorResponse.status + ': ' + errorResponse.statusText);
}
+ } else if (errorResponse.status === 504) {
+ if (!ignoreErrors) {
+ this.showError('Request timeout');
+ }
} else {
unhandled = true;
}
diff --git a/ui-ngx/src/app/modules/home/pages/admin/resource/js-resource.component.ts b/ui-ngx/src/app/modules/home/pages/admin/resource/js-resource.component.ts
index 4a67bd10c8..ca52d61ccf 100644
--- a/ui-ngx/src/app/modules/home/pages/admin/resource/js-resource.component.ts
+++ b/ui-ngx/src/app/modules/home/pages/admin/resource/js-resource.component.ts
@@ -32,7 +32,7 @@ import {
} from '@shared/models/resource.models';
import { startWith, takeUntil } from 'rxjs/operators';
import { ActionNotificationShow } from '@core/notification/notification.actions';
-import { isDefinedAndNotNull } from '@core/utils';
+import { base64toString, isDefinedAndNotNull, stringToBase64 } from '@core/utils';
import { getCurrentAuthState } from '@core/auth/auth.selectors';
@Component({
@@ -84,13 +84,13 @@ export class JsResourceComponent extends EntityComponent implements On
resourceSubType: [entity?.resourceSubType ? entity.resourceSubType : ResourceSubType.EXTENSION, Validators.required],
fileName: [entity ? entity.fileName : null, Validators.required],
data: [entity ? entity.data : null, this.isAdd ? [Validators.required] : []],
- content: [entity?.data?.length ? window.atob(entity.data) : '', Validators.required]
+ content: [entity?.data?.length ? base64toString(entity.data) : '', Validators.required]
});
}
updateForm(entity: Resource): void {
this.entityForm.patchValue(entity);
- const content = entity.resourceSubType === ResourceSubType.MODULE && entity?.data?.length ? window.atob(entity.data) : '';
+ const content = entity.resourceSubType === ResourceSubType.MODULE && entity?.data?.length ? base64toString(entity.data) : '';
this.entityForm.get('content').patchValue(content);
}
@@ -110,7 +110,7 @@ export class JsResourceComponent extends EntityComponent implements On
if (!formValue.fileName) {
formValue.fileName = formValue.title + '.js';
}
- formValue.data = window.btoa((formValue as any).content);
+ formValue.data = stringToBase64((formValue as any).content);
delete (formValue as any).content;
}
return super.prepareFormValue(formValue);