Skip to content

Commit

Permalink
[FEATURE] Avoir les blocs réponses en vert ou rouge sur les QCM (PIX-…
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Aug 16, 2024
2 parents 01c46a4 + 3e309d0 commit f30ef21
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 128 deletions.
125 changes: 125 additions & 0 deletions mon-pix/app/components/module/element/qcm.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import PixButton from '@1024pix/pix-ui/components/pix-button';
import PixCheckbox from '@1024pix/pix-ui/components/pix-checkbox';
import PixMessage from '@1024pix/pix-ui/components/pix-message';
import { fn } from '@ember/helper';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import { t } from 'ember-intl';
import ModulixFeedback from 'mon-pix/components/modulix/feedback';

import { htmlUnsafe } from '../../../helpers/html-unsafe';
import ModuleElement from './module-element';

export default class ModuleQcm extends ModuleElement {
selectedAnswerIds = new Set();

get canValidateElement() {
return this.selectedAnswerIds.size >= 2;
}

get userResponse() {
return [...this.selectedAnswerIds];
}

get disableInput() {
return super.disableInput ? true : null;
}

resetAnswers() {
this.selectedAnswerIds = new Set();
}

@action
checkboxSelected(proposalId) {
if (this.selectedAnswerIds.has(proposalId)) {
this.selectedAnswerIds.delete(proposalId);
} else {
this.selectedAnswerIds.add(proposalId);
}
}

@action
getProposalState(proposalId) {
if (!this.correction) {
return null;
}

if (!this.selectedAnswerIds.has(proposalId)) {
return 'neutral';
}

return this.correction.solution.includes(proposalId) ? 'success' : 'error';
}

<template>
<form class="element-qcm" aria-describedby="instruction-{{this.element.id}}">
<fieldset>
<legend class="screen-reader-only">
{{t "pages.modulix.qcm.direction"}}
</legend>

<div class="element-qcm__instruction" id="instruction-{{this.element.id}}">
{{htmlUnsafe this.element.instruction}}
</div>

<p class="element-qcm__direction" aria-hidden="true">
{{t "pages.modulix.qcm.direction"}}
</p>

<div class="element-qcm__proposals">
{{#each this.element.proposals as |proposal|}}
<PixCheckbox
name={{this.element.id}}
@isDisabled={{this.disableInput}}
@state={{this.getProposalState proposal.id}}
@variant="tile"
{{on "click" (fn this.checkboxSelected proposal.id)}}
>
<:label>{{proposal.content}}</:label>
</PixCheckbox>
{{/each}}
</div>
</fieldset>

{{#if this.shouldDisplayRequiredMessage}}
<div class="element-qcm__required-field-missing">
<PixMessage role="alert" @type="error" @withIcon={{true}}>
{{t "pages.modulix.verification-precondition-failed-alert.qcm"}}
</PixMessage>
</div>
{{/if}}

{{#unless this.correction}}
<PixButton
@variant="success"
@type="submit"
class="element-qcm__verify-button"
@triggerAction={{this.onAnswer}}
>
{{t "pages.modulix.buttons.activity.verify"}}
</PixButton>
{{/unless}}

<div class="element-qcm__feedback" role="status" tabindex="-1">
{{#if this.shouldDisplayFeedback}}
<ModulixFeedback @answerIsValid={{this.answerIsValid}}>
{{htmlUnsafe this.correction.feedback}}
</ModulixFeedback>
{{/if}}
</div>

{{#if this.shouldDisplayRetryButton}}
<PixButton
class="element-qcm__retry-button"
@variant="secondary"
@size="small"
@type="button"
@triggerAction={{this.retry}}
@iconAfter="rotate-right"
>
{{t "pages.modulix.buttons.activity.retry"}}
</PixButton>
{{/if}}
</form>
</template>
}
63 changes: 0 additions & 63 deletions mon-pix/app/components/module/element/qcm.hbs

This file was deleted.

31 changes: 0 additions & 31 deletions mon-pix/app/components/module/element/qcm.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { render } from '@1024pix/ember-testing-library';
// eslint-disable-next-line no-restricted-imports
import { click, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import ModulixQcm from 'mon-pix/components/module/element/qcm';
import { module, test } from 'qunit';
import sinon from 'sinon';

Expand All @@ -21,8 +21,7 @@ module('Integration | Component | Module | QCM', function (hooks) {
],
type: 'qcm',
};
this.set('el', qcmElement);
const screen = await render(hbs`<Module::Element::Qcm @element={{this.el}} />`);
const screen = await render(<template><ModulixQcm @element={{qcmElement}} /></template>);

// then
assert.ok(screen);
Expand Down Expand Up @@ -59,11 +58,9 @@ module('Integration | Component | Module | QCM', function (hooks) {
],
type: 'qcm',
};
this.set('el', qcmElement);
const userResponse = [answeredProposal[0].id, answeredProposal[1].id];
const givenonElementAnswerSpy = sinon.spy();
this.set('onAnswer', givenonElementAnswerSpy);
const screen = await render(hbs`<Module::Element::Qcm @element={{this.el}} @onAnswer={{this.onAnswer}} />`);
const onAnswerSpy = sinon.spy();
const screen = await render(<template><ModulixQcm @element={{qcmElement}} @onAnswer={{onAnswerSpy}} /></template>);
const verifyButton = screen.queryByRole('button', { name: 'Vérifier' });

// when
Expand All @@ -72,7 +69,7 @@ module('Integration | Component | Module | QCM', function (hooks) {
await click(verifyButton);

// then
sinon.assert.calledWith(givenonElementAnswerSpy, { userResponse, element: qcmElement });
sinon.assert.calledWith(onAnswerSpy, { userResponse, element: qcmElement });
assert.ok(true);
});

Expand All @@ -88,18 +85,16 @@ module('Integration | Component | Module | QCM', function (hooks) {
],
type: 'qcm',
};
const onElementAnswerSpy = sinon.spy();
this.set('el', qcmElement);
this.set('onAnswer', onElementAnswerSpy);
const screen = await render(hbs`<Module::Element::Qcm @element={{this.el}} @onAnswer={{this.onAnswer}} />`);
const onAnswerSpy = sinon.spy();
const screen = await render(<template><ModulixQcm @element={{qcmElement}} @onAnswer={{onAnswerSpy}} /></template>);

// when
await click(screen.getByLabelText('checkbox1'));
await click(screen.queryByRole('button', { name: 'Vérifier' }));

// then
assert.dom(screen.getByRole('alert')).exists();
sinon.assert.notCalled(onElementAnswerSpy);
sinon.assert.notCalled(onAnswerSpy);
});

test('should hide the error message when QCM is validated with response', async function (assert) {
Expand All @@ -114,10 +109,8 @@ module('Integration | Component | Module | QCM', function (hooks) {
],
type: 'qcm',
};
const givenonElementAnswerStub = function () {};
this.set('onAnswer', givenonElementAnswerStub);
this.set('el', qcmElement);
const screen = await render(hbs`<Module::Element::Qcm @element={{this.el}} @onAnswer={{this.onAnswer}} />`);
const onAnswerSpy = sinon.spy();
const screen = await render(<template><ModulixQcm @element={{qcmElement}} @onAnswer={{onAnswerSpy}} /></template>);

// when
await click(screen.queryByRole('button', { name: 'Vérifier' }));
Expand All @@ -138,12 +131,14 @@ module('Integration | Component | Module | QCM', function (hooks) {
solution: ['1', '4'],
});

prepareContextRecords.call(this, store, correctionResponse);
this.set('onAnswer', () => {});
const { qcmElement } = prepareContextRecords.call(this, store, correctionResponse);
const onAnswerSpy = sinon.spy();

// when
const screen = await render(
hbs`<Module::Element::Qcm @element={{this.el}} @onAnswer={{this.onAnswer}} @correction={{this.correctionResponse}} />`,
<template>
<ModulixQcm @element={{qcmElement}} @onAnswer={{onAnswerSpy}} @correction={{correctionResponse}} />
</template>,
);

// then
Expand All @@ -164,12 +159,14 @@ module('Integration | Component | Module | QCM', function (hooks) {
solution: ['1', '4'],
});

prepareContextRecords.call(this, store, correctionResponse);
this.set('onAnswer', () => {});
const { qcmElement } = prepareContextRecords.call(this, store, correctionResponse);
const onAnswerSpy = sinon.spy();

// when
const screen = await render(
hbs`<Module::Element::Qcm @element={{this.el}} @onAnswer={{this.onAnswer}} @correction={{this.correctionResponse}} />`,
<template>
<ModulixQcm @element={{qcmElement}} @onAnswer={{onAnswerSpy}} @correction={{correctionResponse}} />
</template>,
);

// then
Expand All @@ -191,12 +188,14 @@ module('Integration | Component | Module | QCM', function (hooks) {
solution: 'solution',
});

prepareContextRecords.call(this, store, correctionResponse);
this.set('onAnswer', () => {});
const { qcmElement } = prepareContextRecords.call(this, store, correctionResponse);
const onAnswerSpy = sinon.spy();

// when
const screen = await render(
hbs`<Module::Element::Qcm @element={{this.el}} @onAnswer={{this.onAnswer}} @correction={{this.correctionResponse}} />`,
<template>
<ModulixQcm @element={{qcmElement}} @onAnswer={{onAnswerSpy}} @correction={{correctionResponse}} />
</template>,
);

// then
Expand All @@ -212,12 +211,14 @@ module('Integration | Component | Module | QCM', function (hooks) {
solution: 'solution',
});

prepareContextRecords.call(this, store, correctionResponse);
this.set('onAnswer', () => {});
const { qcmElement } = prepareContextRecords.call(this, store, correctionResponse);
const onAnswerSpy = sinon.spy();

// when
const screen = await render(
hbs`<Module::Element::Qcm @element={{this.el}} @onAnswer={{this.onAnswer}} @correction={{this.correctionResponse}} />`,
<template>
<ModulixQcm @element={{qcmElement}} @onAnswer={{onAnswerSpy}} @correction={{correctionResponse}} />
</template>,
);

// then
Expand All @@ -235,12 +236,14 @@ module('Integration | Component | Module | QCM', function (hooks) {
solution: 'solution',
});

prepareContextRecords.call(this, store, correctionResponse);
this.set('onAnswer', () => {});
const { qcmElement } = prepareContextRecords.call(this, store, correctionResponse);
const onAnswerSpy = sinon.spy();

// when
const screen = await render(
hbs`<Module::Element::Qcm @element={{this.el}} @onAnswer={{this.onAnswer}} @correction={{this.correctionResponse}} />`,
<template>
<ModulixQcm @element={{qcmElement}} @onAnswer={{onAnswerSpy}} @correction={{correctionResponse}} />
</template>,
);

// then
Expand Down Expand Up @@ -268,6 +271,5 @@ function prepareContextRecords(store, correctionResponse) {
correction: correctionResponse,
elementId: qcmElement.id,
});
this.set('el', qcmElement);
this.set('correctionResponse', correctionResponse);
return { qcmElement };
}

0 comments on commit f30ef21

Please sign in to comment.