Skip to content

Commit

Permalink
✨ (mon-pix): validate certification instructions confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreiaPena committed Jul 4, 2024
1 parent 1dfaab8 commit 6434b42
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 48 deletions.
19 changes: 13 additions & 6 deletions mon-pix/app/components/certification-instructions/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,27 @@ export default class Steps extends Component {
}

@action
nextStep() {
async nextStep() {
if (this.pageId < this.pageCount) {
this.pageId = this.pageId + 1;
}

if (this.isConfirmationCheckboxChecked) {
this.router.transitionTo('authenticated.certifications.start', this.args.candidateId, {
queryParams: {
isConfirmationCheckboxChecked: this.isConfirmationCheckboxChecked,
},
});
await this.submit();

this.router.transitionTo('authenticated.certifications.start', this.args.candidate.id);
}
}

@action
async submit() {
await this.args.candidate.save({
adapterOptions: {
hasSeenCertificationInstructions: true,
},
});
}

@action
enableNextButton(checked) {
this.isConfirmationCheckboxChecked = checked;
Expand Down
1 change: 1 addition & 0 deletions mon-pix/app/models/certification-candidate.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export default class CertificationCandidate extends Model {
@attr('string') firstName;
@attr('string') lastName;
@attr('date-only') birthdate;
@attr('boolean') hasSeenCertificationInstructions;

// references
@attr('number') sessionId;
Expand Down
14 changes: 8 additions & 6 deletions mon-pix/app/routes/authenticated/certifications/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ export default class StartRoute extends Route {
@service store;
@service router;
@service featureToggles;
hasSeenCertificationInstructions = false;

beforeModel(transition) {
this.hasSeenCertificationInstructions = transition.to.queryParams.isConfirmationCheckboxChecked;
}

async model(params) {
const certificationCandidateSubscription = await this.store.findRecord(
'certification-candidate-subscription',
params.certification_candidate_id,
);

const certificationCandidate = await this.store.peekRecord(
'certification-candidate',
params.certification_candidate_id,
);

const hasSeenCertificationInstructions = certificationCandidate?.hasSeenCertificationInstructions;

if (
!this.hasSeenCertificationInstructions &&
!hasSeenCertificationInstructions &&
certificationCandidateSubscription.isSessionVersion3 &&
this.featureToggles.featureToggles.areV3InfoScreensEnabled
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
<h1 class="instructions-header__title">{{t "pages.certification-instructions.title"}}</h1>
</header>
<PixBlock @shadow="heavy" class="instructions-step">
<CertificationInstructions::Steps @candidateId={{this.model.id}} />
<CertificationInstructions::Steps @candidate={{this.model}} />
</PixBlock>
</main>
6 changes: 6 additions & 0 deletions mon-pix/mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import putTutorialEvaluation from './routes/put-tutorial-evaluation';
import putUserSavedTutorial from './routes/put-user-saved-tutorial';
import loadScoOrganizationLearnersRoutes from './routes/sco-organization-learners/index';
import loadSupOrganizationLearnersRoutes from './routes/sup-organization-learners/index';
import updateCertificationCandidates from './routes/update-certification-candidates';
import loadUserRoutes from './routes/users/index';

export default function makeServer(config) {
Expand Down Expand Up @@ -108,4 +109,9 @@ function routes() {
this.get('/certification-courses/:id');

this.post('/feedbacks');

this.patch(
'/certification-candidates/:certificationCandidateId/validate-certification-instructions',
updateCertificationCandidates,
);
}
7 changes: 7 additions & 0 deletions mon-pix/mirage/routes/update-certification-candidates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function (schema, request) {
const certificationCandidateId = request.params.certificationCandidateId;
const certificationCandidate = schema.certificationCandidates.find(certificationCandidateId);
certificationCandidate.update({ hasSeenCertificationInstructions: true });

return certificationCandidate;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { visit } from '@1024pix/ember-testing-library';
import { currentURL } from '@ember/test-helpers';
import { click, currentURL } from '@ember/test-helpers';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { setupApplicationTest } from 'ember-qunit';
import { module, test } from 'qunit';
Expand All @@ -21,7 +21,7 @@ module('Acceptance | Certifications | Information', function (hooks) {

module('when certification candidate participates in a V3 session', function () {
module('when toggle areV3InfoScreensEnabled is enabled', function () {
test('should display the certification information page', async function (assert) {
test('should display the certification instructions page', async function (assert) {
// given
server.create('feature-toggle', {
id: 0,
Expand Down Expand Up @@ -56,6 +56,49 @@ module('Acceptance | Certifications | Information', function (hooks) {
assert.dom(screen.getByRole('heading', { name: 'Bienvenue à la certification Pix', level: 2 })).exists();
assert.dom(screen.getByRole('button', { name: "Continuer vers l'écran suivant" })).exists();
});

test('should validate checkbox and redirect to the certification start page', async function (assert) {
// given
server.create('feature-toggle', {
id: 0,
areV3InfoScreensEnabled: true,
});
server.create('certification-candidate-subscription', {
id: 2,
sessionId: 123,
eligibleSubscription: null,
nonEligibleSubscription: null,
sessionVersion: 3,
});

await authenticateByEmail(user);

const screen = await visit('/certifications');

// when
await fillCertificationJoiner({
sessionId: '123',
firstName: 'toto',
lastName: 'titi',
dayOfBirth: '01',
monthOfBirth: '01',
yearOfBirth: '2000',
intl: this.intl,
});
for (let i = 0; i < 4; i++) {
await click(screen.getByRole('button', { name: "Continuer vers l'écran suivant" }));
}

await click(
screen.getByRole('checkbox', {
name: 'En cochant cette case, je reconnais avoir pris connaissance de ces règles et je m’engage à les respecter.',
}),
);
await click(screen.getByRole('button', { name: "Continuer vers la page d'entrée en certification" }));

// then
assert.strictEqual(currentURL(), '/certifications/candidat/2');
});
});

module('when toggle areV3InfoScreensEnabled is not enabled', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,29 @@ module('Unit | Component | certification-instruction | steps', function (hooks)

module('when pageId equal pageCount', function () {
module('when confirmation checkbox is checked', function () {
test('should redirect to certificartion starter', async function (assert) {
test('should redirect to certification starter', async function (assert) {
// given
const component = createGlimmerComponent('certification-instructions/steps');

component.pageId = 2;
component.pageCount = 2;
component.args = {
candidateId: 123,
};
component.isConfirmationCheckboxChecked = true;
const transitionToStub = sinon.stub();
const saveStub = sinon.stub();
saveStub.resolves();
component.router = {
transitionTo: transitionToStub,
};
component.args.candidate = {
save: saveStub,
id: 123,
};

// when
await component.nextStep();

// then
assert.ok(
transitionToStub.calledWith('authenticated.certifications.start', 123, {
queryParams: {
isConfirmationCheckboxChecked: true,
},
}),
);
assert.ok(transitionToStub.calledWith('authenticated.certifications.start', 123));
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ module('Unit | Route | Certification | Start', function (hooks) {
module('when hasSeenCertificationInstructions is false', function () {
test('should redirect to certification information page', async function (assert) {
// given
const certificationCandidateId = 'certification-candidate-id';
const params = { certification_candidate_id: certificationCandidateId };
const store = this.owner.lookup('service:store');
const certificationCandidate = store.createRecord('certification-candidate', {
sessionId: 1234,
hasSeenCertificationInstructions: false,
});
const params = { certification_candidate_id: certificationCandidate.id };

const certificationCandidateSubscription = store.createRecord('certification-candidate-subscription', {
id: certificationCandidateId,
id: certificationCandidate.id,
sessionId: 1234,
sessionVersion: 3,
});
Expand All @@ -27,13 +30,13 @@ module('Unit | Route | Certification | Start', function (hooks) {
});

const findRecordStub = sinon.stub().returns(certificationCandidateSubscription);
const storeStub = Service.create({ findRecord: findRecordStub });
const peekRecordStub = sinon.stub().returns(certificationCandidate);
const storeStub = Service.create({ findRecord: findRecordStub, peekRecord: peekRecordStub });

const route = this.owner.lookup('route:authenticated/certifications.start');
route.set('store', storeStub);
route.set('featureToggles', featureToggles);
route.router = { replaceWith: sinon.stub() };
route.hasSeenCertificationInstructions = false;

// when
await route.model(params);
Expand All @@ -42,7 +45,7 @@ module('Unit | Route | Certification | Start', function (hooks) {
sinon.assert.calledWithExactly(
route.router.replaceWith,
'authenticated.certifications.information',
certificationCandidateId,
certificationCandidate.id,
);
assert.ok(true);
});
Expand All @@ -51,12 +54,15 @@ module('Unit | Route | Certification | Start', function (hooks) {
module('when hasSeenCertificationInstructions is true', function () {
test('should not redirect to certification information page', async function (assert) {
// given
const certificationCandidateId = 'certification-candidate-id';
const params = { certification_candidate_id: certificationCandidateId };
const store = this.owner.lookup('service:store');
const certificationCandidate = store.createRecord('certification-candidate', {
sessionId: 1234,
hasSeenCertificationInstructions: true,
});
const params = { certification_candidate_id: certificationCandidate.id };

const certificationCandidateSubscription = store.createRecord('certification-candidate-subscription', {
id: certificationCandidateId,
id: certificationCandidate.id,
sessionId: 1234,
sessionVersion: 3,
});
Expand All @@ -67,7 +73,8 @@ module('Unit | Route | Certification | Start', function (hooks) {
});

const findRecordStub = sinon.stub().returns(certificationCandidateSubscription);
const storeStub = Service.create({ findRecord: findRecordStub });
const peekRecordStub = sinon.stub().returns(certificationCandidate);
const storeStub = Service.create({ findRecord: findRecordStub, peekRecord: peekRecordStub });

const route = this.owner.lookup('route:authenticated/certifications.start');
route.set('store', storeStub);
Expand All @@ -88,12 +95,15 @@ module('Unit | Route | Certification | Start', function (hooks) {
module('when session is V3 and toggle is not enabled', function () {
test('should not redirect to certification information page', async function (assert) {
// given
const certificationCandidateId = 'certification-candidate-id';
const params = { certification_candidate_id: certificationCandidateId };
const store = this.owner.lookup('service:store');
const certificationCandidate = store.createRecord('certification-candidate', {
sessionId: 1234,
hasSeenCertificationInstructions: false,
});
const params = { certification_candidate_id: certificationCandidate.id };

const certificationCandidateSubscription = store.createRecord('certification-candidate-subscription', {
id: certificationCandidateId,
id: certificationCandidate.id,
sessionId: 1234,
sessionVersion: 3,
});
Expand All @@ -104,7 +114,8 @@ module('Unit | Route | Certification | Start', function (hooks) {
});

const findRecordStub = sinon.stub().returns(certificationCandidateSubscription);
const storeStub = Service.create({ findRecord: findRecordStub });
const peekRecordStub = sinon.stub().returns(certificationCandidate);
const storeStub = Service.create({ findRecord: findRecordStub, peekRecord: peekRecordStub });

const route = this.owner.lookup('route:authenticated/certifications.start');
route.set('store', storeStub);
Expand All @@ -123,12 +134,15 @@ module('Unit | Route | Certification | Start', function (hooks) {
module('when session is not V3 and toggle is enabled', function () {
test('should not redirect to certification information page', async function (assert) {
// given
const certificationCandidateId = 'certification-candidate-id';
const params = { certification_candidate_id: certificationCandidateId };
const store = this.owner.lookup('service:store');
const certificationCandidate = store.createRecord('certification-candidate', {
sessionId: 1234,
hasSeenCertificationInstructions: false,
});
const params = { certification_candidate_id: certificationCandidate.id };

const certificationCandidateSubscription = store.createRecord('certification-candidate-subscription', {
id: certificationCandidateId,
id: certificationCandidate.id,
sessionId: 1234,
sessionVersion: 2,
});
Expand All @@ -139,7 +153,8 @@ module('Unit | Route | Certification | Start', function (hooks) {
});

const findRecordStub = sinon.stub().returns(certificationCandidateSubscription);
const storeStub = Service.create({ findRecord: findRecordStub });
const peekRecordStub = sinon.stub().returns(certificationCandidate);
const storeStub = Service.create({ findRecord: findRecordStub, peekRecord: peekRecordStub });

const route = this.owner.lookup('route:authenticated/certifications.start');
route.set('store', storeStub);
Expand All @@ -158,12 +173,15 @@ module('Unit | Route | Certification | Start', function (hooks) {
module('when session is not V3 and toggle is not enabled', function () {
test('should not redirect to certification information page', async function (assert) {
// given
const certificationCandidateId = 'certification-candidate-id';
const params = { certification_candidate_id: certificationCandidateId };
const store = this.owner.lookup('service:store');
const certificationCandidate = store.createRecord('certification-candidate', {
sessionId: 1234,
hasSeenCertificationInstructions: false,
});
const params = { certification_candidate_id: certificationCandidate.id };

const certificationCandidateSubscription = store.createRecord('certification-candidate-subscription', {
id: certificationCandidateId,
id: certificationCandidate.id,
sessionId: 1234,
sessionVersion: 2,
});
Expand All @@ -174,7 +192,8 @@ module('Unit | Route | Certification | Start', function (hooks) {
});

const findRecordStub = sinon.stub().returns(certificationCandidateSubscription);
const storeStub = Service.create({ findRecord: findRecordStub });
const peekRecordStub = sinon.stub().returns(certificationCandidate);
const storeStub = Service.create({ findRecord: findRecordStub, peekRecord: peekRecordStub });

const route = this.owner.lookup('route:authenticated/certifications.start');
route.set('store', storeStub);
Expand Down

0 comments on commit 6434b42

Please sign in to comment.