Skip to content

Commit

Permalink
fix: orphaned token label patch (#7903)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tymek authored Aug 16, 2024
1 parent e8fa5ec commit 3b27b5a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,68 @@
import { render } from 'utils/testRenderer';
import { screen } from '@testing-library/react';
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', () => {
it('should show warning icon if it is an orphaned token', async () => {
Expand All @@ -16,7 +77,10 @@ describe('ApiTokenIcon', () => {
it('should show tooltip with warning message if it is an orphaned token', async () => {
const user = userEvent.setup();
render(
<ApiTokenIcon secret='test:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b' />,
<ApiTokenIcon
secret='test:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b'
projects={[]}
/>,
);

const errorIcon = await screen.findByTestId('orphaned-token-icon');
Expand All @@ -26,18 +90,13 @@ describe('ApiTokenIcon', () => {
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 () => {
render(
<ApiTokenIcon secret='*:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b' />,
<ApiTokenIcon
secret='*:development.be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b'
project='*'
projects={['*']}
/>,
);

const errorIcon = await screen.queryByTestId('orphaned-token-icon');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,23 @@ interface IApiTokenIconProps {
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 isWildcardToken = secret?.startsWith('*:');
const isOrphanedToken = tokenFormat === 'v2' && !isWildcardToken;
const isWildcardSecret = secret?.startsWith('*:');
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 (
<IconCell
icon={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ export const useApiTokenTable = (
{
id: 'Icon',
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,
disableGlobalFilter: true,
Expand Down

0 comments on commit 3b27b5a

Please sign in to comment.