mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
fix: orphaned token label only for items without projects (#7901)
Orphaned token label was incorrectly assigned. Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This commit is contained in:
parent
0847a395dc
commit
b9ea24be8d
@ -1,7 +1,68 @@
|
|||||||
import { render } from 'utils/testRenderer';
|
import { render } from 'utils/testRenderer';
|
||||||
import { screen } from '@testing-library/react';
|
import { screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { ApiTokenIcon } from './ApiTokenIcon';
|
import { ApiTokenIcon, isOrphanedToken } from './ApiTokenIcon';
|
||||||
|
|
||||||
|
describe('isOrphanedToken', () => {
|
||||||
|
it('should be true for wildcard tokens with secret indicating it is orphaned', () => {
|
||||||
|
expect(
|
||||||
|
isOrphanedToken({
|
||||||
|
secret: '[]:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b',
|
||||||
|
projects: ['*'],
|
||||||
|
project: '*',
|
||||||
|
}),
|
||||||
|
).toBe(true);
|
||||||
|
expect(
|
||||||
|
isOrphanedToken({
|
||||||
|
secret: 'test:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b',
|
||||||
|
projects: ['*'],
|
||||||
|
project: '*',
|
||||||
|
}),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be false for true wildcard tokens', () => {
|
||||||
|
expect(
|
||||||
|
isOrphanedToken({
|
||||||
|
secret: '*:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b',
|
||||||
|
projects: ['*'],
|
||||||
|
project: '*',
|
||||||
|
}),
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be false for secrets in v1 format', () => {
|
||||||
|
expect(
|
||||||
|
isOrphanedToken({
|
||||||
|
secret: 'be44368985f7fb3237c584ef86f3d6bdada42ddbd63a019d26955178',
|
||||||
|
projects: ['*'],
|
||||||
|
project: '*',
|
||||||
|
}),
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be false if there are projects assigned to a token', () => {
|
||||||
|
expect(
|
||||||
|
isOrphanedToken({
|
||||||
|
secret: 'test:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b',
|
||||||
|
projects: ['test'],
|
||||||
|
project: 'test',
|
||||||
|
}),
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
isOrphanedToken({
|
||||||
|
secret: '[]:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b',
|
||||||
|
projects: ['a', 'b'],
|
||||||
|
}),
|
||||||
|
).toBe(false);
|
||||||
|
expect(
|
||||||
|
isOrphanedToken({
|
||||||
|
secret: '[]:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b',
|
||||||
|
projects: ['a'],
|
||||||
|
}),
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('ApiTokenIcon', () => {
|
describe('ApiTokenIcon', () => {
|
||||||
it('should show warning icon if it is an orphaned token', async () => {
|
it('should show warning icon if it is an orphaned token', async () => {
|
||||||
@ -16,7 +77,10 @@ describe('ApiTokenIcon', () => {
|
|||||||
it('should show tooltip with warning message if it is an orphaned token', async () => {
|
it('should show tooltip with warning message if it is an orphaned token', async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
render(
|
render(
|
||||||
<ApiTokenIcon secret='test:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b' />,
|
<ApiTokenIcon
|
||||||
|
secret='test:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b'
|
||||||
|
projects={[]}
|
||||||
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const errorIcon = await screen.findByTestId('orphaned-token-icon');
|
const errorIcon = await screen.findByTestId('orphaned-token-icon');
|
||||||
@ -26,18 +90,13 @@ describe('ApiTokenIcon', () => {
|
|||||||
expect(tooltip).toHaveTextContent(/orphaned token/);
|
expect(tooltip).toHaveTextContent(/orphaned token/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not show warning icon if token is in v1 format', async () => {
|
|
||||||
render(
|
|
||||||
<ApiTokenIcon secret='be44368985f7fb3237c584ef86f3d6bdada42ddbd63a019d26955178' />,
|
|
||||||
);
|
|
||||||
|
|
||||||
const errorIcon = await screen.queryByTestId('orphaned-token-icon');
|
|
||||||
expect(errorIcon).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not show warning for true wildcard tokens', async () => {
|
it('should not show warning for true wildcard tokens', async () => {
|
||||||
render(
|
render(
|
||||||
<ApiTokenIcon secret='*:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b' />,
|
<ApiTokenIcon
|
||||||
|
secret='*:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b'
|
||||||
|
project='*'
|
||||||
|
projects={['*']}
|
||||||
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const errorIcon = await screen.queryByTestId('orphaned-token-icon');
|
const errorIcon = await screen.queryByTestId('orphaned-token-icon');
|
||||||
|
@ -11,12 +11,23 @@ interface IApiTokenIconProps {
|
|||||||
secret?: string;
|
secret?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ApiTokenIcon: FC<IApiTokenIconProps> = ({ secret }) => {
|
export const isOrphanedToken = ({
|
||||||
|
secret,
|
||||||
|
project,
|
||||||
|
projects,
|
||||||
|
}: IApiTokenIconProps): boolean => {
|
||||||
const tokenFormat = secret?.includes(':') ? 'v2' : 'v1'; // see https://docs.getunleash.io/reference/api-tokens-and-client-keys#format
|
const tokenFormat = secret?.includes(':') ? 'v2' : 'v1'; // see https://docs.getunleash.io/reference/api-tokens-and-client-keys#format
|
||||||
const isWildcardToken = secret?.startsWith('*:');
|
const isWildcardSecret = secret?.startsWith('*:');
|
||||||
const isOrphanedToken = tokenFormat === 'v2' && !isWildcardToken;
|
const hasProjects =
|
||||||
|
(projects && projects?.length > 1) ||
|
||||||
|
(projects?.length === 1 && projects[0] !== '*') ||
|
||||||
|
(project && project !== '*');
|
||||||
|
|
||||||
if (isOrphanedToken) {
|
return tokenFormat === 'v2' && !isWildcardSecret && !hasProjects;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ApiTokenIcon: FC<IApiTokenIconProps> = ({ ...props }) => {
|
||||||
|
if (isOrphanedToken(props)) {
|
||||||
return (
|
return (
|
||||||
<IconCell
|
<IconCell
|
||||||
icon={
|
icon={
|
||||||
|
@ -27,7 +27,11 @@ export const useApiTokenTable = (
|
|||||||
{
|
{
|
||||||
id: 'Icon',
|
id: 'Icon',
|
||||||
Cell: (props: any) => (
|
Cell: (props: any) => (
|
||||||
<ApiTokenIcon secret={props.row.original.secret} />
|
<ApiTokenIcon
|
||||||
|
secret={props.row.original.secret}
|
||||||
|
project={props.row.original.project}
|
||||||
|
projects={props.row.original.projects}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
disableSortBy: true,
|
disableSortBy: true,
|
||||||
disableGlobalFilter: true,
|
disableGlobalFilter: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user