diff --git a/tests/unit/components/Form/CheckboxGroup.CheckboxItem.integration.spec.js b/tests/integration/CheckboxGroup.CheckboxItem.integration.spec.js
similarity index 93%
rename from tests/unit/components/Form/CheckboxGroup.CheckboxItem.integration.spec.js
rename to tests/integration/CheckboxGroup.CheckboxItem.integration.spec.js
index 5339f7992..a6b15419f 100644
--- a/tests/unit/components/Form/CheckboxGroup.CheckboxItem.integration.spec.js
+++ b/tests/integration/CheckboxGroup.CheckboxItem.integration.spec.js
@@ -32,8 +32,8 @@ xdescribe('components/Form/CheckboxGroup and components/Form/CheckboxItem integr
checkboxes = subject.findAll('input[type=checkbox]');
});
- xdescribe('binding to `inputValue`', () => {
- xdescribe('when `inputValue` changes', () => {
+ describe('binding to `inputValue`', () => {
+ describe('when `inputValue` changes', () => {
it('the selected checkbox inputs change to match', () => {
const [optionOne, optionTwo] = checkboxes.wrappers.map(wrapper => wrapper.element);
@@ -59,7 +59,7 @@ xdescribe('components/Form/CheckboxGroup and components/Form/CheckboxItem integr
});
});
- xdescribe('when a checkbox input is checked', () => {
+ describe('when a checkbox input is checked', () => {
it('it emits an `input` event with an array containing the values of the checked inputs', () => {
subject.setProps({ value: [] });
const [optionOne, optionTwo] = checkboxes.wrappers;
@@ -80,7 +80,7 @@ xdescribe('components/Form/CheckboxGroup and components/Form/CheckboxItem integr
});
});
- xdescribe('CheckboxItem element IDs', () => {
+ describe('CheckboxItem element IDs', () => {
it('checkbox input IDs are unique', () => {
const [checkboxOne, checkboxTwo] = checkboxes.wrappers;
expect(checkboxOne.attributes('id')).not.toEqual(checkboxTwo.attributes('id'));
diff --git a/tests/unit/components/Form/RadioGroup.RadioItem.integration.spec.js b/tests/integration/RadioGroup.RadioItem.integration.spec.js
similarity index 92%
rename from tests/unit/components/Form/RadioGroup.RadioItem.integration.spec.js
rename to tests/integration/RadioGroup.RadioItem.integration.spec.js
index 3edc18ef5..f2331aeea 100644
--- a/tests/unit/components/Form/RadioGroup.RadioItem.integration.spec.js
+++ b/tests/integration/RadioGroup.RadioItem.integration.spec.js
@@ -32,8 +32,8 @@ xdescribe('components/Form/RadioGroup and components/Form/RadioItem integration'
radios = subject.findAll('input[type=radio]');
});
- xdescribe('binding to `inputValue`', () => {
- xdescribe('when `inputValue` changes', () => {
+ describe('binding to `inputValue`', () => {
+ describe('when `inputValue` changes', () => {
it('the selected radio input changes to match', () => {
const [optionOne, optionTwo] = radios.wrappers.map(wrapper => wrapper.element);
@@ -51,7 +51,7 @@ xdescribe('components/Form/RadioGroup and components/Form/RadioItem integration'
});
});
- xdescribe('when a radio input is checked', () => {
+ describe('when a radio input is checked', () => {
it('it emits an `input` event with the value of the checked radio', () => {
const [optionOne, optionTwo] = radios.wrappers;
@@ -69,7 +69,7 @@ xdescribe('components/Form/RadioGroup and components/Form/RadioItem integration'
});
});
- xdescribe('RadioItem element IDs', () => {
+ describe('RadioItem element IDs', () => {
it('radio input IDs are unique', () => {
const [radioOne, radioTwo] = radios.wrappers;
expect(radioOne.attributes('id')).not.toEqual(radioTwo.attributes('id'));
@@ -81,7 +81,7 @@ xdescribe('components/Form/RadioGroup and components/Form/RadioItem integration'
});
});
- xdescribe('radio inputs `name` attribute', () => {
+ describe('radio inputs `name` attribute', () => {
let nameOne, nameTwo;
beforeEach(() => {
[nameOne, nameTwo] = radios.wrappers.map(radio => radio.attributes('name'));
diff --git a/tests/unit/components/DownloadLink.spec.js b/tests/unit/components/DownloadLink.spec.js
new file mode 100644
index 000000000..74376b912
--- /dev/null
+++ b/tests/unit/components/DownloadLink.spec.js
@@ -0,0 +1,180 @@
+import { createTestSubject } from '../helpers';
+
+const mockGetDownloadURL = jest.fn()
+ .mockName('getDownloadURL');
+const mockRef = jest.fn()
+ .mockName('ref')
+ .mockReturnValue({
+ getDownloadURL: mockGetDownloadURL,
+ });
+
+jest.mock('@firebase/app', () => ({
+ __esModule: true,
+ default: {
+ apps: [],
+ initializeApp: () => {},
+ auth: jest.fn(),
+ storage: jest.fn()
+ .mockImplementation(() => ({
+ ref: mockRef,
+ })),
+ },
+ })
+);
+
+jest.mock('@firebase/storage', () => ({
+ __esModule: true,
+ default: {
+ registerService: jest.fn(), // required by firebase/app
+ },
+}));
+
+import '@firebase/app';
+import '@firebase/storage';
+
+import DownloadLink from '@/components/DownloadLink';
+
+describe('components/DownloadLink', () => {
+ let wrapper;
+ const mockProps = {
+ exerciseId: 'mock_id',
+ title: 'mock title',
+ fileName: 'mock_name',
+ };
+
+ beforeEach(() => {
+ wrapper = createTestSubject(DownloadLink, {
+ mocks: {},
+ stubs: [],
+ propsData: mockProps,
+ });
+ });
+
+ it('renders the component', () => {
+ expect(wrapper.exists()).toBe(true);
+ });
+
+ describe('lifecycle hooks', () => {
+ xdescribe('mounted', () => {
+ // const localVue = createLocalVue();
+ const mockGetDownloadURL = jest.fn()
+ .mockName('getDownloadURL');
+
+ const mockHref = 'mock href';
+
+ it('should call .getDownloadURL()', () => {
+ createTestSubject(DownloadLink, {
+ propsData: mockProps,
+ stubs: [],
+ mocks: {
+ getDownloadURL: mockGetDownloadURL,
+ },
+ });
+
+ expect(mockGetDownloadURL).toHaveBeenCalled();
+ });
+
+ it('should set linkHref if .getDownloadURL() returned download url', async () => {
+ expect.assertions(1);
+
+ const wrapper = createTestSubject(DownloadLink, {
+ mocks: {
+ getDownloadURL: mockGetDownloadURL
+ .mockReturnValue(mockHref),
+ },
+ stubs: [],
+ propsData: mockProps,
+ });
+
+ await wrapper.vm.$nextTick();
+ expect(wrapper.vm.linkHref).toEqual(mockHref);
+ });
+
+ it('should not set linkHref if .getDownloadURL() failed', async () => {
+ expect.assertions(1);
+
+ const wrapper = createTestSubject(DownloadLink, {
+ mocks: {
+ getDownloadURL: mockGetDownloadURL
+ .mockReturnValue(false),
+ },
+ stubs: [],
+ propsData: mockProps,
+ });
+
+ await wrapper.vm.$nextTick();
+ expect(wrapper.vm.linkHref).toBeEmpty();
+ });
+ });
+ });
+
+ describe('methods', () => {
+
+ xdescribe('getDownloadURL()', () => {
+ it('returns false if filename not set', async () => {
+ expect.assertions(1);
+
+ const result = await wrapper.vm.getDownloadURL();
+
+ expect(result).toBe(false);
+ });
+
+ describe('with filename', () => {
+ const mockFileName = 'mock file name';
+ const mockHref = 'mock href';
+
+ beforeEach(() => {
+ wrapper.setProps({
+ fileName: mockFileName,
+ });
+ });
+
+ it('calls storage().ref()', async () => {
+ expect.assertions(1);
+
+ await wrapper.vm.getDownloadURL();
+
+ expect(mockRef).toHaveBeenCalled();
+ });
+
+ it('calls fileRef.getDownloadURL()', async () => {
+ expect.assertions(1);
+
+ await wrapper.vm.getDownloadURL();
+
+ expect(mockGetDownloadURL).toHaveBeenCalled();
+ });
+
+ it('returns download url if fileRef.getDownloadURL() returned a valid response', async () => {
+ expect.assertions(1);
+
+ mockGetDownloadURL.mockReturnValue(mockHref);
+
+ const result = await wrapper.vm.getDownloadURL();
+
+ expect(result).toBe(mockHref);
+ });
+
+ it('returns false if fileRef.getDownloadURL() returned invalid response', async () => {
+ expect.assertions(1);
+
+ mockGetDownloadURL.mockReturnValue(null);
+
+ const result = await wrapper.vm.getDownloadURL();
+
+ expect(result).toBe(false);
+ });
+
+ it('returns false if fileRef.getDownloadURL() threw', async () => {
+ expect.assertions(1);
+ mockGetDownloadURL.mockImplementation(() => {
+ throw new Error('Error');
+ });
+ const result = await wrapper.vm.getDownloadURL();
+ expect(result).toBe(false);
+ });
+ });
+ });
+ });
+});
+
diff --git a/tests/unit/components/Form/CheckboxGroup.spec.js b/tests/unit/components/Form/CheckboxGroup.spec.js
index 7368b0d62..90d6ff392 100644
--- a/tests/unit/components/Form/CheckboxGroup.spec.js
+++ b/tests/unit/components/Form/CheckboxGroup.spec.js
@@ -1,77 +1,15 @@
-import { shallowMount } from '@vue/test-utils';
+import { createTestSubject } from '../../helpers';
import CheckboxGroup from '@/components/Form/CheckboxGroup';
-const createTestSubject = (propsData) => {
- return shallowMount(CheckboxGroup, {
- propsData: {
- label: 'Example question',
- id: 'example',
- value: ['selected-checkbox-value'],
- ...propsData,
- },
- slots: {
- default: ['CheckboxItem components'],
- },
- });
-};
+describe('components/Form/CheckboxGroup', () => {
-xdescribe('components/Form/CheckboxGroup', () => {
it('component name is "CheckboxGroup"', () => {
expect(CheckboxGroup.name).toBe('CheckboxGroup');
});
- xdescribe('properties', () => {
+ describe('props', () => {
let prop;
- /*
- ** @todo these are now part of `FormField`, which this component extends.
- ** Therefore we could test here that this component extends FormField
- ** and move these prop tests to FormField.spec.js instead
- */
- // xdescribe('label', () => {
- // beforeEach(() => {
- // prop = CheckboxGroup.props.label;
- // });
-
- // it('is optional', () => {
- // expect(prop.required).not.toBe(true);
- // expect(prop.default).toBe('');
- // });
-
- // it('must be a String', () => {
- // expect(prop.type).toBe(String);
- // });
- // });
-
- // xdescribe('hint', () => {
- // beforeEach(() => {
- // prop = CheckboxGroup.props.hint;
- // });
-
- // it('is optional', () => {
- // expect(prop.required).not.toBe(true);
- // expect(prop.default).toBe('');
- // });
-
- // it('must be a String', () => {
- // expect(prop.type).toBe(String);
- // });
- // });
-
- // xdescribe('id', () => {
- // beforeEach(() => {
- // prop = CheckboxGroup.props.id;
- // });
-
- // it('is required', () => {
- // expect(prop.required).toBe(true);
- // });
-
- // it('must be a String', () => {
- // expect(prop.type).toBe(String);
- // });
- // });
-
- xdescribe('value', () => {
+ describe('value', () => {
beforeEach(() => {
prop = CheckboxGroup.props.value;
});
@@ -107,31 +45,48 @@ xdescribe('components/Form/CheckboxGroup', () => {
expect(valid).toBe(false);
});
});
+
});
- xdescribe('`v-model` interface', () => {
- let subject;
+ describe('component functions', () => {
+ let wrapper;
+ const inputMock = jest.fn();
beforeEach(() => {
- subject = createTestSubject();
- });
+ wrapper = createTestSubject(CheckboxGroup, {
+ mocks: {
+ emitted: {
+ input: inputMock,
+ },
+ },
+ stubs: [],
+ propsData: {
+ value: ['selected-checkbox-value'],
+ id: '',
+ },
+ });
+ });
+
+ describe('`v-model` interface', () => {
+ it('renders successfully', () => {
+ expect(wrapper.exists()).toBeTrue();
+ });
- xdescribe('when the `value` property changes', () => {
+ describe('when the `value` property changes', () => {
it('updates computed property `inputValue`', () => {
- expect(subject.vm.inputValue).toEqual(['selected-checkbox-value']);
- subject.setProps({
+ wrapper.setProps({
value: ['some-other-value'],
});
- expect(subject.vm.inputValue).toEqual(['some-other-value']);
+ expect(wrapper.vm.inputValue).toEqual(['some-other-value']);
});
});
- xdescribe('when computed property `inputValue` changes', () => {
+ describe('when computed property `inputValue` changes', () => {
it('emits an `input` event', () => {
- subject.setData({
+ wrapper.setData({
inputValue: ['some-new-value'],
});
- const emitted = subject.emitted().input;
+ const emitted = wrapper.emitted().input;
expect(emitted).toBeArrayOfSize(1);
expect(emitted[0][0]).toEqual(['some-new-value']);
@@ -139,148 +94,23 @@ xdescribe('components/Form/CheckboxGroup', () => {
});
});
- xdescribe('template', () => {
- let subject;
-
- it('the root element has the `id` attribute which was passed in as prop `id`', () => {
- subject = createTestSubject();
- expect(subject.is('#example')).toBe(true);
- });
-
- xdescribe('