Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ui/src/__tests__/components/denali/icons/Icon.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,17 @@ describe('Icon', () => {
const icon = getByTestId('icon');
expect(icon).toMatchSnapshot();
});

it('should render default managed-resource icon key with 24x24 viewBox', () => {
const { getByTestId } = render(
<Icon
icon='terraform'
viewBoxWidth='24'
viewBoxHeight='24'
size='1.25em'
/>
);
const icon = getByTestId('icon');
expect(icon.getAttribute('viewBox')).toBe('0 0 24 24');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright The Athenz Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { render } from '@testing-library/react';
import { ManagedResourceIcon } from '../../../components/resource-ownership/ManagedResourceIcon';

describe('ManagedResourceIcon', () => {
it('renders nothing when show is false', () => {
const { container } = render(<ManagedResourceIcon show={false} />);
expect(container.firstChild).toBeNull();
});

it('renders icon with stable data-wdio when shown', () => {
const { container } = render(
<ManagedResourceIcon
show={true}
resourceOwnershipUi={{ icon: 'terraform', label: 'OpenTofu' }}
tooltip='Custom tooltip'
/>
);
const svg = container.querySelector(
'[data-wdio="resource-ownership-managed"]'
);
expect(svg).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright The Athenz Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React from 'react';
import { render, fireEvent, act } from '@testing-library/react';
import { ResourceOwnershipCliSuggestion } from '../../../components/resource-ownership/ResourceOwnershipCliSuggestion';

describe('ResourceOwnershipCliSuggestion', () => {
const writeText = jest.fn();

beforeEach(() => {
jest.useFakeTimers();
writeText.mockResolvedValue(undefined);
Object.assign(navigator, { clipboard: { writeText } });
});

afterEach(() => {
jest.useRealTimers();
jest.restoreAllMocks();
});

it('copies command and resets copied state after delay', async () => {
const { getByTestId } = render(
<ResourceOwnershipCliSuggestion command='zms-cli -d my.domain' />
);
await act(async () => {
fireEvent.click(getByTestId('resource-ownership-cli-copy'));
});
expect(writeText).toHaveBeenCalledWith('zms-cli -d my.domain');
expect(getByTestId('resource-ownership-cli-copy').title).toBe('Copied');
await act(async () => {
jest.advanceTimersByTime(2000);
});
expect(getByTestId('resource-ownership-cli-copy').title).toBe(
'Copy command'
);
});

it('clears copied timer on unmount', async () => {
const setState = jest.spyOn(
ResourceOwnershipCliSuggestion.prototype,
'setState'
);
const { getByTestId, unmount } = render(
<ResourceOwnershipCliSuggestion command='zms-cli -d my.domain' />
);
await act(async () => {
fireEvent.click(getByTestId('resource-ownership-cli-copy'));
});
unmount();
setState.mockClear();
jest.advanceTimersByTime(2000);
expect(setState).not.toHaveBeenCalled();
setState.mockRestore();
});

it('renders configurable owner label in warning copy', () => {
const { getByTestId } = render(
<ResourceOwnershipCliSuggestion
command='zms-cli -d my.domain'
resourceOwnershipUi={{
label: 'OpenTofu',
icon: 'terraform',
cliSuggestionBody:
'This resource is {{label}}-managed and cannot be edited via the Athenz UI.',
cliSuggestionEmergencyHeading: 'Emergency only:',
cliSuggestionGuideFooter: 'See',
}}
/>
);
expect(
getByTestId('resource-ownership-cli-suggestion').textContent
).toContain('OpenTofu-managed');
});

it('does not show copied state when clipboard write fails', async () => {
writeText.mockRejectedValue(new Error('denied'));
const { getByTestId } = render(
<ResourceOwnershipCliSuggestion command='zms-cli -d my.domain' />
);
await act(async () => {
fireEvent.click(getByTestId('resource-ownership-cli-copy'));
});
expect(getByTestId('resource-ownership-cli-copy').title).toBe(
'Copy command'
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright The Athenz Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import ResourceOwnershipModalFeedback from '../../../components/resource-ownership/ResourceOwnershipModalFeedback';

const store = createStore(() => ({
domains: { headerDetails: {} },
}));

function renderWithStore(ui) {
return render(<Provider store={store}>{ui}</Provider>);
}

describe('ResourceOwnershipModalFeedback', () => {
it('shows CLI suggestion instead of raw error when command is set', () => {
const { getByTestId, queryByText } = renderWithStore(
<ResourceOwnershipModalFeedback
errorMessage='Forbidden'
resourceOwnershipCliCommand='zms-cli -d dom'
/>
);
expect(getByTestId('resource-ownership-cli-suggestion')).toBeTruthy();
expect(queryByText('Forbidden')).toBeNull();
});

it('shows error when no CLI command', () => {
const { getByText } = renderWithStore(
<ResourceOwnershipModalFeedback
errorMessage='Forbidden'
resourceOwnershipCliCommand={null}
/>
);
expect(getByText('Forbidden')).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -499,13 +499,13 @@ exports[`AddAssertionForRole should render 1`] = `
>
<input
checked=""
id="radiobutton-rule-effect-radio-groupundefined-ALLOW"
name="rule-effect-radio-groupundefined"
id="radiobutton-rule-effect-radio-group-undefined-ALLOW"
name="rule-effect-radio-group-undefined"
type="radio"
value="ALLOW"
/>
<label
for="radiobutton-rule-effect-radio-groupundefined-ALLOW"
for="radiobutton-rule-effect-radio-group-undefined-ALLOW"
>
Allow
</label>
Expand All @@ -515,13 +515,13 @@ exports[`AddAssertionForRole should render 1`] = `
data-testid="radiobutton-wrapper"
>
<input
id="radiobutton-rule-effect-radio-groupundefined-DENY"
name="rule-effect-radio-groupundefined"
id="radiobutton-rule-effect-radio-group-undefined-DENY"
name="rule-effect-radio-group-undefined"
type="radio"
value="DENY"
/>
<label
for="radiobutton-rule-effect-radio-groupundefined-DENY"
for="radiobutton-rule-effect-radio-group-undefined-DENY"
>
Deny
</label>
Expand All @@ -548,8 +548,8 @@ exports[`AddAssertionForRole should render 1`] = `
<input
autocomplete="off"
data-testid="input-node"
id="rule-actionundefined"
name="rule-actionundefined"
id="rule-action-undefined"
name="rule-action-undefined"
placeholder="Rule Action"
value=""
/>
Expand Down Expand Up @@ -579,8 +579,8 @@ exports[`AddAssertionForRole should render 1`] = `
<input
autocomplete="off"
data-testid="input-node"
id="rule-resourceundefined"
name="rule-resourceundefined"
id="rule-resource-undefined"
name="rule-resource-undefined"
placeholder="Rule Resource"
value=""
/>
Expand All @@ -603,12 +603,12 @@ exports[`AddAssertionForRole should render 1`] = `
>
<input
data-partial="false"
id="checkbox-case-sensitiveundefined"
name="checkbox-case-sensitiveundefined"
id="checkbox-case-sensitive-undefined"
name="checkbox-case-sensitive-undefined"
type="checkbox"
/>
<label
for="checkbox-case-sensitiveundefined"
for="checkbox-case-sensitive-undefined"
>
Case Sensitive Action and Resource
</label>
Expand Down Expand Up @@ -1132,13 +1132,13 @@ exports[`AddAssertionForRole should render failed to submit action is required 1
>
<input
checked=""
id="radiobutton-rule-effect-radio-groupundefined-ALLOW"
name="rule-effect-radio-groupundefined"
id="radiobutton-rule-effect-radio-group-undefined-ALLOW"
name="rule-effect-radio-group-undefined"
type="radio"
value="ALLOW"
/>
<label
for="radiobutton-rule-effect-radio-groupundefined-ALLOW"
for="radiobutton-rule-effect-radio-group-undefined-ALLOW"
>
Allow
</label>
Expand All @@ -1148,13 +1148,13 @@ exports[`AddAssertionForRole should render failed to submit action is required 1
data-testid="radiobutton-wrapper"
>
<input
id="radiobutton-rule-effect-radio-groupundefined-DENY"
name="rule-effect-radio-groupundefined"
id="radiobutton-rule-effect-radio-group-undefined-DENY"
name="rule-effect-radio-group-undefined"
type="radio"
value="DENY"
/>
<label
for="radiobutton-rule-effect-radio-groupundefined-DENY"
for="radiobutton-rule-effect-radio-group-undefined-DENY"
>
Deny
</label>
Expand All @@ -1181,8 +1181,8 @@ exports[`AddAssertionForRole should render failed to submit action is required 1
<input
autocomplete="off"
data-testid="input-node"
id="rule-actionundefined"
name="rule-actionundefined"
id="rule-action-undefined"
name="rule-action-undefined"
placeholder="Rule Action"
value=""
/>
Expand Down Expand Up @@ -1212,8 +1212,8 @@ exports[`AddAssertionForRole should render failed to submit action is required 1
<input
autocomplete="off"
data-testid="input-node"
id="rule-resourceundefined"
name="rule-resourceundefined"
id="rule-resource-undefined"
name="rule-resource-undefined"
placeholder="Rule Resource"
value=""
/>
Expand All @@ -1236,12 +1236,12 @@ exports[`AddAssertionForRole should render failed to submit action is required 1
>
<input
data-partial="false"
id="checkbox-case-sensitiveundefined"
name="checkbox-case-sensitiveundefined"
id="checkbox-case-sensitive-undefined"
name="checkbox-case-sensitive-undefined"
type="checkbox"
/>
<label
for="checkbox-case-sensitiveundefined"
for="checkbox-case-sensitive-undefined"
>
Case Sensitive Action and Resource
</label>
Expand Down
Loading
Loading