Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ describe('OnboardingLicenseStep.vue', () => {
expect(wrapper.text()).toContain('Manage License');
});

it('renders a clear status when no licensing device is available', () => {
activationStoreMock.registrationState.value = 'ENOFLASH';

const wrapper = mountComponent();

expect(wrapper.text()).toContain('No valid license device detected');
expect(wrapper.text()).not.toContain('Unregistered');
});

it('opens activation link in new tab when activate button is clicked', async () => {
const windowOpenMock = vi.fn();
vi.stubGlobal('open', windowOpenMock);
Expand Down
11 changes: 11 additions & 0 deletions web/__test__/components/Registration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,17 @@ describe('Registration.standalone.vue', () => {
expect(wrapper.find('[data-testid="manage-license-button"]').exists()).toBe(false);
});

it('renders licensing-device copy when no valid licensing device is available', async () => {
serverStore.state = 'ENOFLASH';

await wrapper.vm.$nextTick();

expect(wrapper.find('h3').text()).toContain('No valid license device detected');
expect(wrapper.find('.prose').text()).toContain(
'No valid TPM or USB flash device was detected for licensing.'
);
});

it('does not show a connect sign-in action on the registration page', async () => {
serverStore.state = 'ENOKEYFILE';
serverStore.registered = false;
Expand Down
34 changes: 28 additions & 6 deletions web/src/components/Onboarding/steps/OnboardingLicenseStep.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,43 @@ const { activationCode, registrationState, hasActivationCode } = storeToRefs(
useActivationCodeDataStore()
);

// Valid license states where the server is considered "Registered/Licensed"
const VALID_LICENSE_STATES = ['TRIAL', 'BASIC', 'STARTER', 'PLUS', 'PRO', 'UNLEASHED', 'LIFETIME'];
const VALID_LICENSE_STATES: ReadonlySet<string> = new Set([
'TRIAL',
'BASIC',
'STARTER',
'PLUS',
'PRO',
'UNLEASHED',
'LIFETIME',
]);
const NO_LICENSE_DEVICE_STATES: ReadonlySet<string> = new Set([
'ENOFLASH',
'ENOFLASH1',
'ENOFLASH2',
'ENOFLASH3',
'ENOFLASH4',
'ENOFLASH5',
'ENOFLASH6',
'ENOFLASH7',
]);
const lt = (key: string, fallback: string) => (te(key) ? t(key) : fallback);

const effectiveState = computed(() => registrationState.value || state.value);

const hasValidLicense = computed(() => {
return effectiveState.value && VALID_LICENSE_STATES.includes(effectiveState.value);
return Boolean(effectiveState.value && VALID_LICENSE_STATES.has(effectiveState.value));
});
const hasNoLicenseDevice = computed(() => {
return Boolean(effectiveState.value && NO_LICENSE_DEVICE_STATES.has(effectiveState.value));
});

// Computeds
const statusText = computed(() =>
hasValidLicense.value
? lt('onboarding.licenseStep.status.registered', 'Registered')
: lt('onboarding.licenseStep.status.unregistered', 'Unregistered')
hasNoLicenseDevice.value
? lt('onboarding.licenseStep.status.noLicenseDevice', 'No valid license device detected')
: hasValidLicense.value
? lt('onboarding.licenseStep.status.registered', 'Registered')
: lt('onboarding.licenseStep.status.unregistered', 'Unregistered')
);
const statusBoxTextClass = computed(() => (hasValidLicense.value ? 'text-green-500' : 'text-red-500'));

Expand Down
7 changes: 4 additions & 3 deletions web/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@
"onboarding.licenseStep.title": "Unraid OS License",
"onboarding.licenseStep.description": "Ready for activation. Click below to manage your license and server registration in the Unraid Account App.",
"onboarding.licenseStep.status.registered": "Registered",
"onboarding.licenseStep.status.noLicenseDevice": "No valid license device detected",
"onboarding.licenseStep.status.unregistered": "Unregistered",
"onboarding.licenseStep.labels.status": "Status",
"onboarding.licenseStep.labels.activationCode": "Activation Code",
Expand Down Expand Up @@ -778,9 +779,9 @@
"server.state.enoconn.heading": "Cannot validate Unraid Trial key",
"server.state.enoconn.humanReadable": "Trial Requires Internet Connection",
"server.state.enoconn.message": "<p>Your Trial key requires an internet connection.</p><p><a href=\"/Settings/NetworkSettings\" class=\"underline\">Please check Settings > Network</a></p>",
"server.state.enoflash.heading": "Cannot access your boot device",
"server.state.enoflash.humanReadable": "No Boot Device",
"server.state.enoflash.message": "<p>There is a physical problem accessing your boot device</p>",
"server.state.enoflash.heading": "No valid license device detected",
"server.state.enoflash.humanReadable": "No License Device",
"server.state.enoflash.message": "<p>No valid TPM or USB flash device was detected for licensing. Connect a license-capable USB flash device or enable TPM licensing, then refresh registration.</p>",
"server.state.enokeyfile.heading": "Let's Unleash Your Hardware",
"server.state.enokeyfile.humanReadable": "No Keyfile",
"server.state.enokeyfile.message": "<p>Choose an option below, then use our <a href=\"https://unraid.net/getting-started\" target=\"_blank\" rel=\"noreffer noopener\">Getting Started Guide</a> to configure your array in less than 15 minutes.</p>",
Expand Down
Loading