diff --git a/apps/wallet/src/components/change-canister/AdvancedUpdateMode.spec.ts b/apps/wallet/src/components/change-canister/AdvancedUpdateMode.spec.ts new file mode 100644 index 000000000..ac56b961e --- /dev/null +++ b/apps/wallet/src/components/change-canister/AdvancedUpdateMode.spec.ts @@ -0,0 +1,51 @@ +import { VueWrapper } from '@vue/test-utils'; +import { describe, expect, it } from 'vitest'; +import { ChangeCanisterFormValue } from '~/components/change-canister/change-canister.types'; +import { mount } from '~/test.utils'; +import { ChangeCanisterTargetType } from '~/types/station.types'; +import AdvancedUpdateMode from './AdvancedUpdateMode.vue'; + +describe('AdvancedUpdateMode', () => { + it('renders with empty form', () => { + const wrapper = mount(AdvancedUpdateMode, { + props: { + modelValue: { + wasmInitArg: undefined, + target: undefined, + wasmModule: undefined, + }, + }, + }); + + expect(wrapper.exists()).toBe(true); + expect(wrapper.find('[name="target"]').exists()).toBe(true); + expect(wrapper.find('[name="arg"]').exists()).toBe(true); + expect(wrapper.find('[name="wasm"]').exists()).toBe(true); + }); + + it('when target type changes the modelValue picks up the change', async () => { + const wrapper = mount(AdvancedUpdateMode, { + props: { + modelValue: { + wasmInitArg: undefined, + target: undefined, + wasmModule: undefined, + }, + }, + }) as unknown as VueWrapper< + InstanceType & { upgradeTarget: ChangeCanisterTargetType } + >; + + // picks up the change to upgrade station + wrapper.vm.upgradeTarget = ChangeCanisterTargetType.UpgradeStation; + await wrapper.vm.$nextTick(); + const modelValue = wrapper.emitted('update:modelValue')?.[0]?.[0] as ChangeCanisterFormValue; + expect(modelValue.target).toEqual({ UpgradeStation: null }); + + // picks up the change to upgrade upgrader + wrapper.vm.upgradeTarget = ChangeCanisterTargetType.UpgradeUpgrader; + await wrapper.vm.$nextTick(); + const modelValue2 = wrapper.emitted('update:modelValue')?.[1]?.[0] as ChangeCanisterFormValue; + expect(modelValue2.target).toEqual({ UpgradeUpgrader: null }); + }); +}); diff --git a/apps/wallet/src/components/change-canister/ChangeCanisterConfirmationScreen.spec.ts b/apps/wallet/src/components/change-canister/ChangeCanisterConfirmationScreen.spec.ts new file mode 100644 index 000000000..b4e379dec --- /dev/null +++ b/apps/wallet/src/components/change-canister/ChangeCanisterConfirmationScreen.spec.ts @@ -0,0 +1,47 @@ +import { describe, expect, it } from 'vitest'; +import { mount } from '~/test.utils'; +import ChangeCanisterConfirmationScreen from './ChangeCanisterConfirmationScreen.vue'; + +describe('ChangeCanisterConfirmationScreen', () => { + it('confirmation screen has checksum and comment fields', () => { + const wrapper = mount(ChangeCanisterConfirmationScreen, { + props: { + wasmModuleChecksum: 'checksum', + comment: 'My test comment', + }, + }); + + expect(wrapper.exists()).toBe(true); + expect(wrapper.find('[name="wasm_checksum"]').exists()).toBe(true); + expect(wrapper.find('[name="comment"]').exists()).toBe(true); + }); + + it('confirmation screen shows the checksum in the field in readonly mode', () => { + const wrapper = mount(ChangeCanisterConfirmationScreen, { + props: { + wasmModuleChecksum: 'checksum', + }, + }); + + expect(wrapper.exists()).toBe(true); + + const field = wrapper.find('[name="wasm_checksum"]').element as HTMLInputElement; + expect(field.value).toEqual('checksum'); + expect(field.readOnly).toBe(true); + }); + + it('confirmation screen shows the comment in the field in edit mode', () => { + const wrapper = mount(ChangeCanisterConfirmationScreen, { + props: { + wasmModuleChecksum: 'checksum', + comment: 'My test comment', + }, + }); + + expect(wrapper.exists()).toBe(true); + + const field = wrapper.find('[name="comment"]').element as HTMLInputElement; + expect(field.value).toEqual('My test comment'); + expect(field.readOnly).toBe(false); + }); +}); diff --git a/apps/wallet/src/components/change-canister/ChangeCanisterConfirmationScreen.vue b/apps/wallet/src/components/change-canister/ChangeCanisterConfirmationScreen.vue index 6d674f54e..87c7f0724 100644 --- a/apps/wallet/src/components/change-canister/ChangeCanisterConfirmationScreen.vue +++ b/apps/wallet/src/components/change-canister/ChangeCanisterConfirmationScreen.vue @@ -11,7 +11,7 @@ { + it('on mount triggers the check for new updates', () => { + const pinia = mockPinia({ activate: true }); + const station = useStationStore(); + vi.spyOn(station, 'checkVersionUpdates').mockImplementation(() => Promise.resolve()); + + const wrapper = mount( + RegistryUpdateMode, + { props: { modelValue: {} } }, + { plugins: { pinia } }, + ); + + expect(wrapper.exists()).toBe(true); + expect(station.checkVersionUpdates).toHaveBeenCalled(); + }); + + it('shows already in latest version screen', () => { + const pinia = mockPinia({ + activate: true, + initialState: { + station: { + versionManagement: { + loading: false, + nextStationVersion: undefined, + nextUpgraderVersion: undefined, + }, + }, + }, + }); + + const station = useStationStore(); + vi.spyOn(station, 'checkVersionUpdates').mockImplementation(() => Promise.resolve()); + + const wrapper = mount( + RegistryUpdateMode, + { props: { modelValue: {} } }, + { plugins: { pinia } }, + ); + + expect(wrapper.find('[data-test-id="latest-screen"]').exists()).toBe(true); + }); + + it('shows update available screen', () => { + const pinia = mockPinia({ + activate: true, + initialState: { + station: { + versionManagement: { + loading: false, + nextStationVersion: '1.2.3', + nextUpgraderVersion: '1.2.3', + }, + }, + }, + }); + + const station = useStationStore(); + vi.spyOn(station, 'checkVersionUpdates').mockImplementation(() => Promise.resolve()); + + const wrapper = mount( + RegistryUpdateMode, + { props: { modelValue: {} } }, + { plugins: { pinia } }, + ); + + expect(wrapper.find('[data-test-id="update-available-screen"]').exists()).toBe(true); + }); + + it('shows loading screen while version updates is in progress', () => { + const pinia = mockPinia({ + activate: true, + initialState: { + station: { + versionManagement: { + loading: true, + }, + }, + }, + }); + + const station = useStationStore(); + vi.spyOn(station, 'checkVersionUpdates').mockImplementation(() => Promise.resolve()); + + const wrapper = mount( + RegistryUpdateMode, + { props: { modelValue: {} } }, + { plugins: { pinia } }, + ); + + expect(station.checkVersionUpdates).not.toHaveBeenCalled(); + expect(wrapper.find('[data-test-id="loading-screen"]').exists()).toBe(true); + }); +}); diff --git a/apps/wallet/src/components/change-canister/RegistryUpdateMode.vue b/apps/wallet/src/components/change-canister/RegistryUpdateMode.vue index 0eb4f3c0f..d85a80353 100644 --- a/apps/wallet/src/components/change-canister/RegistryUpdateMode.vue +++ b/apps/wallet/src/components/change-canister/RegistryUpdateMode.vue @@ -3,16 +3,18 @@ {{ $t('app.update_recommended_latest') }} -

+

{{ $t('app.checking_for_updates') }}

-

+

{{ $t('app.update_already_latest_version') }}

-

{{ $t('app.update_available') }}

+

+ {{ $t('app.update_available') }} +