Skip to content

Commit 239203a

Browse files
authored
fix: testBackends method (#1413)
* fix: testBackends method Signed-off-by: Oleksii Orel <oorel@redhat.com>
1 parent afbaaa2 commit 239203a

File tree

10 files changed

+231
-13
lines changed

10 files changed

+231
-13
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"start": "$PWD/run/local-run.sh $@",
2626
"start:prepare": "$PWD/run/prepare-local-run.sh",
2727
"start:cleanup": "$PWD/run/revert-local-run.sh",
28-
"license:check": "$PWD/scripts/container_tool.sh run --rm -t -v $PWD/:/workspace/project quay.io/che-incubator/dash-licenses:next --check",
28+
"license:check": "$PWD/scripts/container_tool.sh run --rm -t -v $PWD/:/workspace/project quay.io/che-incubator/dash-licenses:next --check --batch 200",
2929
"license:generate": "$PWD/scripts/container_tool.sh run --rm -t -v $PWD/:/workspace/project quay.io/che-incubator/dash-licenses:next",
3030
"test": "yarn run pretest && yarn workspaces foreach -A run test --no-cache",
3131
"test:check": "yarn run pretest && yarn workspace @eclipse-che/dashboard-frontend test --config=jest.config.check.js",

packages/dashboard-frontend/src/__tests__/const.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const REQUEST_TIME_700 = 700;
2222
export const REQUEST_TIME_800 = 800;
2323
export const REQUEST_TIME_1300 = 1300;
2424

25-
export const TIME_LIMIT = 9000;
25+
export const TIME_LIMIT = 9800;
2626

2727
export const namespace = { name: 'user-che', attributes: { phase: 'Active' } };
2828
export const url = 'https://github.com/eclipse-che/che-dashboard';

packages/dashboard-frontend/src/services/bootstrap/__tests__/index.spec.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212

1313
import { container } from '@/inversify.config';
14+
import { provisionKubernetesNamespace } from '@/services/backend-client/kubernetesNamespaceApi';
1415
import { WebsocketClient } from '@/services/backend-client/websocketClient';
1516
import Bootstrap from '@/services/bootstrap';
1617
import { ResourceFetcherService } from '@/services/resource-fetcher';
@@ -25,7 +26,6 @@ import { infrastructureNamespacesActionCreators } from '@/store/InfrastructureNa
2526
import { chePluginsActionCreators } from '@/store/Plugins/chePlugins';
2627
import { devWorkspacePluginsActionCreators } from '@/store/Plugins/devWorkspacePlugins';
2728
import { podsActionCreators } from '@/store/Pods';
28-
import { sanityCheckActionCreators } from '@/store/SanityCheck';
2929
import { serverConfigActionCreators } from '@/store/ServerConfig';
3030
import { sshKeysActionCreators } from '@/store/SshKeys';
3131
import { userProfileActionCreators } from '@/store/User/Profile';
@@ -38,7 +38,15 @@ jest.spyOn(ResourceFetcherService.prototype, 'prefetchResources').mockImplementa
3838
});
3939

