diff --git a/packages/editor-ui/src/plugins/i18n/locales/en.json b/packages/editor-ui/src/plugins/i18n/locales/en.json index 7dc37253b82b8..c2a8182b24a4a 100644 --- a/packages/editor-ui/src/plugins/i18n/locales/en.json +++ b/packages/editor-ui/src/plugins/i18n/locales/en.json @@ -1797,6 +1797,7 @@ "settings.usageAndPlan.license.activation.error.title": "Activation failed", "settings.usageAndPlan.license.activation.success.title": "License activated", "settings.usageAndPlan.license.activation.success.message": "Your {name} {type} has been successfully activated.", + "settings.usageAndPlan.license.communityRegistered.tooltip": "You have registered your email to unlock additional features on your community plan", "settings.externalSecrets.title": "External Secrets", "settings.externalSecrets.info": "Connect external secrets tools for centralized credentials management across environments, and to enhance system security.", "settings.externalSecrets.info.link": "More info", diff --git a/packages/editor-ui/src/views/SettingsUsageAndPlan.test.ts b/packages/editor-ui/src/views/SettingsUsageAndPlan.test.ts new file mode 100644 index 0000000000000..2002d2f7318fb --- /dev/null +++ b/packages/editor-ui/src/views/SettingsUsageAndPlan.test.ts @@ -0,0 +1,51 @@ +import { createTestingPinia } from '@pinia/testing'; +import { createComponentRenderer } from '@/__tests__/render'; +import { mockedStore } from '@/__tests__/utils'; +import { useUsageStore } from '@/stores/usage.store'; +import SettingsUsageAndPlan from '@/views/SettingsUsageAndPlan.vue'; + +vi.mock('vue-router', () => { + return { + useRoute: () => ({ + query: {}, + }), + useRouter: () => ({ + replace: vi.fn(), + }), + RouterLink: { + template: '', + }, + }; +}); + +let usageStore: ReturnType>; + +const renderComponent = createComponentRenderer(SettingsUsageAndPlan); + +describe('SettingsUsageAndPlan', () => { + beforeEach(() => { + createTestingPinia(); + usageStore = mockedStore(useUsageStore); + }); + + it('should not throw errors when rendering', async () => { + expect(() => renderComponent()).not.toThrow(); + }); + + it('should render the title only while loading', async () => { + const { getByRole } = renderComponent(); + expect(getByRole('heading', { level: 2 })).toBeInTheDocument(); + expect(getByRole('heading').nextElementSibling).toBeNull(); + }); + + it('should show community registered badge', async () => { + usageStore.isLoading = false; + usageStore.viewPlansUrl = 'https://subscription.n8n.io'; + usageStore.managePlanUrl = 'https://subscription.n8n.io'; + usageStore.planName = 'Community registered'; + const { getByRole, container } = renderComponent(); + expect(getByRole('heading', { level: 3 })).toHaveTextContent('Community Edition'); + expect(getByRole('heading', { level: 3 })).toContain(container.querySelector('.n8n-badge')); + expect(container.querySelector('.n8n-badge')).toHaveTextContent('registered'); + }); +}); diff --git a/packages/editor-ui/src/views/SettingsUsageAndPlan.vue b/packages/editor-ui/src/views/SettingsUsageAndPlan.vue index f562bf7bb9e20..81506dfadcd33 100644 --- a/packages/editor-ui/src/views/SettingsUsageAndPlan.vue +++ b/packages/editor-ui/src/views/SettingsUsageAndPlan.vue @@ -32,6 +32,18 @@ const canUserActivateLicense = computed(() => hasPermission(['rbac'], { rbac: { scope: 'license:manage' } }), ); +const badgedPlanName = computed(() => { + const [name, badge] = usageStore.planName.split(' '); + return { + name, + badge, + }; +}); + +const isCommunityEditionRegistered = computed( + () => usageStore.planName.toLowerCase() === 'community registered', +); + const showActivationSuccess = () => { toast.showMessage({ type: 'success', @@ -125,11 +137,15 @@ const onDialogOpened = () => {