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 @@ -82,4 +82,20 @@ export const commonStrings = createTranslator('CommonStrings', {
message: 'Removed {label}',
context: 'Announced when an option is removed. {label} is the name of the option',
},
moveUpLabel: {
message: 'Move up',
context: 'Label for the button that moves a resource up in the list. Not visible in the UI.',
},
moveDownLabel: {
message: 'Move down',
context: 'Label for the button that moves a resource down in the list. Not visible in the UI.',
},
moveLeftLabel: {
message: 'Move left',
context: 'Label for the button that moves a resource left in the list. Not visible in the UI.',
},
moveRightLabel: {
message: 'Move right',
context: 'Label for the button that moves a resource right in the list. Not visible in the UI.',
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,47 @@ describe('useChoiceInteraction', () => {
});
});

describe('setChoiceOrder()', () => {
it('applies the given order', () => {
const { state, setChoiceOrder } = setup([
makeAnswer({ id: 'a' }),
makeAnswer({ id: 'b' }),
makeAnswer({ id: 'c' }),
]);
setChoiceOrder(['c', 'a', 'b']);
expect(state.value.choices.map(a => a.id)).toEqual(['c', 'a', 'b']);
});

it('is a no-op when the given order is not a permutation of the current ids', () => {
const { state, setChoiceOrder } = setup([
makeAnswer({ id: 'a' }),
makeAnswer({ id: 'b' }),
makeAnswer({ id: 'c' }),
]);

setChoiceOrder(['c', 'a']);
expect(state.value.choices.map(a => a.id)).toEqual(['a', 'b', 'c']);

setChoiceOrder(['c', 'a', 'zzz']);
expect(state.value.choices.map(a => a.id)).toEqual(['a', 'b', 'c']);
});

it('produces the same bodyXml as moveChoiceUp for the equivalent move', () => {
const choices = [
makeAnswer({ id: 'a', content: 'A' }),
makeAnswer({ id: 'b', content: 'B' }),
makeAnswer({ id: 'c', content: 'C' }),
];
const viaChevron = setup(choices);
viaChevron.moveChoiceUp('c');

const viaDrag = setup(choices);
viaDrag.setChoiceOrder(['a', 'c', 'b']);

expect(viaDrag.bodyXml.value).toBe(viaChevron.bodyXml.value);
});
});

describe('toggleCorrectChoice()', () => {
it('singleSelect: sets only the target as correct and clears others', () => {
const { state, toggleCorrectChoice, questionTypeRef } = setup([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,37 @@ describe('useOrderingInteraction', () => {
});
});

describe('setItemOrder()', () => {
it('applies the given order', () => {
const { state, setItemOrder } = setup();
const [firstId, secondId, thirdId] = state.value.items.map(i => i.id);
setItemOrder([thirdId, firstId, secondId]);
expect(state.value.items.map(i => i.id)).toEqual([thirdId, firstId, secondId]);
});

it('is a no-op when the given order is not a permutation of the current ids', () => {
const { state, setItemOrder } = setup();
const [firstId, secondId, thirdId] = state.value.items.map(i => i.id);

setItemOrder([thirdId, firstId]);
expect(state.value.items.map(i => i.id)).toEqual([firstId, secondId, thirdId]);

setItemOrder([thirdId, firstId, 'order_zzzzzzzz']);
expect(state.value.items.map(i => i.id)).toEqual([firstId, secondId, thirdId]);
});

it('produces the same bodyXml as moveItemUp for the equivalent move', () => {
const viaChevron = setup();
const [firstId, secondId, thirdId] = viaChevron.state.value.items.map(i => i.id);
viaChevron.moveItemUp(secondId);

const viaDrag = setup();
viaDrag.setItemOrder([secondId, firstId, thirdId]);

expect(viaDrag.bodyXml.value).toBe(viaChevron.bodyXml.value);
});
});

describe('setItemContent()', () => {
it('updates only the targeted item content', () => {
const { state, setItemContent } = setup();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ export function useChoiceInteraction(interactionBlock, questionType) {
state.value = { ...state.value, choices };
}

/** Apply a permutation of the current choice ids; anything else is ignored. */
function setChoiceOrder(orderedIds) {
const byId = new Map(state.value.choices.map(c => [c.id, c]));
const choices = [...new Set(orderedIds)].map(id => byId.get(id));
if (choices.length !== byId.size || choices.includes(undefined)) return;
state.value = { ...state.value, choices };
}

/**
* Toggle the correct flag for a single choice.
*
Expand Down Expand Up @@ -98,6 +106,7 @@ export function useChoiceInteraction(interactionBlock, questionType) {
removeChoice,
moveChoiceUp,
moveChoiceDown,
setChoiceOrder,
toggleCorrectChoice,
setPrompt,
setChoiceContent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ export function useOrderingInteraction(interactionBlock, questionType) {
state.value = { ...state.value, items };
}

/** Apply a permutation of the current item ids; anything else is ignored. */
function setItemOrder(orderedIds) {
const byId = new Map(state.value.items.map(item => [item.id, item]));
const items = [...new Set(orderedIds)].map(id => byId.get(id));
if (items.length !== byId.size || items.includes(undefined)) return;
state.value = { ...state.value, items };
}

function setItemContent(id, html) {
state.value = {
...state.value,
Expand All @@ -62,6 +70,7 @@ export function useOrderingInteraction(interactionBlock, questionType) {
removeItem,
moveItemUp,
moveItemDown,
setItemOrder,
setItemContent,
setPrompt,
};
Expand Down
Loading
Loading