diff --git a/config/settings/base.py b/config/settings/base.py index bd31cfe98b..9755ac871c 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -460,7 +460,7 @@ def safe_key() -> str: ], 'DEFAULT_THROTTLE_RATES': { 'anon': '4/second', - 'user': '4/second' + 'user': '4/second', } } diff --git a/locales_dev/en/translation.json b/locales_dev/en/translation.json index 99a876efe1..b6542aa5c8 100644 --- a/locales_dev/en/translation.json +++ b/locales_dev/en/translation.json @@ -99,6 +99,7 @@ "Share Link to Installation Job": "Share Link to Installation Job", "Show Logs": "Show Logs", "Skipped": "Skipped", + "Something went wrong. Please try again later.": "Something went wrong. Please try again later.", "Start Pre-Install Validation": "Start Pre-Install Validation", "Start Pre-Install Validation on Scratch Org": "Start Pre-Install Validation on Scratch Org", "Steps": "Steps", diff --git a/metadeploy/adminapi/api.py b/metadeploy/adminapi/api.py index 35981319ca..2e42eadaf4 100644 --- a/metadeploy/adminapi/api.py +++ b/metadeploy/adminapi/api.py @@ -138,6 +138,7 @@ class Meta: class PlanTemplateViewSet(AdminAPIViewSet): model_name = "PlanTemplate" serializer_base = PlanTemplateSerializer + throttle_classes = [] class PlanFilter(filters.FilterSet): @@ -150,22 +151,27 @@ class PlanViewSet(AdminAPIViewSet): model_name = "Plan" serializer_base = PlanSerializer filterset_class = PlanFilter + throttle_classes = [] class PlanSlugViewSet(AdminAPIViewSet): model_name = "PlanSlug" + throttle_classes = [] class VersionViewSet(AdminAPIViewSet): model_name = "Version" + throttle_classes = [] class ProductCategoryViewSet(AdminAPIViewSet): model_name = "ProductCategory" + throttle_classes = [] class AllowedListViewSet(AdminAPIViewSet): model_name = "AllowedList" + throttle_classes = [] class AllowedListOrgSerializer(AdminAPISerializer): @@ -175,6 +181,7 @@ class AllowedListOrgSerializer(AdminAPISerializer): class AllowedListOrgViewSet(AdminAPIViewSet): model_name = "AllowedListOrg" serializer_base = AllowedListOrgSerializer + throttle_classes = [] class TranslationViewSet(viewsets.ViewSet): @@ -194,6 +201,7 @@ class TranslationViewSet(viewsets.ViewSet): permission_classes = [IsAPIUser] model_name = "Translation" + throttle_classes = [] def partial_update(self, request, pk=None): # Add or update a Translation record for each message diff --git a/metadeploy/adminapi/tests/test_api.py b/metadeploy/adminapi/tests/test_api.py index 6244fa023e..bc28d1f7d5 100644 --- a/metadeploy/adminapi/tests/test_api.py +++ b/metadeploy/adminapi/tests/test_api.py @@ -86,6 +86,14 @@ def test_list(self, admin_api_client, plan_factory): "meta": {"page": {"total": 1}}, } + def test_throttle(self, admin_api_client): + url = "http://testserver/admin/rest/allowedlistorgs" + for i in range(0, 4): + response = admin_api_client.get(url) + + response = admin_api_client.get(url) + assert response.status_code == 200 + def test_retrieve(self, admin_api_client, step_factory): step = step_factory() plan = step.plan diff --git a/package.json b/package.json index 4b372052c3..acf432466c 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "heroku-postbuild": "yarn prod" }, "dependencies": { - "@omnistudio/omniscript-lwc-compiler": "^244.4.0", "@react-hook/window-scroll": "^1.3.0", "@salesforce-ux/design-system": "^2.18.1", "@salesforce/design-system-react": "^0.10.48", @@ -154,6 +153,9 @@ "webpack-dev-server": "^4.9.3", "webpack-merge": "^5.8.0" }, + "optionalDependencies": { + "@omnistudio/omniscript-lwc-compiler": "^244.4.0" + }, "resolutions": { "@storybook/**/ansi-regex": "^5.0.1", "@storybook/**/glob-parent": "^5.1.2", diff --git a/src/js/components/apiErrors.tsx b/src/js/components/apiErrors.tsx index 9b18c8585e..f17d05a274 100644 --- a/src/js/components/apiErrors.tsx +++ b/src/js/components/apiErrors.tsx @@ -18,6 +18,15 @@ const ErrorToast = ({ doRemoveError: typeof removeError; }) => { const { t } = useTranslation(); + + if ( + error.message && + typeof error.message === 'string' && + /<[a-z][\s\S]*>/i.test(error.message) + ) { + error.message = t('Something went wrong. Please try again later.'); + } + return ( 500 && response.status <= 600) { + msg = 'Something went wrong. Please try again later.'; + } dispatch(addError(msg)); const error: ApiError = new Error(msg); error.response = response; diff --git a/test/js/components/apiErrors.test.js b/test/js/components/apiErrors.test.js index 9ddd68085a..8907ede4d6 100644 --- a/test/js/components/apiErrors.test.js +++ b/test/js/components/apiErrors.test.js @@ -16,6 +16,16 @@ describe('', () => { return { getByText }; }; + const setupforRawHTML = () => { + const errors = [ + { id: 'err1', message: '
This is Error
' }, + ]; + const { getByText } = render( + , + ); + return { getByText }; + }; + test('calls window.location.reload on link click', () => { const { getByText } = setup(); @@ -24,6 +34,13 @@ describe('', () => { expect(window.location.reload).toHaveBeenCalledTimes(1); }); + test('for raw html error', () => { + const { getByText } = setupforRawHTML(); + + expect( + getByText('Something went wrong. Please try again later.'), + ).toBeVisible(); + }); test('calls doRemoveError on close click', () => { const { getByText } = setup(); diff --git a/test/js/utils/api.test.js b/test/js/utils/api.test.js index 0d7235f346..4a4b7a8a15 100644 --- a/test/js/utils/api.test.js +++ b/test/js/utils/api.test.js @@ -35,6 +35,14 @@ describe('apiFetch', () => { }); describe('error', () => { + test('throws Error for status code greater than 500', () => { + fetchMock.getOnce('/test/url/', { status: 503, body: {} }); + + expect.assertions(1); + return expect(apiFetch('/test/url/', dispatch)).rejects.toThrow( + 'Something went wrong. Please try again later.', + ); + }); test('throws Error without response', () => { fetchMock.getOnce('/test/url/', { status: 500, body: {} });