@northern.tech/store 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +9 -0
- package/.prettierignore +1 -0
- package/CHANGELOG.md +12 -0
- package/actions.ts +32 -0
- package/api/general-api.test.ts +51 -0
- package/api/general-api.ts +60 -0
- package/api/types/AWSCredentials.ts +16 -0
- package/api/types/Actor.ts +35 -0
- package/api/types/Addon.ts +17 -0
- package/api/types/AddonTenantadm.ts +17 -0
- package/api/types/Alert.ts +34 -0
- package/api/types/AlertDetails.ts +23 -0
- package/api/types/AlertSubject.ts +23 -0
- package/api/types/ApiBurst.ts +21 -0
- package/api/types/ApiBurstTenantadm.ts +21 -0
- package/api/types/ApiLimits.ts +16 -0
- package/api/types/ApiLimitsTenantadm.ts +16 -0
- package/api/types/ApiQuota.ts +17 -0
- package/api/types/ApiQuotaTenantadm.ts +17 -0
- package/api/types/Artifact.ts +48 -0
- package/api/types/ArtifactDeployments.ts +48 -0
- package/api/types/ArtifactInfo.ts +11 -0
- package/api/types/ArtifactInfoDeployments.ts +11 -0
- package/api/types/ArtifactLink.ts +11 -0
- package/api/types/ArtifactTypeInfo.ts +13 -0
- package/api/types/ArtifactTypeInfoDeployments.ts +13 -0
- package/api/types/ArtifactUpdate.ts +10 -0
- package/api/types/ArtifactUploadLink.ts +15 -0
- package/api/types/Attribute.ts +36 -0
- package/api/types/AttributeInventory.ts +32 -0
- package/api/types/AuditLog.ts +26 -0
- package/api/types/AuthSet.ts +33 -0
- package/api/types/AuthSetDeviceauth.ts +37 -0
- package/api/types/AutoAuthRequest.ts +23 -0
- package/api/types/AzureSharedAccessSecret.ts +11 -0
- package/api/types/BillingInfo.ts +13 -0
- package/api/types/BinaryDeltaConfiguration.ts +15 -0
- package/api/types/BinaryDeltaConfigurationDeployments.ts +15 -0
- package/api/types/BinaryDeltaLimits.ts +15 -0
- package/api/types/BinaryDeltaLimitsDeployments.ts +15 -0
- package/api/types/BoundingBox.ts +11 -0
- package/api/types/CancelRequest.ts +10 -0
- package/api/types/CardData.ts +49 -0
- package/api/types/CardSetupData.ts +17 -0
- package/api/types/CheckoutData.ts +13 -0
- package/api/types/Configuration.ts +11 -0
- package/api/types/Count.ts +13 -0
- package/api/types/Credentials.ts +23 -0
- package/api/types/DBusSubsystem.ts +27 -0
- package/api/types/DeltaConfiguration.ts +14 -0
- package/api/types/DeltaConfigurationDeployments.ts +14 -0
- package/api/types/Deployment.ts +95 -0
- package/api/types/DeploymentAggregation.ts +18 -0
- package/api/types/DeploymentAggregationItem.ts +18 -0
- package/api/types/DeploymentAggregationTerm.ts +23 -0
- package/api/types/DeploymentAggregationTerms.ts +18 -0
- package/api/types/DeploymentAttributeProjection.ts +11 -0
- package/api/types/DeploymentAuditlogs.ts +11 -0
- package/api/types/DeploymentDeployments.ts +99 -0
- package/api/types/DeploymentFilterTerm.ts +37 -0
- package/api/types/DeploymentIdentifier.ts +10 -0
- package/api/types/DeploymentPhase.ts +23 -0
- package/api/types/DeploymentReporting.ts +46 -0
- package/api/types/DeploymentSearchTerms.ts +39 -0
- package/api/types/DeploymentSortTerm.ts +25 -0
- package/api/types/DeploymentStatistics.ts +15 -0
- package/api/types/DeploymentStatusStatistics.ts +54 -0
- package/api/types/Device.ts +29 -0
- package/api/types/DeviceAggregation.ts +18 -0
- package/api/types/DeviceAggregationItem.ts +18 -0
- package/api/types/DeviceAggregationTerm.ts +27 -0
- package/api/types/DeviceAggregationTerms.ts +22 -0
- package/api/types/DeviceAttribute.ts +23 -0
- package/api/types/DeviceAttributeProjection.ts +15 -0
- package/api/types/DeviceAuditlogs.ts +17 -0
- package/api/types/DeviceAuthEvent.ts +23 -0
- package/api/types/DeviceConfiguration.ts +16 -0
- package/api/types/DeviceDeployment.ts +11 -0
- package/api/types/DeviceDeployments.ts +31 -0
- package/api/types/DeviceDeviceauth.ts +42 -0
- package/api/types/DeviceFilterAttribute.ts +22 -0
- package/api/types/DeviceFilterTerm.ts +41 -0
- package/api/types/DeviceInventory.ts +19 -0
- package/api/types/DeviceInventoryInventory.ts +19 -0
- package/api/types/DeviceReporting.ts +22 -0
- package/api/types/DeviceSearchTerms.ts +39 -0
- package/api/types/DeviceSortTerm.ts +29 -0
- package/api/types/DeviceState.ts +32 -0
- package/api/types/DeviceStateDeviceconnect.ts +33 -0
- package/api/types/DeviceStateIot_manager.ts +14 -0
- package/api/types/DeviceStatus.ts +19 -0
- package/api/types/DeviceWithImage.ts +80 -0
- package/api/types/DirectUploadMetadata.ts +18 -0
- package/api/types/EmailVerificationCompletion.ts +13 -0
- package/api/types/EmailVerificationRequest.ts +13 -0
- package/api/types/Error.ts +17 -0
- package/api/types/ErrorAuditlogs.ts +13 -0
- package/api/types/ErrorDeployments.ts +17 -0
- package/api/types/ErrorDeviceauth.ts +13 -0
- package/api/types/ErrorDeviceconfig.ts +17 -0
- package/api/types/ErrorDeviceconnect.ts +17 -0
- package/api/types/ErrorDevicemonitor.ts +17 -0
- package/api/types/ErrorExt.ts +18 -0
- package/api/types/ErrorInventory.ts +17 -0
- package/api/types/ErrorIot_manager.ts +17 -0
- package/api/types/ErrorNotFound.ts +17 -0
- package/api/types/ErrorReporting.ts +18 -0
- package/api/types/ErrorTenantadm.ts +13 -0
- package/api/types/ErrorUseradm.ts +17 -0
- package/api/types/Event.ts +48 -0
- package/api/types/ExternalIdentity.ts +17 -0
- package/api/types/Features.ts +17 -0
- package/api/types/FileUpload.ts +23 -0
- package/api/types/Filter.ts +19 -0
- package/api/types/FilterAttribute.ts +21 -0
- package/api/types/FilterDefinition.ts +18 -0
- package/api/types/FilterDeployments.ts +19 -0
- package/api/types/FilterInventory.ts +20 -0
- package/api/types/FilterPredicate.ts +78 -0
- package/api/types/FilterPredicateDeployments.ts +48 -0
- package/api/types/FilterPredicateInventory.ts +76 -0
- package/api/types/GeoBoundingBox.ts +10 -0
- package/api/types/GeoBoundingBoxFilter.ts +6 -0
- package/api/types/GeoDistance.ts +17 -0
- package/api/types/GeoDistanceFilter.ts +10 -0
- package/api/types/GeoPoint.ts +15 -0
- package/api/types/Group.ts +10 -0
- package/api/types/HTTP.ts +19 -0
- package/api/types/IdentityData.ts +25 -0
- package/api/types/InputParameter.ts +8 -0
- package/api/types/Integration.ts +24 -0
- package/api/types/JobStatus.ts +13 -0
- package/api/types/Limit.ts +21 -0
- package/api/types/LimitDeployments.ts +21 -0
- package/api/types/LimitDeviceauth.ts +10 -0
- package/api/types/LimitUseradm.ts +11 -0
- package/api/types/Limits.ts +11 -0
- package/api/types/LineDescriptor.ts +11 -0
- package/api/types/LogSubsystem.ts +23 -0
- package/api/types/LoginOptions.ts +18 -0
- package/api/types/ManagementAPIConfiguration.ts +5 -0
- package/api/types/MenderTypes.ts +183 -0
- package/api/types/MonitorConfiguration.ts +22 -0
- package/api/types/NewConfigurationDeployment.ts +15 -0
- package/api/types/NewConfigurationDeploymentResponse.ts +10 -0
- package/api/types/NewDeployment.ts +42 -0
- package/api/types/NewDeploymentForGroup.ts +33 -0
- package/api/types/NewDeploymentPhase.ts +37 -0
- package/api/types/NewDeploymentPhaseDeployments.ts +20 -0
- package/api/types/NewDeploymentV2.ts +31 -0
- package/api/types/NewTenant.ts +41 -0
- package/api/types/Object.ts +35 -0
- package/api/types/OwnUserUpdate.ts +21 -0
- package/api/types/PasswordResetCompletion.ts +17 -0
- package/api/types/PasswordResetRequest.ts +13 -0
- package/api/types/Permission.ts +21 -0
- package/api/types/PermissionObject.ts +14 -0
- package/api/types/PermissionSet.ts +22 -0
- package/api/types/PermissionSetWithScope.ts +15 -0
- package/api/types/PersonalAccessToken.ts +29 -0
- package/api/types/PersonalAccessTokenRequest.ts +18 -0
- package/api/types/Plan.ts +19 -0
- package/api/types/PlanBindingDetails.ts +13 -0
- package/api/types/PlanChangeRequest.ts +14 -0
- package/api/types/PlanLimits.ts +12 -0
- package/api/types/PreAuthSet.ts +16 -0
- package/api/types/Release.ts +32 -0
- package/api/types/ReleaseDeployments.ts +32 -0
- package/api/types/ReleaseUpdate.ts +13 -0
- package/api/types/Releases.ts +9 -0
- package/api/types/ReleasesDeleteError.ts +21 -0
- package/api/types/ReleasesDeployments.ts +9 -0
- package/api/types/Role.ts +19 -0
- package/api/types/RolePermission.ts +25 -0
- package/api/types/RolePermissionObject.ts +17 -0
- package/api/types/RoleUseradm.ts +19 -0
- package/api/types/SAMLMetadata.ts +21 -0
- package/api/types/Scope.ts +19 -0
- package/api/types/SelectAttribute.ts +17 -0
- package/api/types/ServiceSubsystem.ts +19 -0
- package/api/types/Settings.ts +23 -0
- package/api/types/SortCriteria.ts +30 -0
- package/api/types/SsoObject.ts +21 -0
- package/api/types/Status.ts +17 -0
- package/api/types/StatusDeviceauth.ts +18 -0
- package/api/types/StatusTenantadm.ts +19 -0
- package/api/types/StorageLimit.ts +17 -0
- package/api/types/SubscriptionData.ts +8 -0
- package/api/types/SupportRequest.ts +17 -0
- package/api/types/Tag.ts +27 -0
- package/api/types/Tags.ts +10 -0
- package/api/types/TaskResult.ts +13 -0
- package/api/types/TaskResultCLI.ts +10 -0
- package/api/types/TaskResultHTTPRequest.ts +8 -0
- package/api/types/TaskResultHTTPResponse.ts +10 -0
- package/api/types/Tenant.ts +38 -0
- package/api/types/TenantApiLimits.ts +12 -0
- package/api/types/TenantApiLimitsTenantadm.ts +12 -0
- package/api/types/TenantIdName.ts +14 -0
- package/api/types/TenantIdsData.ts +10 -0
- package/api/types/TenantInfo.ts +14 -0
- package/api/types/TenantShortInfo.ts +21 -0
- package/api/types/TenantTenantadm.ts +38 -0
- package/api/types/TenantsIdName.ts +6 -0
- package/api/types/Update.ts +17 -0
- package/api/types/UpdateDeployments.ts +18 -0
- package/api/types/UpdateFile.ts +13 -0
- package/api/types/UpdateFileDeployments.ts +13 -0
- package/api/types/UpdateTypes.ts +8 -0
- package/api/types/UpgradeCompleteRequest.ts +23 -0
- package/api/types/User.ts +13 -0
- package/api/types/UserAuditlogs.ts +13 -0
- package/api/types/UserNew.ts +26 -0
- package/api/types/UserUpdate.ts +25 -0
- package/api/types/UserUseradm.ts +45 -0
- package/api/types/UserWithTenantInfo.ts +8 -0
- package/api/types/XDeltaArgs.ts +9 -0
- package/api/types/XDeltaArgsDeployments.ts +9 -0
- package/api/types/XDeltaArgsLimits.ts +10 -0
- package/api/types/XDeltaArgsLimitsDeployments.ts +10 -0
- package/api/users-api.ts +34 -0
- package/appSlice/constants.ts +166 -0
- package/appSlice/index.ts +159 -0
- package/appSlice/reducer.test.ts +97 -0
- package/appSlice/selectors.ts +33 -0
- package/appSlice/thunks.test.ts +118 -0
- package/appSlice/thunks.ts +148 -0
- package/auth.test.ts +36 -0
- package/auth.ts +82 -0
- package/commonConstants.tsx +252 -0
- package/commonSelectors.ts +255 -0
- package/constants.ts +22 -0
- package/deploymentsSlice/constants.ts +175 -0
- package/deploymentsSlice/index.ts +145 -0
- package/deploymentsSlice/reducer.test.ts +108 -0
- package/deploymentsSlice/selectors.ts +58 -0
- package/deploymentsSlice/thunks.test.ts +425 -0
- package/deploymentsSlice/thunks.ts +382 -0
- package/devicesSlice/constants.ts +56 -0
- package/devicesSlice/index.ts +207 -0
- package/devicesSlice/reducer.test.ts +194 -0
- package/devicesSlice/selectors.ts +127 -0
- package/devicesSlice/thunks.test.tsx +1245 -0
- package/devicesSlice/thunks.tsx +1098 -0
- package/monitorSlice/constants.ts +17 -0
- package/monitorSlice/index.ts +65 -0
- package/monitorSlice/reducer.test.ts +79 -0
- package/monitorSlice/selectors.ts +15 -0
- package/monitorSlice/thunks.test.ts +112 -0
- package/monitorSlice/thunks.ts +101 -0
- package/onboardingSlice/constants.ts +53 -0
- package/onboardingSlice/index.ts +60 -0
- package/onboardingSlice/reducer.test.ts +45 -0
- package/onboardingSlice/selectors.ts +15 -0
- package/onboardingSlice/thunks.test.ts +235 -0
- package/onboardingSlice/thunks.ts +142 -0
- package/organizationSlice/constants.ts +82 -0
- package/organizationSlice/index.ts +111 -0
- package/organizationSlice/reducer.test.ts +78 -0
- package/organizationSlice/selectors.ts +45 -0
- package/organizationSlice/thunks.test.ts +619 -0
- package/organizationSlice/thunks.ts +383 -0
- package/package.json +38 -0
- package/releasesSlice/constants.ts +18 -0
- package/releasesSlice/index.ts +116 -0
- package/releasesSlice/reducer.test.ts +78 -0
- package/releasesSlice/selectors.ts +33 -0
- package/releasesSlice/thunks.test.ts +389 -0
- package/releasesSlice/thunks.ts +379 -0
- package/selectors.ts +22 -0
- package/store.ts +89 -0
- package/storehooks.test.tsx +386 -0
- package/storehooks.ts +250 -0
- package/thunks.ts +21 -0
- package/tsconfig.json +11 -0
- package/tsup.config.ts +11 -0
- package/usersSlice/constants.ts +374 -0
- package/usersSlice/index.ts +151 -0
- package/usersSlice/reducer.test.ts +141 -0
- package/usersSlice/selectors.ts +60 -0
- package/usersSlice/thunks.test.ts +660 -0
- package/usersSlice/thunks.ts +773 -0
- package/utils.test.ts +187 -0
- package/utils.ts +249 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Copyright 2023 Northern.tech AS
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { EXTERNAL_PROVIDER } from '@northern.tech/store/constants';
|
|
15
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
16
|
+
|
|
17
|
+
export const getOrganization = state => state.organization.organization;
|
|
18
|
+
export const getExternalIntegrations = state => state.organization.externalDeviceIntegrations;
|
|
19
|
+
export const getAuditlogState = state => state.organization.auditlog.selectionState;
|
|
20
|
+
export const getAuditLog = state => state.organization.auditlog.events;
|
|
21
|
+
export const getAuditLogSelectionState = state => state.organization.auditlog.selectionState;
|
|
22
|
+
export const getSsoConfig = ({ organization: { ssoConfigs = [] } }) => ssoConfigs[0];
|
|
23
|
+
export const getTenantsList = state => state.organization.organization.tenantList;
|
|
24
|
+
export const getWebhookEvents = state => state.organization.webhooks.events;
|
|
25
|
+
export const getWebhookEventTotal = state => state.organization.webhooks.eventTotal;
|
|
26
|
+
|
|
27
|
+
export const getDeviceTwinIntegrations = createSelector([getExternalIntegrations], integrations =>
|
|
28
|
+
integrations.filter(integration => integration.id && EXTERNAL_PROVIDER[integration.provider]?.deviceTwin)
|
|
29
|
+
);
|
|
30
|
+
export const getIsServiceProvider = state => state.organization.organization.service_provider;
|
|
31
|
+
|
|
32
|
+
export const getWebhooks = createSelector([getExternalIntegrations], integrations =>
|
|
33
|
+
integrations.filter(integration => integration.id && integration.provider === EXTERNAL_PROVIDER.webhook.provider)
|
|
34
|
+
);
|
|
35
|
+
export const getWebhookEventInfo = createSelector([getWebhooks, getWebhookEvents, getWebhookEventTotal], (webhooks, events, eventTotal) =>
|
|
36
|
+
webhooks.length ? { events, eventTotal } : { events: [], eventTotal: 0 }
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
export const getAuditLogEntry = createSelector([getAuditLog, getAuditLogSelectionState], (events, { selectedId }) => {
|
|
40
|
+
if (!selectedId) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const [eventAction, eventTime] = atob(selectedId).split('|');
|
|
44
|
+
return events.find(item => item.action === eventAction && item.time === eventTime);
|
|
45
|
+
});
|
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
// Copyright 2020 Northern.tech AS
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
// @ts-nocheck
|
|
15
|
+
import { EXTERNAL_PROVIDER } from '@northern.tech/store/commonConstants';
|
|
16
|
+
import configureMockStore from 'redux-mock-store';
|
|
17
|
+
import { thunk } from 'redux-thunk';
|
|
18
|
+
|
|
19
|
+
import { actions } from '.';
|
|
20
|
+
import { defaultState, webhookEvents } from '../../../../tests/mockData';
|
|
21
|
+
import { actions as appActions } from '../appSlice';
|
|
22
|
+
import { locations } from '../appSlice/constants';
|
|
23
|
+
import { getSessionInfo } from '../auth';
|
|
24
|
+
import { TIMEOUTS } from '../commonConstants';
|
|
25
|
+
import { SSO_TYPES } from './constants';
|
|
26
|
+
import {
|
|
27
|
+
cancelRequest,
|
|
28
|
+
cancelUpgrade,
|
|
29
|
+
changeIntegration,
|
|
30
|
+
changeSsoConfig,
|
|
31
|
+
completeUpgrade,
|
|
32
|
+
confirmCardUpdate,
|
|
33
|
+
createIntegration,
|
|
34
|
+
createOrganizationTrial,
|
|
35
|
+
deleteIntegration,
|
|
36
|
+
deleteSsoConfig,
|
|
37
|
+
downloadLicenseReport,
|
|
38
|
+
getAuditLogs,
|
|
39
|
+
getAuditLogsCsvLink,
|
|
40
|
+
getCurrentCard,
|
|
41
|
+
getIntegrations,
|
|
42
|
+
getSsoConfigById,
|
|
43
|
+
getSsoConfigs,
|
|
44
|
+
getTargetLocation,
|
|
45
|
+
getUserOrganization,
|
|
46
|
+
getWebhookEvents,
|
|
47
|
+
requestPlanChange,
|
|
48
|
+
sendSupportMessage,
|
|
49
|
+
setAuditlogsState,
|
|
50
|
+
startCardUpdate,
|
|
51
|
+
startUpgrade,
|
|
52
|
+
storeSsoConfig,
|
|
53
|
+
tenantDataDivergedMessage
|
|
54
|
+
} from './thunks';
|
|
55
|
+
|
|
56
|
+
const middlewares = [thunk];
|
|
57
|
+
const mockStore = configureMockStore(middlewares);
|
|
58
|
+
|
|
59
|
+
const expectedDeviceProviders = [
|
|
60
|
+
{ id: 1, provider: EXTERNAL_PROVIDER['iot-hub'].provider, something: 'something', connection_string: 'something_else' },
|
|
61
|
+
{ id: 2, provider: EXTERNAL_PROVIDER['iot-core'].provider, something: 'new' }
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const expectedSsoConfigs = [
|
|
65
|
+
{ id: '1', issuer: 'https://samltest.id/saml/idp', valid_until: '2038-08-24T21:14:09Z' },
|
|
66
|
+
{ id: '2', issuer: 'https://samltest2.id/saml/idp', valid_until: '2030-10-24T21:14:09Z' }
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const oldHostname = window.location.hostname;
|
|
70
|
+
|
|
71
|
+
/* eslint-disable sonarjs/no-identical-functions */
|
|
72
|
+
describe('organization actions', () => {
|
|
73
|
+
it('should handle different error message formats', async () => {
|
|
74
|
+
const store = mockStore({ ...defaultState });
|
|
75
|
+
const expectedActions = [
|
|
76
|
+
{ type: cancelRequest.pending.type },
|
|
77
|
+
{ type: appActions.setSnackbar.type, payload: { message: 'Deactivation request was sent successfully', autoHideDuration: TIMEOUTS.fiveSeconds } },
|
|
78
|
+
{ type: cancelRequest.fulfilled.type }
|
|
79
|
+
];
|
|
80
|
+
await store.dispatch(cancelRequest(defaultState.organization.organization.id, 'testReason')).then(() => {
|
|
81
|
+
const storeActions = store.getActions();
|
|
82
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
83
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should point to proper target locations from different circumstances', () => {
|
|
88
|
+
const expectations = [
|
|
89
|
+
{ hostname: locations.us.location, location: locations.us.key, result: locations.us.location },
|
|
90
|
+
{ hostname: locations.us.location, location: locations.eu.key, result: locations.eu.location },
|
|
91
|
+
{ hostname: locations.eu.location, location: locations.us.key, result: locations.us.location },
|
|
92
|
+
{ hostname: locations.eu.location, location: locations.eu.key, result: locations.eu.location },
|
|
93
|
+
{ hostname: `staging.${locations.us.location}`, location: locations.us.key, result: `staging.${locations.us.location}` },
|
|
94
|
+
{ hostname: `staging.${locations.us.location}`, location: locations.eu.key, result: `staging.${locations.eu.location}` },
|
|
95
|
+
{ hostname: `testing.staging.${locations.us.location}`, location: locations.us.key, result: `testing.staging.${locations.us.location}` },
|
|
96
|
+
{ hostname: `testing.staging.${locations.us.location}`, location: locations.eu.key, result: `testing.staging.${locations.eu.location}` },
|
|
97
|
+
{ hostname: 'docker.mender.io', location: locations.us.key, result: '' },
|
|
98
|
+
{ hostname: 'docker.mender.io', location: locations.eu.key, result: '' },
|
|
99
|
+
{ hostname: 'localhost', location: locations.us.key, result: '' },
|
|
100
|
+
{ hostname: 'localhost', location: locations.eu.key, result: '' }
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
expectations.map(({ hostname, location, result }) => {
|
|
104
|
+
window.location = { ...window.location, hostname };
|
|
105
|
+
let targetLocation = getTargetLocation(location);
|
|
106
|
+
expect(targetLocation).toBe(result ? `https://${result}` : result);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
window.location = { ...window.location, hostname: oldHostname };
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should handle trial creation', async () => {
|
|
113
|
+
const store = mockStore({ ...defaultState });
|
|
114
|
+
expect(store.getActions()).toHaveLength(0);
|
|
115
|
+
const expectedActions = [{ type: appActions.setFirstLoginAfterSignup.type, payload: true }];
|
|
116
|
+
const result = store.dispatch(
|
|
117
|
+
createOrganizationTrial({
|
|
118
|
+
'g-recaptcha-response': 'test',
|
|
119
|
+
email: 'test@test.com',
|
|
120
|
+
location: 'us',
|
|
121
|
+
marketing: true,
|
|
122
|
+
organization: 'test',
|
|
123
|
+
plan: 'os',
|
|
124
|
+
tos: true
|
|
125
|
+
})
|
|
126
|
+
);
|
|
127
|
+
jest.advanceTimersByTime(6000);
|
|
128
|
+
result.then(token => {
|
|
129
|
+
expect(token).toBeTruthy();
|
|
130
|
+
expect(store.getActions()).toHaveLength(expectedActions.length);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should handle credit card details retrieval', async () => {
|
|
135
|
+
const store = mockStore({ ...defaultState });
|
|
136
|
+
expect(store.getActions()).toHaveLength(0);
|
|
137
|
+
const expectedActions = [
|
|
138
|
+
{ type: getCurrentCard.pending.type },
|
|
139
|
+
{ type: actions.receiveCurrentCard.type, payload: defaultState.organization.card },
|
|
140
|
+
{ type: getCurrentCard.fulfilled.type }
|
|
141
|
+
];
|
|
142
|
+
await store.dispatch(getCurrentCard()).then(() => {
|
|
143
|
+
const storeActions = store.getActions();
|
|
144
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
145
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should handle organization retrieval', async () => {
|
|
150
|
+
const store = mockStore({ ...defaultState, users: { ...defaultState.users, currentSession: getSessionInfo() } });
|
|
151
|
+
expect(store.getActions()).toHaveLength(0);
|
|
152
|
+
const expectedActions = [
|
|
153
|
+
{ type: getUserOrganization.pending.type },
|
|
154
|
+
{ type: actions.setOrganization.type, payload: defaultState.organization.organization },
|
|
155
|
+
{ type: appActions.setAnnouncement.type, payload: tenantDataDivergedMessage },
|
|
156
|
+
{ type: getUserOrganization.fulfilled.type }
|
|
157
|
+
];
|
|
158
|
+
await store.dispatch(getUserOrganization()).then(() => {
|
|
159
|
+
const storeActions = store.getActions();
|
|
160
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
161
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should handle support request sending', async () => {
|
|
166
|
+
const store = mockStore({ ...defaultState });
|
|
167
|
+
expect(store.getActions()).toHaveLength(0);
|
|
168
|
+
const expectedActions = [
|
|
169
|
+
{ type: sendSupportMessage.pending.type },
|
|
170
|
+
{ type: appActions.setSnackbar.type, payload: { message: 'Your request was sent successfully', autoHideDuration: TIMEOUTS.fiveSeconds } },
|
|
171
|
+
{ type: sendSupportMessage.fulfilled.type }
|
|
172
|
+
];
|
|
173
|
+
await store.dispatch(sendSupportMessage({ body: 'test', subject: 'testsubject' })).then(() => {
|
|
174
|
+
const storeActions = store.getActions();
|
|
175
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
176
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should handle schema based support request sending', async () => {
|
|
181
|
+
const store = mockStore({ ...defaultState });
|
|
182
|
+
expect(store.getActions()).toHaveLength(0);
|
|
183
|
+
const expectedActions = [
|
|
184
|
+
{ type: requestPlanChange.pending.type },
|
|
185
|
+
{ type: appActions.setSnackbar.type, payload: { message: 'Your request was sent successfully', autoHideDuration: TIMEOUTS.fiveSeconds } },
|
|
186
|
+
{ type: requestPlanChange.fulfilled.type }
|
|
187
|
+
];
|
|
188
|
+
await store
|
|
189
|
+
.dispatch(
|
|
190
|
+
requestPlanChange({
|
|
191
|
+
tenantId: defaultState.organization.organization.id,
|
|
192
|
+
content: {
|
|
193
|
+
current_plan: 'Basic',
|
|
194
|
+
requested_plan: 'Enterprise',
|
|
195
|
+
current_addons: 'something,extra',
|
|
196
|
+
requested_addons: 'something,extra,special',
|
|
197
|
+
user_message: 'more please'
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
)
|
|
201
|
+
.then(() => {
|
|
202
|
+
const storeActions = store.getActions();
|
|
203
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
204
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should handle license report downloads', async () => {
|
|
209
|
+
const store = mockStore({ ...defaultState });
|
|
210
|
+
expect(store.getActions()).toHaveLength(0);
|
|
211
|
+
const expectedActions = [{ type: downloadLicenseReport.pending.type }, { type: downloadLicenseReport.fulfilled.type }];
|
|
212
|
+
const result = await store.dispatch(downloadLicenseReport()).unwrap();
|
|
213
|
+
const storeActions = store.getActions();
|
|
214
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
215
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
216
|
+
expect(result).toEqual('test,report');
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it('should handle account upgrade init', async () => {
|
|
220
|
+
const store = mockStore({ ...defaultState });
|
|
221
|
+
const expectedActions = [{ type: startUpgrade.pending.type }, { type: startUpgrade.fulfilled.type }];
|
|
222
|
+
const secret = await store.dispatch(startUpgrade(defaultState.organization.organization.id)).unwrap();
|
|
223
|
+
const storeActions = store.getActions();
|
|
224
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
225
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
226
|
+
expect(secret).toEqual('testSecret');
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should handle account upgrade cancelling', async () => {
|
|
230
|
+
const store = mockStore({ ...defaultState });
|
|
231
|
+
const expectedActions = [{ type: cancelUpgrade.pending.type }, { type: cancelUpgrade.fulfilled.type }];
|
|
232
|
+
await store.dispatch(cancelUpgrade(defaultState.organization.organization.id));
|
|
233
|
+
const storeActions = store.getActions();
|
|
234
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
235
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it('should handle account upgrade completion', async () => {
|
|
239
|
+
const store = mockStore({ ...defaultState, users: { ...defaultState.users, currentSession: getSessionInfo() } });
|
|
240
|
+
expect(store.getActions()).toHaveLength(0);
|
|
241
|
+
const expectedActions = [
|
|
242
|
+
{ type: completeUpgrade.pending.type },
|
|
243
|
+
{ type: getUserOrganization.pending.type },
|
|
244
|
+
{ type: actions.setOrganization.type, payload: defaultState.organization.organization },
|
|
245
|
+
{ type: appActions.setAnnouncement.type, payload: tenantDataDivergedMessage },
|
|
246
|
+
{ type: getUserOrganization.fulfilled.type },
|
|
247
|
+
{ type: completeUpgrade.fulfilled.type }
|
|
248
|
+
];
|
|
249
|
+
await store.dispatch(completeUpgrade({ tenantId: defaultState.organization.organization.id, plan: 'enterprise' }));
|
|
250
|
+
const storeActions = store.getActions();
|
|
251
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
252
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('should handle confirm card update initialization', async () => {
|
|
256
|
+
const store = mockStore({ ...defaultState });
|
|
257
|
+
expect(store.getActions()).toHaveLength(0);
|
|
258
|
+
const expectedActions = [
|
|
259
|
+
{ type: startCardUpdate.pending.type },
|
|
260
|
+
{ type: actions.receiveSetupIntent.type, payload: 'testIntent' },
|
|
261
|
+
{ type: startCardUpdate.fulfilled.type }
|
|
262
|
+
];
|
|
263
|
+
const secret = await store.dispatch(startCardUpdate()).unwrap();
|
|
264
|
+
const storeActions = store.getActions();
|
|
265
|
+
expect(secret).toEqual('testSecret');
|
|
266
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
267
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('should handle confirm card update confirmation', async () => {
|
|
271
|
+
const store = mockStore({ ...defaultState });
|
|
272
|
+
expect(store.getActions()).toHaveLength(0);
|
|
273
|
+
const expectedActions = [
|
|
274
|
+
{ type: confirmCardUpdate.pending.type },
|
|
275
|
+
{ type: appActions.setSnackbar.type, payload: 'Payment card was updated successfully' },
|
|
276
|
+
{ type: actions.receiveSetupIntent.type, payload: null },
|
|
277
|
+
{ type: confirmCardUpdate.fulfilled.type }
|
|
278
|
+
];
|
|
279
|
+
const request = store.dispatch(confirmCardUpdate());
|
|
280
|
+
expect(request).resolves.toBeTruthy();
|
|
281
|
+
await request.then(() => {
|
|
282
|
+
const storeActions = store.getActions();
|
|
283
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
284
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('should handle auditlog retrieval', async () => {
|
|
289
|
+
const store = mockStore({
|
|
290
|
+
...defaultState,
|
|
291
|
+
app: {
|
|
292
|
+
...defaultState.app,
|
|
293
|
+
features: {
|
|
294
|
+
...defaultState.app.features,
|
|
295
|
+
hasAuditlogs: true,
|
|
296
|
+
isEnterprise: true
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
expect(store.getActions()).toHaveLength(0);
|
|
301
|
+
const expectedActions = [
|
|
302
|
+
{ type: getAuditLogs.pending.type },
|
|
303
|
+
{
|
|
304
|
+
type: actions.receiveAuditLogs.type,
|
|
305
|
+
payload: { events: defaultState.organization.auditlog.events, total: defaultState.organization.auditlog.selectionState.total }
|
|
306
|
+
},
|
|
307
|
+
{ type: getAuditLogs.fulfilled.type }
|
|
308
|
+
];
|
|
309
|
+
const request = store.dispatch(getAuditLogs({ page: 1, perPage: 20 }));
|
|
310
|
+
expect(request).resolves.toBeTruthy();
|
|
311
|
+
await request.then(() => {
|
|
312
|
+
const storeActions = store.getActions();
|
|
313
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
314
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
it('should allow auditlog state tracking', async () => {
|
|
318
|
+
const store = mockStore({ ...defaultState });
|
|
319
|
+
await store.dispatch(setAuditlogsState({ page: 1, sort: { direction: 'something' } }));
|
|
320
|
+
const expectedActions = [
|
|
321
|
+
{ type: setAuditlogsState.pending.type },
|
|
322
|
+
{ type: getAuditLogs.pending.type },
|
|
323
|
+
{
|
|
324
|
+
type: actions.setAuditLogState.type,
|
|
325
|
+
payload: { ...defaultState.organization.auditlog.selectionState, isLoading: true, sort: { direction: 'something' } }
|
|
326
|
+
},
|
|
327
|
+
{ type: getAuditLogs.fulfilled.type },
|
|
328
|
+
{ type: actions.setAuditLogState.type, payload: { isLoading: false } },
|
|
329
|
+
{ type: setAuditlogsState.fulfilled.type }
|
|
330
|
+
];
|
|
331
|
+
const storeActions = store.getActions();
|
|
332
|
+
expect(storeActions.length).toEqual(expectedActions.length);
|
|
333
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
334
|
+
});
|
|
335
|
+
it('should handle csv information download', async () => {
|
|
336
|
+
const store = mockStore({ ...defaultState });
|
|
337
|
+
expect(store.getActions()).toHaveLength(0);
|
|
338
|
+
const expectedActions = [{ type: getAuditLogsCsvLink.pending.type }, { type: getAuditLogsCsvLink.fulfilled.type }];
|
|
339
|
+
const request = store.dispatch(getAuditLogsCsvLink()).unwrap();
|
|
340
|
+
expect(request).resolves.toBeTruthy();
|
|
341
|
+
await request.then(link => {
|
|
342
|
+
const storeActions = store.getActions();
|
|
343
|
+
expect(storeActions.length).toEqual(expectedActions.length);
|
|
344
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
345
|
+
expect(link).toEqual('http://localhost/api/management/v1/auditlogs/logs/export?limit=20000&sort=desc');
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
it('should allow initializing external device providers', async () => {
|
|
349
|
+
const store = mockStore({
|
|
350
|
+
...defaultState,
|
|
351
|
+
organization: {
|
|
352
|
+
...defaultState.organization,
|
|
353
|
+
externalDeviceIntegrations: [
|
|
354
|
+
{ id: 1, something: 'something' },
|
|
355
|
+
{ id: 2, provider: 'aws', something: 'new' }
|
|
356
|
+
]
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
expect(store.getActions()).toHaveLength(0);
|
|
360
|
+
const expectedActions = [
|
|
361
|
+
{ type: createIntegration.pending.type },
|
|
362
|
+
{ type: appActions.setSnackbar.type, payload: 'The integration was set up successfully' },
|
|
363
|
+
{ type: getIntegrations.pending.type },
|
|
364
|
+
{ type: actions.receiveExternalDeviceIntegrations.type, payload: expectedDeviceProviders },
|
|
365
|
+
{ type: getIntegrations.fulfilled.type },
|
|
366
|
+
{ type: createIntegration.fulfilled.type }
|
|
367
|
+
];
|
|
368
|
+
const request = store.dispatch(createIntegration({ connection_string: 'testString', provider: 'iot-hub' }));
|
|
369
|
+
expect(request).resolves.toBeTruthy();
|
|
370
|
+
await request.then(() => {
|
|
371
|
+
const storeActions = store.getActions();
|
|
372
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
373
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
it('should allow configuring external device providers', async () => {
|
|
377
|
+
const store = mockStore({
|
|
378
|
+
...defaultState,
|
|
379
|
+
organization: {
|
|
380
|
+
...defaultState.organization,
|
|
381
|
+
externalDeviceIntegrations: [
|
|
382
|
+
{ id: 1, something: 'something' },
|
|
383
|
+
{ id: 2, provider: 'iot-core', something: 'new' }
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
expect(store.getActions()).toHaveLength(0);
|
|
388
|
+
const expectedActions = [
|
|
389
|
+
{ type: changeIntegration.pending.type },
|
|
390
|
+
{ type: appActions.setSnackbar.type, payload: 'The integration was updated successfully' },
|
|
391
|
+
{ type: getIntegrations.pending.type },
|
|
392
|
+
{ type: actions.receiveExternalDeviceIntegrations.type, payload: expectedDeviceProviders },
|
|
393
|
+
{ type: getIntegrations.fulfilled.type },
|
|
394
|
+
{ type: changeIntegration.fulfilled.type }
|
|
395
|
+
];
|
|
396
|
+
const request = store.dispatch(changeIntegration({ connection_string: 'testString2', id: 1, provider: 'iot-hub' }));
|
|
397
|
+
expect(request).resolves.toBeTruthy();
|
|
398
|
+
await request.then(() => {
|
|
399
|
+
const storeActions = store.getActions();
|
|
400
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
401
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
it('should allow retrieving external device providers', async () => {
|
|
405
|
+
const store = mockStore({
|
|
406
|
+
...defaultState,
|
|
407
|
+
organization: {
|
|
408
|
+
...defaultState.organization,
|
|
409
|
+
externalDeviceIntegrations: [
|
|
410
|
+
{ id: 1, something: 'something' },
|
|
411
|
+
{ id: 2, provider: 'iot-core', something: 'new' }
|
|
412
|
+
]
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
expect(store.getActions()).toHaveLength(0);
|
|
416
|
+
const expectedActions = [
|
|
417
|
+
{ type: getIntegrations.pending.type },
|
|
418
|
+
{ type: actions.receiveExternalDeviceIntegrations.type, payload: expectedDeviceProviders },
|
|
419
|
+
{ type: getIntegrations.fulfilled.type }
|
|
420
|
+
];
|
|
421
|
+
const request = store.dispatch(getIntegrations());
|
|
422
|
+
expect(request).resolves.toBeTruthy();
|
|
423
|
+
await request.then(() => {
|
|
424
|
+
const storeActions = store.getActions();
|
|
425
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
426
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
it('should allow deleting external device provider configurations', async () => {
|
|
430
|
+
const store = mockStore({ ...defaultState, externalDeviceIntegrations: [{ id: 1, something: 'something' }] });
|
|
431
|
+
expect(store.getActions()).toHaveLength(0);
|
|
432
|
+
const expectedActions = [
|
|
433
|
+
{ type: deleteIntegration.pending.type },
|
|
434
|
+
{ type: appActions.setSnackbar.type, payload: 'The integration was removed successfully' },
|
|
435
|
+
{ type: actions.receiveExternalDeviceIntegrations.type, payload: [] },
|
|
436
|
+
{ type: deleteIntegration.fulfilled.type }
|
|
437
|
+
];
|
|
438
|
+
const request = store.dispatch(deleteIntegration({ id: 1 }));
|
|
439
|
+
expect(request).resolves.toBeTruthy();
|
|
440
|
+
await request.then(() => {
|
|
441
|
+
const storeActions = store.getActions();
|
|
442
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
443
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
it('should allow retrieving webhook events', async () => {
|
|
447
|
+
const store = mockStore({
|
|
448
|
+
...defaultState,
|
|
449
|
+
organization: {
|
|
450
|
+
...defaultState.organization,
|
|
451
|
+
webhooks: {
|
|
452
|
+
...defaultState.organization.webhooks,
|
|
453
|
+
events: [
|
|
454
|
+
{ id: 1, something: 'something' },
|
|
455
|
+
{ id: 2, provider: 'aws', something: 'new' }
|
|
456
|
+
]
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
expect(store.getActions()).toHaveLength(0);
|
|
461
|
+
const expectedActions = [
|
|
462
|
+
{ type: getWebhookEvents.pending.type },
|
|
463
|
+
{ type: actions.receiveWebhookEvents.type, payload: { value: webhookEvents, total: 2 } },
|
|
464
|
+
{ type: getWebhookEvents.fulfilled.type }
|
|
465
|
+
];
|
|
466
|
+
const request = store.dispatch(getWebhookEvents());
|
|
467
|
+
expect(request).resolves.toBeTruthy();
|
|
468
|
+
await request.then(() => {
|
|
469
|
+
const storeActions = store.getActions();
|
|
470
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
471
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
it('should auto check for more webhook events', async () => {
|
|
475
|
+
const existingEvents = [
|
|
476
|
+
{ id: 1, something: 'something' },
|
|
477
|
+
{ id: 2, provider: 'aws', something: 'new' }
|
|
478
|
+
];
|
|
479
|
+
const store = mockStore({
|
|
480
|
+
...defaultState,
|
|
481
|
+
organization: {
|
|
482
|
+
...defaultState.organization,
|
|
483
|
+
webhooks: {
|
|
484
|
+
...defaultState.organization.webhooks,
|
|
485
|
+
events: existingEvents,
|
|
486
|
+
eventTotal: 2
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
expect(store.getActions()).toHaveLength(0);
|
|
491
|
+
const defaultEvent = webhookEvents[0];
|
|
492
|
+
const expectedActions = [
|
|
493
|
+
{ type: getWebhookEvents.pending.type },
|
|
494
|
+
{ type: actions.receiveWebhookEvents.type, payload: { value: [defaultEvent], total: 1 } },
|
|
495
|
+
{ type: getWebhookEvents.pending.type },
|
|
496
|
+
{ type: actions.receiveWebhookEvents.type, payload: { value: existingEvents, total: 2 } },
|
|
497
|
+
{ type: getWebhookEvents.fulfilled.type },
|
|
498
|
+
{ type: getWebhookEvents.fulfilled.type }
|
|
499
|
+
];
|
|
500
|
+
const request = store.dispatch(getWebhookEvents({ page: 1, perPage: 1 }));
|
|
501
|
+
expect(request).resolves.toBeTruthy();
|
|
502
|
+
await request.then(() => {
|
|
503
|
+
const storeActions = store.getActions();
|
|
504
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
505
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
it('should allow configuring external identity providers', async () => {
|
|
509
|
+
const store = mockStore({
|
|
510
|
+
...defaultState,
|
|
511
|
+
organization: {
|
|
512
|
+
...defaultState.organization,
|
|
513
|
+
ssoConfigs: [{ id: 1, something: 'something' }]
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
expect(store.getActions()).toHaveLength(0);
|
|
517
|
+
const expectedActions = [
|
|
518
|
+
{ type: storeSsoConfig.pending.type },
|
|
519
|
+
{ type: appActions.setSnackbar.type, payload: 'The SSO configuration was stored successfully' },
|
|
520
|
+
{ type: getSsoConfigs.pending.type },
|
|
521
|
+
{ type: getSsoConfigById.pending.type },
|
|
522
|
+
{ type: getSsoConfigById.pending.type },
|
|
523
|
+
{ type: getSsoConfigById.fulfilled.type },
|
|
524
|
+
{ type: getSsoConfigById.fulfilled.type },
|
|
525
|
+
{ type: actions.receiveSsoConfigs.type },
|
|
526
|
+
{ type: getSsoConfigs.fulfilled.type },
|
|
527
|
+
{ type: storeSsoConfig.fulfilled.type }
|
|
528
|
+
];
|
|
529
|
+
const request = store.dispatch(
|
|
530
|
+
storeSsoConfig({ config: { connection_string: 'testString', provider: 'iot-hub' }, contentType: SSO_TYPES.oidc.contentType })
|
|
531
|
+
);
|
|
532
|
+
expect(request).resolves.toBeTruthy();
|
|
533
|
+
await request.then(() => {
|
|
534
|
+
const storeActions = store.getActions();
|
|
535
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
536
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
it('should allow updating external identity providers', async () => {
|
|
540
|
+
const store = mockStore({
|
|
541
|
+
...defaultState,
|
|
542
|
+
organization: {
|
|
543
|
+
...defaultState.organization,
|
|
544
|
+
ssoConfigs: [
|
|
545
|
+
{ id: 1, something: 'something' },
|
|
546
|
+
{ id: 2, provider: 'aws', something: 'new' }
|
|
547
|
+
]
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
expect(store.getActions()).toHaveLength(0);
|
|
551
|
+
const expectedActions = [
|
|
552
|
+
{ type: changeSsoConfig.pending.type },
|
|
553
|
+
{ type: appActions.setSnackbar.type, payload: 'The SSO configuration was updated successfully' },
|
|
554
|
+
{ type: getSsoConfigs.pending.type },
|
|
555
|
+
{ type: getSsoConfigById.pending.type },
|
|
556
|
+
{ type: getSsoConfigById.pending.type },
|
|
557
|
+
{ type: getSsoConfigById.fulfilled.type },
|
|
558
|
+
{ type: getSsoConfigById.fulfilled.type },
|
|
559
|
+
{ type: actions.receiveSsoConfigs.type },
|
|
560
|
+
{ type: getSsoConfigs.fulfilled.type },
|
|
561
|
+
{ type: changeSsoConfig.fulfilled.type }
|
|
562
|
+
];
|
|
563
|
+
const request = store.dispatch(
|
|
564
|
+
changeSsoConfig({ config: { connection_string: 'testString2', id: 1, provider: 'iot-hub' }, contentType: SSO_TYPES.oidc.contentType })
|
|
565
|
+
);
|
|
566
|
+
expect(request).resolves.toBeTruthy();
|
|
567
|
+
await request.then(() => {
|
|
568
|
+
const storeActions = store.getActions();
|
|
569
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
570
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
it('should allow retrieving external identity providers', async () => {
|
|
574
|
+
const store = mockStore({
|
|
575
|
+
...defaultState,
|
|
576
|
+
organization: {
|
|
577
|
+
...defaultState.organization,
|
|
578
|
+
ssoConfigs: [
|
|
579
|
+
{ id: 1, something: 'something' },
|
|
580
|
+
{ id: 2, provider: 'aws', something: 'new' }
|
|
581
|
+
]
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
expect(store.getActions()).toHaveLength(0);
|
|
585
|
+
const expectedActions = [
|
|
586
|
+
{ type: getSsoConfigs.pending.type },
|
|
587
|
+
{ type: getSsoConfigById.pending.type },
|
|
588
|
+
{ type: getSsoConfigById.pending.type },
|
|
589
|
+
{ type: getSsoConfigById.fulfilled.type },
|
|
590
|
+
{ type: getSsoConfigById.fulfilled.type },
|
|
591
|
+
{ type: actions.receiveSsoConfigs.type, payload: expectedSsoConfigs },
|
|
592
|
+
{ type: getSsoConfigs.fulfilled.type }
|
|
593
|
+
];
|
|
594
|
+
const request = store.dispatch(getSsoConfigs());
|
|
595
|
+
expect(request).resolves.toBeTruthy();
|
|
596
|
+
await request.then(() => {
|
|
597
|
+
const storeActions = store.getActions();
|
|
598
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
599
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
it('should allow deleting external identity providers', async () => {
|
|
603
|
+
const store = mockStore({ ...defaultState, organization: { ...defaultState.organization, ssoConfigs: [...expectedSsoConfigs] } });
|
|
604
|
+
expect(store.getActions()).toHaveLength(0);
|
|
605
|
+
const expectedActions = [
|
|
606
|
+
{ type: deleteSsoConfig.pending.type },
|
|
607
|
+
{ type: appActions.setSnackbar.type, payload: 'The SSO configuration was removed successfully' },
|
|
608
|
+
{ type: actions.receiveSsoConfigs.type, payload: [expectedSsoConfigs[1]] },
|
|
609
|
+
{ type: deleteSsoConfig.fulfilled.type }
|
|
610
|
+
];
|
|
611
|
+
const request = store.dispatch(deleteSsoConfig({ id: '1' }));
|
|
612
|
+
expect(request).resolves.toBeTruthy();
|
|
613
|
+
await request.then(() => {
|
|
614
|
+
const storeActions = store.getActions();
|
|
615
|
+
expect(storeActions).toHaveLength(expectedActions.length);
|
|
616
|
+
expectedActions.map((action, index) => expect(storeActions[index]).toMatchObject(action));
|
|
617
|
+
});
|
|
618
|
+
});
|
|
619
|
+
});
|