4040
jest.spyOn(serverConfigActionCreators, 'requestServerConfig').mockImplementation(() => jest.fn());
41-
jest.spyOn(sanityCheckActionCreators, 'testBackends').mockImplementation(() => jest.fn());
41+
jest.mock('@/services/backend-client/kubernetesNamespaceApi', () => {
42+
const originalModule = jest.requireActual(
43+
'@/services/backend-client/kubernetesNamespaceApi',
44+
) as Record<string, unknown>;
45+
return {
46+
...originalModule,
47+
provisionKubernetesNamespace: jest.fn(),
48+
};
49+
});
4250
jest.spyOn(brandingActionCreators, 'requestBranding').mockImplementation(() => jest.fn());
4351
jest.mock('@/store/InfrastructureNamespaces', () => ({
4452
...jest.requireActual('@/store/InfrastructureNamespaces'),
@@ -120,7 +128,7 @@ describe('Dashboard bootstrap', () => {
120128
// await bootstrap.init();
121129

122130
expect(serverConfigActionCreators.requestServerConfig).toHaveBeenCalledTimes(1);
123-
expect(sanityCheckActionCreators.testBackends).toHaveBeenCalledTimes(1);
131+
expect(provisionKubernetesNamespace).toHaveBeenCalledTimes(1);
124132

125133
expect(mockPrefetchResources).toHaveBeenCalledTimes(1);
126134

packages/dashboard-frontend/src/services/bootstrap/__tests__/namespaceProvisionWarnings.spec.tsx

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,167 @@ describe('Check namespace provision warnings', () => {
6565
},
6666
]);
6767
});
68+
it('should register the advanced authorization warning for allowGroups', () => {
69+
const store = new MockStoreBuilder()
70+
.withDwServerConfig({
71+
networking: {
72+
auth: {
73+
advancedAuthorization: {
74+
allowGroups: ['test-group'],
75+
},
76+
},
77+
},
78+
})
79+
.build();
80+
81+
checkNamespaceProvisionWarnings(store.getState);
82+
83+
expect(warningsReporterService.hasWarning).toBeTruthy();
84+
expect(warningsReporterService.reportAllWarnings()).toEqual([
85+
{
86+
key: 'advancedAuthorizationGroupsWarning',
87+
title:
88+
'Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.',
89+
},
90+
]);
91+
});
92+
93+
it('should register the advanced authorization warning for denyGroups', () => {
94+
const store = new MockStoreBuilder()
95+
.withDwServerConfig({
96+
networking: {
97+
auth: {
98+
advancedAuthorization: {
99+
denyGroups: ['test-group'],
100+
},
101+
},
102+
},
103+
})
104+
.build();
105+
106+
checkNamespaceProvisionWarnings(store.getState);
107+
108+
expect(warningsReporterService.hasWarning).toBeTruthy();
109+
expect(warningsReporterService.reportAllWarnings()).toEqual([
110+
{
111+
key: 'advancedAuthorizationGroupsWarning',
112+
title:
113+
'Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.',
114+
},
115+
]);
116+
});
117+
118+
it('should register the advanced authorization warning for allowGroups', () => {
119+
const store = new MockStoreBuilder()
120+
.withDwServerConfig({
121+
networking: {
122+
auth: {
123+
advancedAuthorization: {
124+
allowGroups: ['test-group'],
125+
},
126+
},
127+
},
128+
})
129+
.build();
130+
131+
checkNamespaceProvisionWarnings(store.getState);
132+
133+
expect(warningsReporterService.hasWarning).toBeTruthy();
134+
expect(warningsReporterService.reportAllWarnings()).toEqual([
135+
{
136+
key: 'advancedAuthorizationGroupsWarning',
137+
title:
138+
'Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.',
139+
},
140+
]);
141+
});
142+
143+
it('should register the advanced authorization warning for allowUsers', () => {
144+
const store = new MockStoreBuilder()
145+
.withDwServerConfig({
146+
networking: {
147+
auth: {
148+
advancedAuthorization: {
149+
allowUsers: ['user0'],
150+
},
151+
},
152+
},
153+
})
154+
.build();
155+
156+
checkNamespaceProvisionWarnings(store.getState);
157+
158+
expect(warningsReporterService.hasWarning).toBeTruthy();
159+
expect(warningsReporterService.reportAllWarnings()).toEqual([
160+
{
161+
key: 'advancedAuthorizationUsersWarning',
162+
title:
163+
'Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.',
164+
},
165+
]);
166+
});
167+
168+
it('should register the advanced authorization warning for denyUsers', () => {
169+
const store = new MockStoreBuilder()
170+
.withDwServerConfig({
171+
networking: {
172+
auth: {
173+
advancedAuthorization: {
174+
denyUsers: ['test-user'],
175+
},
176+
},
177+
},
178+
})
179+
.build();
180+
181+
checkNamespaceProvisionWarnings(store.getState);
182+
183+
expect(warningsReporterService.hasWarning).toBeTruthy();
184+
expect(warningsReporterService.reportAllWarnings()).toEqual([
185+
{
186+
key: 'advancedAuthorizationUsersWarning',
187+
title:
188+
'Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.',
189+
},
190+
]);
191+
});
192+
193+
it('should register all possible warnings', () => {
194+
const store = new MockStoreBuilder()
195+
.withDwServerConfig({
196+
defaultNamespace: {
197+
autoProvision: false,
198+
},
199+
networking: {
200+
auth: {
201+
advancedAuthorization: {
202+
denyUsers: ['test-user'],
203+
denyGroups: ['test-group'],
204+
},
205+
},
206+
},
207+
})
208+
.build();
209+
210+
checkNamespaceProvisionWarnings(store.getState);
211+
212+
expect(warningsReporterService.hasWarning).toBeTruthy();
213+
expect(warningsReporterService.reportAllWarnings()).toEqual([
214+
{
215+
key: 'autoProvisionWarning',
216+
title:
217+
'Automatic namespace provisioning is disabled. Namespace might not have been configured yet. Please, contact the administrator.',
218+
},
219+
{
220+
key: 'advancedAuthorizationGroupsWarning',
221+
title:
222+
'Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.',
223+
},
224+
{
225+
key: 'advancedAuthorizationUsersWarning',
226+
title:
227+
'Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.',
228+
},
229+
]);
230+
});
68231
});

