Skip to content
Snippets Groups Projects
Unverified Commit 53822be5 authored by Douglas Fabris's avatar Douglas Fabris Committed by GitHub
Browse files

test: Cover sidebar audit/administration items hooks (#29821)

parent 46434669
No related branches found
No related tags found
No related merge requests found
Showing with 456 additions and 15 deletions
......@@ -95,9 +95,9 @@ export const useUserDropdownAppsActionButtons = () => {
?.filter((action) => {
return applyButtonFilters(action);
})
.map((action, key) => {
.map((action) => {
return {
id: action.actionId + key,
id: `${action.appId}_${action.actionId}`,
// icon: action.icon as GenericMenuItemProps['icon'],
content: action.labelI18n,
onClick: () => {
......
import { MockedAuthorizationContext } from '@rocket.chat/mock-providers/src/MockedAuthorizationContext';
import { MockedModalContext } from '@rocket.chat/mock-providers/src/MockedModalContext';
import { MockedServerContext } from '@rocket.chat/mock-providers/src/MockedServerContext';
import { MockedSettingsContext } from '@rocket.chat/mock-providers/src/MockedSettingsContext';
import { MockedUserContext } from '@rocket.chat/mock-providers/src/MockedUserContext';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { renderHook } from '@testing-library/react-hooks';
import React from 'react';
import { useAdministrationItems } from './useAdministrationItems';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// ✅ turns retries off
retry: false,
},
},
});
beforeEach(() => {
queryClient.clear();
});
it('should not show upgrade item if has license and not have trial', async () => {
const { result, waitFor } = renderHook(() => useAdministrationItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleRequest={async (args) => {
if (args.method === 'GET' && args.pathPattern === '/v1/licenses.get') {
return {
licenses: [
{
modules: ['testModule'],
meta: { trial: false },
},
],
} as any;
}
if (args.method === 'GET' && args.pathPattern === '/v1/cloud.registrationStatus') {
return {
registrationStatus: {
workspaceRegistered: false,
},
};
}
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={[]}>
<MockedModalContext>{children}</MockedModalContext>
</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => Boolean(result.all.length > 1));
expect(result.current).toEqual([]);
});
it('should return an upgrade item if not have license or if have a trial', async () => {
const { result, waitFor } = renderHook(() => useAdministrationItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleRequest={async (args) => {
if (args.method === 'GET' && args.pathPattern === '/v1/licenses.get') {
return {
licenses: [
{
modules: [],
},
],
} as any;
}
if (args.method === 'GET' && args.pathPattern === '/v1/cloud.registrationStatus') {
return {
registrationStatus: {
workspaceRegistered: false,
},
};
}
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={[]}>
<MockedModalContext>{children}</MockedModalContext>
</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => {
return !queryClient.isFetching();
});
expect(result.current[0]).toEqual(
expect.objectContaining({
id: 'showUpgradeItem',
}),
);
});
it('should return omnichannel item if has `view-livechat-manager` permission ', async () => {
const { result, waitFor } = renderHook(() => useAdministrationItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleRequest={async (args) => {
if (args.method === 'GET' && args.pathPattern === '/v1/licenses.get') {
return {
licenses: [
{
modules: [],
},
],
} as any;
}
if (args.method === 'GET' && args.pathPattern === '/v1/cloud.registrationStatus') {
return {
registrationStatus: {
workspaceRegistered: false,
},
};
}
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={['view-livechat-manager']}>
<MockedModalContext>{children}</MockedModalContext>
</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => Boolean(result.current.length));
expect(result.current[0]).toEqual(
expect.objectContaining({
id: 'omnichannel',
}),
);
});
it('should show administration item if has at least one admin permission', async () => {
const { result, waitFor } = renderHook(() => useAdministrationItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleRequest={async (args) => {
if (args.method === 'GET' && args.pathPattern === '/v1/licenses.get') {
return {
licenses: [
{
modules: [],
},
],
} as any;
}
if (args.method === 'GET' && args.pathPattern === '/v1/cloud.registrationStatus') {
return {
registrationStatus: {
workspaceRegistered: false,
},
};
}
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={['access-permissions']}>
<MockedModalContext>{children}</MockedModalContext>
</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => Boolean(result.current.length));
expect(result.current[0]).toEqual(
expect.objectContaining({
id: 'workspace',
}),
);
});
import {
useTranslation,
useRoute,
useMethod,
useSetModal,
useRole,
useRouter,
useAtLeastOnePermission,
usePermission,
} from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import React from 'react';
import type { UpgradeTabVariant } from '../../../../../lib/upgradeTab';
import { getUpgradeTabLabel, isFullyFeature } from '../../../../../lib/upgradeTab';
import Emoji from '../../../../components/Emoji';
import type { GenericMenuItemProps } from '../../../../components/GenericMenu/GenericMenuItem';
import { useRegistrationStatus } from '../../../../hooks/useRegistrationStatus';
import RegisterWorkspaceModal from '../../../../views/admin/cloud/modals/RegisterWorkspaceModal';
import { useUpgradeTabParams } from '../../../../views/hooks/useUpgradeTabParams';
......@@ -53,8 +52,8 @@ const ADMIN_PERMISSIONS = [
*/
export const useAdministrationItems = (): GenericMenuItemProps[] => {
const router = useRouter();
const t = useTranslation();
const router = useRouter();
const shouldShowAdminMenu = useAtLeastOnePermission(ADMIN_PERMISSIONS);
......@@ -66,9 +65,13 @@ export const useAdministrationItems = (): GenericMenuItemProps[] => {
const isAdmin = useRole('admin');
const setModal = useSetModal();
const checkCloudRegisterStatus = useMethod('cloud:checkRegisterStatus');
const result = useQuery(['admin/cloud/register-status'], async () => checkCloudRegisterStatus());
const { workspaceRegistered } = result.data || {};
// TODO: DEPRECATE IT
// const checkCloudRegisterStatus = useMethod('cloud:checkRegisterStatus');
// const result = useQuery(['admin/cloud/register-status'], async () => checkCloudRegisterStatus());
// const { workspaceRegistered } = result.data || {};
const { data: registrationStatusData } = useRegistrationStatus();
const workspaceRegistered = registrationStatusData?.registrationStatus?.workspaceRegistered ?? false;
const handleRegisterWorkspaceClick = (): void => {
const handleModalClose = (): void => setModal(null);
......
import { MockedAuthorizationContext } from '@rocket.chat/mock-providers/src/MockedAuthorizationContext';
import { MockedServerContext } from '@rocket.chat/mock-providers/src/MockedServerContext';
import { MockedSettingsContext } from '@rocket.chat/mock-providers/src/MockedSettingsContext';
import { MockedUserContext } from '@rocket.chat/mock-providers/src/MockedUserContext';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { renderHook } from '@testing-library/react-hooks';
import React from 'react';
import { useAuditItems } from './useAuditItems';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// ✅ turns retries off
retry: false,
},
},
});
it('should return an empty array if doesn`t have license', async () => {
const { result, waitFor } = renderHook(() => useAuditItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleMethod={(methodName, ..._) => {
if (methodName === 'license:getModules') {
return [] as any;
}
throw new Error('Method not mocked');
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={['can-audit', 'can-audit-log']}>{children}</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => Boolean(result.all.length > 1));
expect(result.current).toEqual([]);
});
it('should return an empty array if have license and not have permissions', async () => {
const { result, waitFor } = renderHook(() => useAuditItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleMethod={(methodName, ..._) => {
if (methodName === 'license:getModules') {
return ['auditing'] as any;
}
throw new Error('Method not mocked');
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={[]}>{children}</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => Boolean(result.all.length > 1));
expect(result.current).toEqual([]);
});
it('should return auditItems if have license and permissions', async () => {
const { result, waitFor } = renderHook(() => useAuditItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleMethod={(methodName, ..._) => {
if (methodName === 'license:getModules') {
return ['auditing'] as any;
}
throw new Error('Method not mocked');
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={['can-audit', 'can-audit-log']}>{children}</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => Boolean(result.current.length));
expect(result.current[0]).toEqual(
expect.objectContaining({
id: 'messages',
}),
);
expect(result.current[1]).toEqual(
expect.objectContaining({
id: 'auditLog',
}),
);
});
it('should return auditMessages item if have license and can-audit permission', async () => {
const { result, waitFor } = renderHook(() => useAuditItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleMethod={(methodName, ..._) => {
if (methodName === 'license:getModules') {
return ['auditing'] as any;
}
throw new Error('Method not mocked');
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={['can-audit']}>{children}</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => Boolean(result.current.length));
expect(result.current[0]).toEqual(
expect.objectContaining({
id: 'messages',
}),
);
});
it('should return audiLogs item if have license and can-audit-log permission', async () => {
const { result, waitFor } = renderHook(() => useAuditItems(), {
wrapper: ({ children }) => (
<QueryClientProvider client={queryClient}>
<MockedServerContext
handleMethod={(methodName, ..._) => {
if (methodName === 'license:getModules') {
return ['auditing'] as any;
}
throw new Error('Method not mocked');
}}
>
<MockedSettingsContext settings={{}}>
<MockedUserContext userPreferences={{}}>
<MockedAuthorizationContext permissions={['can-audit-log']}>{children}</MockedAuthorizationContext>
</MockedUserContext>
</MockedSettingsContext>
</MockedServerContext>
</QueryClientProvider>
),
});
await waitFor(() => Boolean(result.current.length));
expect(result.current[0]).toEqual(
expect.objectContaining({
id: 'auditLog',
}),
);
});
......@@ -13,7 +13,7 @@ export const useUpgradeTabParams = (): { tabType: UpgradeTabVariant | false; tri
const { data: registrationStatusData, isSuccess: isSuccessRegistrationStatus } = useRegistrationStatus();
const registered = registrationStatusData?.registrationStatus?.workspaceRegistered ?? false;
const hasValidLicense = licensesData?.licenses.some((licence) => licence.modules.length > 0) ?? false;
const hasValidLicense = licensesData?.licenses.some((license) => license.modules.length > 0) ?? false;
const hadExpiredTrials = cloudWorkspaceHadTrial ?? false;
const trialLicense = licensesData?.licenses?.find(({ meta }) => meta?.trial);
......
File moved
......@@ -39,7 +39,7 @@
"testapi": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' mocha --config ./.mocharc.api.js",
"testunit": "npm run .testunit:definition && npm run .testunit:client && npm run .testunit:server",
".testunit:server": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' mocha --config ./.mocharc.js",
".testunit:client": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' mocha --config ./.mocharc.client.js --exit",
".testunit:client": "jest && TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' mocha --config ./.mocharc.client.js --exit",
".testunit:definition": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' mocha --config ./.mocharc.definition.js",
"testunit-watch": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' mocha --watch --config ./.mocharc.js",
"test": "npm run testapi && npm run testui",
......
import type { ReactNode } from 'react';
import React from 'react';
import { ModalContext } from '@rocket.chat/ui-contexts';
export const MockedModalContext = ({ children }: { children: React.ReactNode }) => {
const [currentModal, setCurrentModal] = React.useState<ReactNode>(null);
return (
<ModalContext.Provider
value={{
modal: {
setModal: setCurrentModal,
},
currentModal,
}}
>
{children}
</ModalContext.Provider>
);
};
import React from 'react';
import type { Serialized } from '@rocket.chat/core-typings';
import type { Method, OperationParams, OperationResult, PathPattern, UrlParams } from '@rocket.chat/rest-typings';
import type { ServerMethodName, ServerMethodParameters } from '@rocket.chat/ui-contexts';
import type { ServerMethodName, ServerMethodParameters, ServerMethodReturn } from '@rocket.chat/ui-contexts';
import { ServerContext } from '@rocket.chat/ui-contexts';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
export const MockedServerContext = ({
handleRequest,
handleMethod,
children,
}: {
handleRequest: <TMethod extends Method, TPathPattern extends PathPattern>(args: {
handleRequest?: <TMethod extends Method, TPathPattern extends PathPattern>(args: {
method: TMethod;
pathPattern: TPathPattern;
keys: UrlParams<TPathPattern>;
params: OperationParams<TMethod, TPathPattern>;
}) => Promise<Serialized<OperationResult<TMethod, TPathPattern>>>;
handleMethod?: <MethodName extends ServerMethodName>(
methodName: MethodName,
...args: ServerMethodParameters<MethodName>
) => Promise<ServerMethodReturn<MethodName>>;
children: React.ReactNode;
}): any => {
const [queryClient] = React.useState(() => new QueryClient());
......@@ -23,15 +28,16 @@ export const MockedServerContext = ({
value={
{
absoluteUrl: (path: string) => `http://localhost:3000/${path}`,
callMethod: <MethodName extends ServerMethodName>(_methodName: MethodName, ..._args: ServerMethodParameters<MethodName>) =>
Promise.reject('mock not implemented'),
callMethod: <MethodName extends ServerMethodName>(methodName: MethodName, ...args: ServerMethodParameters<MethodName>) => {
return handleMethod?.(methodName, ...args);
},
callEndpoint: async <TMethod extends Method, TPathPattern extends PathPattern>(args: {
method: TMethod;
pathPattern: TPathPattern;
keys: UrlParams<TPathPattern>;
params: OperationParams<TMethod, TPathPattern>;
}) => {
return handleRequest(args);
return handleRequest?.(args);
},
getStream: () => () => undefined,
} as any
......
export * from './MockedAuthorizationContext';
export * from './MockedModalContext';
export * from './MockedServerContext';
export * from './MockedSettingsContext';
export * from './MockedUserContext';
......@@ -71,3 +71,36 @@ it('should return 0 unseen features', () => {
}),
);
});
it('should ignore removed feature previews', () => {
const { result } = renderHook(() => useFeaturePreviewList(), {
wrapper: ({ children }) => (
<MockedSettingsContext
settings={{
Accounts_AllowFeaturePreview: true,
}}
>
<MockedUserContext
userPreferences={{
featuresPreview: [
{
name: 'oldFeature',
value: false,
},
],
}}
>
{children}
</MockedUserContext>
</MockedSettingsContext>
),
});
expect(result.current).toEqual(
expect.objectContaining({
featurePreviewEnabled: true,
unseenFeatures: defaultFeaturesPreview.length,
features: defaultFeaturesPreview,
}),
);
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment