diff --git a/ui/src/components/view/InfoCard.vue b/ui/src/components/view/InfoCard.vue
index 0031d730f569..e37c8af3d6e5 100644
--- a/ui/src/components/view/InfoCard.vue
+++ b/ui/src/components/view/InfoCard.vue
@@ -370,7 +370,7 @@
{{ $t('label.disksize') }}
-
{{ (resource.volumes.reduce((total, item) => total += item.size, 0) / (1024 * 1024 * 1024.0)).toFixed(2) }} GB Storage
+
{{ (resource.volumes.reduce((total, item) => total += item.size, 0) / (1024 * 1024 * 1024.0)).toFixed(2) }} GiB Storage
{{ $bytesToHumanReadableSize(resource.size) }}
diff --git a/ui/tests/unit/components/view/DetailsTab.spec.js b/ui/tests/unit/components/view/DetailsTab.spec.js
new file mode 100644
index 000000000000..19e531d6f586
--- /dev/null
+++ b/ui/tests/unit/components/view/DetailsTab.spec.js
@@ -0,0 +1,67 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import { flushPromises } from '@vue/test-utils'
+
+import common from '../../../common'
+import DetailsTab from '@/components/view/DetailsTab.vue'
+
+const i18n = common.createMockI18n('en')
+
+describe('Components > View > DetailsTab.vue', () => {
+ beforeEach(() => {
+ jest.spyOn(console, 'warn').mockImplementation(() => {})
+ })
+
+ afterEach(() => {
+ jest.restoreAllMocks()
+ })
+
+ it('displays backup volume sizes in GiB when the API provides bytes', async () => {
+ const router = common.createMockRouter([{
+ path: '/backup/:id',
+ name: 'backup',
+ meta: { name: 'backup', details: ['volumes'] },
+ component: { template: '' }
+ }])
+ await router.push('/backup/backup-1')
+ await router.isReady()
+
+ const wrapper = common.createFactory(DetailsTab, {
+ router,
+ i18n,
+ props: {
+ resource: {
+ volumes: JSON.stringify([{
+ uuid: 'volume-1',
+ type: 'ROOT',
+ path: 'root.qcow2',
+ size: 2 * 1024 * 1024 * 1024
+ }]),
+ vmbackupofferingremoved: true
+ }
+ }
+ })
+
+ await flushPromises()
+
+ expect(wrapper.text()).toContain('2.0 GiB')
+ expect(wrapper.text()).not.toContain('2.0 GB')
+
+ wrapper.unmount()
+ })
+})
diff --git a/ui/tests/unit/components/view/InfoCard.spec.js b/ui/tests/unit/components/view/InfoCard.spec.js
new file mode 100644
index 000000000000..9f09dc705a9c
--- /dev/null
+++ b/ui/tests/unit/components/view/InfoCard.spec.js
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import { flushPromises } from '@vue/test-utils'
+
+import common from '../../../common'
+import InfoCard from '@/components/view/InfoCard.vue'
+
+const i18n = common.createMockI18n('en')
+
+describe('Components > View > InfoCard.vue', () => {
+ beforeEach(() => {
+ jest.spyOn(console, 'warn').mockImplementation(() => {})
+ })
+
+ afterEach(() => {
+ jest.restoreAllMocks()
+ })
+
+ it('displays VM volume totals in GiB when the API provides bytes', async () => {
+ const router = common.createMockRouter([{
+ path: '/vm/:id',
+ name: 'vm',
+ meta: { name: 'vm' },
+ component: { template: '' }
+ }])
+ await router.push('/vm/vm-1')
+ await router.isReady()
+
+ const wrapper = common.createFactory(InfoCard, {
+ router,
+ i18n,
+ store: common.createMockStore({ user: { apis: {} } }),
+ props: {
+ resource: {
+ name: 'test-vm',
+ vmtype: 'UserVm',
+ volumes: [{ size: 2 * 1024 * 1024 * 1024 }]
+ }
+ }
+ })
+
+ await flushPromises()
+
+ expect(wrapper.text()).toContain('2.00 GiB Storage')
+ expect(wrapper.text()).not.toContain('2.00 GB Storage')
+
+ wrapper.unmount()
+ })
+})