packages/dashboard-frontend/src/services/bootstrap/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import common, { api } from '@eclipse-che/common';
1414
import { Store } from 'redux';
1515

1616
import { lazyInject } from '@/inversify.config';
17+
import { provisionKubernetesNamespace } from '@/services/backend-client/kubernetesNamespaceApi';
1718
import { WebsocketClient } from '@/services/backend-client/websocketClient';
1819
import { ChannelListener } from '@/services/backend-client/websocketClient/messageHandler';
1920
import {
@@ -48,7 +49,7 @@ import {
4849
import { chePluginsActionCreators } from '@/store/Plugins/chePlugins';
4950
import { devWorkspacePluginsActionCreators } from '@/store/Plugins/devWorkspacePlugins';
5051
import { podsActionCreators, selectPodsResourceVersion } from '@/store/Pods';
51-
import { sanityCheckActionCreators } from '@/store/SanityCheck';
52+
import { backendCheckRequestAction } from '@/store/SanityCheck/actions';
5253
import { serverConfigActionCreators } from '@/store/ServerConfig';
5354
import { sshKeysActionCreators } from '@/store/SshKeys';
5455
import { userProfileActionCreators } from '@/store/User/Profile';
@@ -128,9 +129,11 @@ export default class Bootstrap {
128129
}
129130

130131
private async doBackendsSanityCheck(): Promise<void> {
131-
const { testBackends } = sanityCheckActionCreators;
132132
try {
133-
await testBackends()(this.store.dispatch, this.store.getState, undefined);
133+
await provisionKubernetesNamespace();
134+
backendCheckRequestAction({
135+
lastFetched: Date.now(),
136+
});
134137
} catch (e) {
135138
checkNamespaceProvisionWarnings(this.store.getState);
136139
const errorMessage = common.helpers.errors.getMessage(e);

packages/dashboard-frontend/src/services/bootstrap/namespaceProvisionWarnings.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import { container } from '@/inversify.config';
1414
import { WarningsReporterService } from '@/services/bootstrap/warningsReporter';
1515
import { RootState } from '@/store';
16-
import { selectAutoProvision } from '@/store/ServerConfig/selectors';
16+
import { selectAdvancedAuthorization, selectAutoProvision } from '@/store/ServerConfig/selectors';
1717

1818
const warningsReporterService = container.get(WarningsReporterService);
1919

@@ -26,4 +26,21 @@ export function checkNamespaceProvisionWarnings(getState: () => RootState): void
2626
`Automatic namespace provisioning is disabled. Namespace might not have been configured yet. Please, contact the administrator.`,
2727
);
2828
}
29+
30+
const advancedAuthorization = selectAdvancedAuthorization(state);
31+
if (advancedAuthorization === undefined || Object.keys(advancedAuthorization).length === 0) {
32+
return;
33+
}
34+
if (advancedAuthorization.allowGroups || advancedAuthorization.denyGroups) {
35+
warningsReporterService.registerWarning(
36+
'advancedAuthorizationGroupsWarning',
37+
`Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.`,
38+
);
39+
}
40+
if (advancedAuthorization.allowUsers || advancedAuthorization.denyUsers) {
41+
warningsReporterService.registerWarning(
42+
'advancedAuthorizationUsersWarning',
43+
`Advanced authorization is enabled. User might not be allowed. Please, contact the administrator.`,
44+
);
45+
}
2946
}

packages/dashboard-frontend/src/services/workspace-client/__tests__/helpers.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ describe('Workspace-client helpers', () => {
3030
expect(getErrorMessage(undefined)).toEqual('Check the browser logs message.');
3131
});
3232

33+
it('should return the the error message', () => {
34+
expect(
35+
getErrorMessage({
36+
errorCode: 0,
37+
message:
38+
'User is not authorized to create a project. Please contact your system administrator.',
39+
}),
40+
).toEqual(
41+
'User is not authorized to create a project. Please contact your system administrator.',
42+
);
43+
});
44+
3345
it('should return the unknown error message', () => {
3446
expect(getErrorMessage({})).toEqual('Unexpected error type. Please report a bug.');
3547
});

packages/dashboard-frontend/src/services/workspace-client/helpers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212

1313
import common from '@eclipse-che/common';
14+
import { isErrorLike } from '@eclipse-che/common/lib/helpers/errors';
1415
import { AxiosResponse } from 'axios';
1516
import cloneDeep from 'lodash/cloneDeep';
1617

@@ -30,7 +31,7 @@ export function getErrorMessage(error: unknown): string {
3031
const endpoint = request?.responseURL ? request?.responseURL : response?.request?.responseURL;
3132

3233
if (!code || !endpoint) {
33-
return 'Unexpected error type. Please report a bug.';
34+
return isErrorLike(error) ? error.message : 'Unexpected error type. Please report a bug.';
3435
}
3536

3637
const errorDetails = `HTTP Error code ${code}. Endpoint which throws an error ${endpoint}.`;

packages/dashboard-frontend/src/store/SanityCheck/__tests__/actions.spec.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,14 @@ describe('SanityCheck, actions', () => {
116116
jest.spyOn(helpers.errors, 'includesAxiosResponse').mockReturnValueOnce(true);
117117
console.error = jest.fn();
118118

119-
await expect(store.dispatch(actionCreators.testBackends())).rejects.toThrow(errorMessage);
119+
let err: unknown = undefined;
120+
try {
121+
await store.dispatch(actionCreators.testBackends());
122+
} catch (e) {
123+
err = e;
124+
}
125+
126+
expect(err).toEqual(errorMessage);
120127

121128
const actions = store.getActions();
122129
expect(actions).toHaveLength(2);
@@ -143,7 +150,14 @@ describe('SanityCheck, actions', () => {
143150
(helpers.errors.getMessage as jest.Mock).mockReturnValueOnce(errorMessage);
144151
console.error = jest.fn();
145152

146-
await expect(store.dispatch(actionCreators.testBackends())).rejects.toThrow(errorMessage);
153+
let err: unknown = undefined;
154+
try {
155+
await store.dispatch(actionCreators.testBackends());
156+
} catch (e) {
157+
err = e;
158+
}
159+
160+
expect(err).toEqual(errorMessage);
147161

148162
expect(signIn).toHaveBeenCalled();
149163

packages/dashboard-frontend/src/store/SanityCheck/actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export const actionCreators = {
7777
) {
7878
console.error(e.response.data.trace.join('\n'));
7979
}
80-
throw new Error(errorMessage);
80+
throw errorMessage;
8181
}
8282
},
8383
};

0 commit comments

Comments
 (0)