diff --git a/packages/frontend/@n8n/i18n/src/locales/en.json b/packages/frontend/@n8n/i18n/src/locales/en.json index 766587e622f..0e624a6cf7b 100644 --- a/packages/frontend/@n8n/i18n/src/locales/en.json +++ b/packages/frontend/@n8n/i18n/src/locales/en.json @@ -2533,8 +2533,8 @@ "nodeSettings.communityNodeTooltip": "This is a community node", "nodeSettings.retryOnFail.description": "If active, the node tries to execute again when it fails", "nodeSettings.retryOnFail.displayName": "Retry On Fail", - "nodeSettings.scopes.expandedNoticeWithScopes": "{count} scope available for {activeCredential} credentials
{scopes}
Show less | {count} scopes available for {activeCredential} credentials
{scopes}
Show less", - "nodeSettings.scopes.notice": "{count} scope available for {activeCredential} credentials | {count} scopes available for {activeCredential} credentials", + "nodeSettings.scopes.expandedNoticeWithScopes": "{count} scope available for {activeCredential} credentials
{scopes}
Show less | {count} scopes available for {activeCredential} credentials
{scopes}
Show less", + "nodeSettings.scopes.notice": "{count} scope available for {activeCredential} credentials | {count} scopes available for {activeCredential} credentials", "nodeSettings.theNodeIsNotValidAsItsTypeIsUnknown": "The node is not valid as its type ({nodeType}) is unknown", "nodeSettings.communityNodeDetails.title": "Node details", "nodeSettings.communityNodeUnknown.title": "Install this node to use it", diff --git a/packages/frontend/editor-ui/src/features/credentials/components/ScopesNotice.test.ts b/packages/frontend/editor-ui/src/features/credentials/components/ScopesNotice.test.ts new file mode 100644 index 00000000000..32a23ade5ff --- /dev/null +++ b/packages/frontend/editor-ui/src/features/credentials/components/ScopesNotice.test.ts @@ -0,0 +1,77 @@ +import { createTestingPinia } from '@pinia/testing'; +import userEvent from '@testing-library/user-event'; + +import { createComponentRenderer } from '@/__tests__/render'; +import { useCredentialsStore } from '../credentials.store'; +import ScopesNotice from './ScopesNotice.vue'; + +const renderComponent = createComponentRenderer(ScopesNotice); + +describe.each([ + { scopeCount: '1 scope', scopes: ['read:items'] }, + { scopeCount: '2 scopes', scopes: ['read:items', 'write:items'] }, +])('ScopesNotice ($scopeCount)', ({ scopeCount, scopes }) => { + beforeEach(() => { + createTestingPinia(); + useCredentialsStore().state.credentialTypes = { + testOAuth2Api: { + name: 'testOAuth2Api', + displayName: 'Test OAuth2 API', + properties: [], + }, + }; + }); + + it('reveals the available scopes when clicking the scope count', async () => { + const { getByText, getByRole } = renderComponent({ + props: { + activeCredentialType: 'testOAuth2Api', + scopes, + }, + }); + + expect(getByRole('region')).not.toHaveTextContent('read:items'); + expect(getByRole('region')).not.toHaveTextContent('write:items'); + + await userEvent.click(getByText(scopeCount, { exact: false })); + + for (const scope of scopes) { + expect(getByRole('region')).toHaveTextContent(scope); + } + expect(getByText('Show less')).toBeVisible(); + + await userEvent.click(getByText('Show less')); + + for (const scope of scopes) { + expect(getByRole('region')).not.toHaveTextContent(scope); + } + expect(getByText(`${scopeCount} available`)).toBeVisible(); + }); + + // NODE-5622: Users expect the "scopes available" control to reveal the scope list. + it('reveals the available scopes when clicking the available label', async () => { + const { getByText, getByRole } = renderComponent({ + props: { + activeCredentialType: 'testOAuth2Api', + scopes, + }, + }); + + expect(getByRole('region')).not.toHaveTextContent('read:items'); + expect(getByRole('region')).not.toHaveTextContent('write:items'); + + await userEvent.click(getByText(/available/)); + + for (const scope of scopes) { + expect(getByRole('region')).toHaveTextContent(scope); + } + expect(getByText('Show less')).toBeVisible(); + + await userEvent.click(getByText(/available/)); + + for (const scope of scopes) { + expect(getByRole('region')).not.toHaveTextContent(scope); + } + expect(getByText(`${scopeCount} available`)).toBeVisible(); + }); +});