diff --git a/web/__test__/components/Registration.test.ts b/web/__test__/components/Registration.test.ts index 5196d0c872..dce6329d51 100644 --- a/web/__test__/components/Registration.test.ts +++ b/web/__test__/components/Registration.test.ts @@ -88,7 +88,11 @@ vi.mock('@unraid/ui', async (importOriginal) => { return { ...actual, - BrandButton: { template: '', props: ['text', 'title', 'icon', 'disabled'] }, + BrandButton: { + template: + '', + props: ['text', 'title', 'icon', 'disabled'], + }, CardWrapper: { template: '
' }, PageContainer: { template: '
' }, SettingsGrid: { template: '
' }, @@ -321,6 +325,8 @@ describe('Registration.standalone.vue', () => { const moveButton = wrapper.find('[data-testid="move-license-to-tpm"]'); expect(moveButton.exists()).toBe(true); + expect(moveButton.attributes('disabled')).toBeUndefined(); + expect(findItemByLabel(t('TPM GUID'))?.props('text')).toBe('03-V35H8S0L1QHK1SBG1XHXJNH7'); }); it('shows Move License to TPM when flashGuid is missing but the active GUID is still a flash GUID', async () => { @@ -349,7 +355,7 @@ describe('Registration.standalone.vue', () => { expect(accountStore.replaceTpm).toHaveBeenCalled(); }); - it('does not show Move License to TPM for trial states', async () => { + it('shows a disabled Move License to TPM button for trial states', async () => { serverStore.state = 'TRIAL'; serverStore.guid = '058F-6387-0000-0000F1F1E1C6'; serverStore.flashGuid = '058F-6387-0000-0000F1F1E1C6'; @@ -358,7 +364,43 @@ describe('Registration.standalone.vue', () => { await wrapper.vm.$nextTick(); - expect(wrapper.find('[data-testid="move-license-to-tpm"]').exists()).toBe(false); + const moveButton = wrapper.find('[data-testid="move-license-to-tpm"]'); + + expect(moveButton.exists()).toBe(true); + expect(moveButton.attributes('disabled')).toBeDefined(); + expect(findItemByLabel(t('TPM GUID'))?.props('text')).toBe('03-V35H8S0L1QHK1SBG1XHXJNH7'); + expect(wrapper.text()).toContain( + 'Trials are locked to the registered GUID. You can move to TPM by purchasing a license.' + ); + }); + + it('shows a disabled Move License to TPM button for expired trial states', async () => { + serverStore.state = 'EEXPIRED'; + serverStore.guid = '058F-6387-0000-0000F1F1E1C6'; + serverStore.flashGuid = '058F-6387-0000-0000F1F1E1C6'; + serverStore.tpmGuid = '03-V35H8S0L1QHK1SBG1XHXJNH7'; + serverStore.keyfile = 'keyfile-present'; + + await wrapper.vm.$nextTick(); + + const moveButton = wrapper.find('[data-testid="move-license-to-tpm"]'); + + expect(moveButton.exists()).toBe(true); + expect(moveButton.attributes('disabled')).toBeDefined(); + }); + + it('does not trigger the TPM replacement action when the trial TPM button is clicked', async () => { + serverStore.state = 'TRIAL'; + serverStore.guid = '058F-6387-0000-0000F1F1E1C6'; + serverStore.flashGuid = '058F-6387-0000-0000F1F1E1C6'; + serverStore.tpmGuid = '03-V35H8S0L1QHK1SBG1XHXJNH7'; + serverStore.keyfile = 'keyfile-present'; + + await wrapper.vm.$nextTick(); + + await wrapper.find('[data-testid="move-license-to-tpm"]').trigger('click'); + + expect(accountStore.replaceTpm).not.toHaveBeenCalled(); }); it('does not show Move License to TPM after switching to TPM boot', async () => { diff --git a/web/src/components/Registration.standalone.vue b/web/src/components/Registration.standalone.vue index b5de772cc6..2796fc95e6 100644 --- a/web/src/components/Registration.standalone.vue +++ b/web/src/components/Registration.standalone.vue @@ -134,10 +134,9 @@ const showPartnerActivationCode = computed(() => { (currentState === 'ENOKEYFILE' || currentState === 'TRIAL' || currentState === 'EEXPIRED') ); }); -const showTpmTransferInfo = computed((): boolean => +const showTpmTransferButton = computed((): boolean => Boolean( - keyInstalled.value && - !showTrialExpiration.value && + (keyInstalled.value || showTrialExpiration.value) && bootDeviceType.value === 'flash' && // The active GUID tells us whether we're still booted from flash, even if // flashGuid is missing or has already fallen back to the TPM value. @@ -146,6 +145,7 @@ const showTpmTransferInfo = computed((): boolean => guid.value !== tpmGuid.value ) ); +const disableTpmTransferButton = computed((): boolean => showTrialExpiration.value); // Organize items into three sections const bootDeviceItems = computed((): RegistrationItemProps[] => { @@ -158,6 +158,14 @@ const bootDeviceItems = computed((): RegistrationItemProps[] => { }, ] : []), + ...(showTpmTransferButton.value && tpmGuid.value + ? [ + { + label: t('registration.tpmGuid'), + text: tpmGuid.value, + }, + ] + : []), ...(bootDeviceType.value ? [ { @@ -390,12 +398,19 @@ const actionItems = computed((): RegistrationItemProps[] => { >

{{ t('registration.actions') }}

+

+ {{ t('registration.moveLicenseToTpmTrialDisabled') }} +