From c063a3ac8923254d558f8442d3e575cad46e1f71 Mon Sep 17 00:00:00 2001 From: Geoffroy Begouaussel Date: Wed, 6 Nov 2024 18:31:24 +0100 Subject: [PATCH] feat(mon-pix): custom organization results block should accept search params --- .../custom-organization-block.gjs | 78 ++++++--- .../results/evaluation-results-hero/index.gjs | 5 +- .../hero/custom-organization-block-test.js | 62 ++++--- .../hero/custom-organization-block-test.js | 163 ++++++++++++++++++ 4 files changed, 254 insertions(+), 54 deletions(-) create mode 100644 mon-pix/tests/unit/components/campaigns/assessment/hero/custom-organization-block-test.js diff --git a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/custom-organization-block.gjs b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/custom-organization-block.gjs index fb4c8c8d10a..9d854b6e5e6 100644 --- a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/custom-organization-block.gjs +++ b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/custom-organization-block.gjs @@ -1,29 +1,59 @@ import PixButtonLink from '@1024pix/pix-ui/components/pix-button-link'; +import Component from '@glimmer/component'; import { t } from 'ember-intl'; -import { and } from 'ember-truth-helpers'; import MarkdownToHtml from '../../../../markdown-to-html'; - +export default class EvaluationResultsCustomOrganizationBlock extends Component { + get customButtonUrl() { + if (this.args.campaign.customResultPageButtonUrl && this.args.campaign.customResultPageButtonText) { + const params = {}; + + if (Number.isFinite(this.args.campaignParticipationResult.masteryRate)) { + params.masteryPercentage = Number(this.args.campaignParticipationResult.masteryRate * 100).toFixed(0); + } + params.externalId = this.args.campaignParticipationResult.participantExternalId ?? undefined; + params.stage = this.args.campaignParticipationResult.reachedStage?.get('threshold') ?? undefined; + + return buildUrl(this.args.campaign.customResultPageButtonUrl, params); + } else { + return null; + } + } + + +} + +function buildUrl(baseUrl, params) { + const Url = new URL(baseUrl); + const urlParams = new URLSearchParams(Url.search); + for (const key in params) { + if (params[key] !== undefined) { + urlParams.set(key, params[key]); + } + } + Url.search = urlParams.toString(); + return Url.toString(); +} diff --git a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs index 5c626cbf7da..4f72b37fef2 100644 --- a/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs +++ b/mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs @@ -210,9 +210,8 @@ export default class EvaluationResultsHero extends Component { {{#if this.showCustomOrganizationBlock}} {{/if}} {{#if @campaignParticipationResult.canRetry}} diff --git a/mon-pix/tests/integration/components/campaigns/assessment/results/hero/custom-organization-block-test.js b/mon-pix/tests/integration/components/campaigns/assessment/results/hero/custom-organization-block-test.js index e031b25f32e..25bbb89af78 100644 --- a/mon-pix/tests/integration/components/campaigns/assessment/results/hero/custom-organization-block-test.js +++ b/mon-pix/tests/integration/components/campaigns/assessment/results/hero/custom-organization-block-test.js @@ -11,9 +11,12 @@ module( setupIntlRenderingTest(hooks); test('displays the block title', async function (assert) { + // given + this.set('campaign', {}); + // when const screen = await render( - hbs``, + hbs``, ); // then @@ -25,13 +28,14 @@ module( test('displays organization custom text', async function (assert) { // given const customResultPageText = 'My custom result page text'; - this.set('customResultPageText', customResultPageText); + + this.set('campaign', { + customResultPageText, + }); // when const screen = await render( - hbs``, + hbs``, ); // then @@ -42,13 +46,13 @@ module( module('when organization custom text is not defined', function () { test('not display organization custom text', async function (assert) { // given - this.set('customResultPageText', null); + this.set('campaign', { + customResultPageText: null, + }); // when const screen = await render( - hbs``, + hbs``, ); // then @@ -62,23 +66,29 @@ module( test('displays organization custom link', async function (assert) { // given const customResultPageButtonUrl = 'https://pix.org/'; - this.set('customResultPageButtonUrl', customResultPageButtonUrl); - const customResultPageButtonText = 'My custom button'; - this.set('customResultPageButtonText', customResultPageButtonText); + + this.set('campaign', { + customResultPageButtonUrl, + customResultPageButtonText, + }); + + this.set('campaignParticipationResult', { + masteryRate: 0.75, + }); // when const screen = await render( hbs``, ); // then assert.strictEqual( screen.getByRole('link', { name: customResultPageButtonText }).href, - customResultPageButtonUrl, + `${customResultPageButtonUrl}?masteryPercentage=75`, ); }); }); @@ -87,16 +97,14 @@ module( test('not display organization custom link', async function (assert) { // given const customResultPageButtonUrl = 'https://pix.org/'; - this.set('customResultPageButtonUrl', customResultPageButtonUrl); - this.set('customResultPageButtonText', null); + this.set('campaign', { + customResultPageButtonUrl, + }); // when const screen = await render( - hbs``, + hbs``, ); // then @@ -107,15 +115,15 @@ module( module('when organization custom link label is defined but url is not', function () { test('not display organization custom link', async function (assert) { // given - this.set('customResultPageButtonUrl', null); - this.set('customResultPageButtonText', 'Some custom button text'); + + this.set('campaign', { + customResultPageButtonUrl: null, + customResultPageButtonText: 'Some custom button text', + }); // when const screen = await render( - hbs``, + hbs``, ); // then diff --git a/mon-pix/tests/unit/components/campaigns/assessment/hero/custom-organization-block-test.js b/mon-pix/tests/unit/components/campaigns/assessment/hero/custom-organization-block-test.js new file mode 100644 index 00000000000..83f1a532222 --- /dev/null +++ b/mon-pix/tests/unit/components/campaigns/assessment/hero/custom-organization-block-test.js @@ -0,0 +1,163 @@ +import { setupTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +import createGlimmerComponent from '../../../../../helpers/create-glimmer-component'; + +module('Unit | Component | Campaigns | Assessment | Results | Hero | Custom Organization Block', function (hooks) { + setupTest(hooks); + + module('#customButtonUrl', function () { + module('when there is no custom link', function () { + test('should return null', async function (assert) { + // given + const store = this.owner.lookup('service:store'); + + const component = createGlimmerComponent( + 'campaigns/assessment/results/evaluation-results-hero/custom-organization-block', + ); + + component.args.campaign = store.createRecord('campaign', { + customResultPageButtonUrl: null, + customResultPageButtonText: 'useless label', + }); + + // when + const url = component.customButtonUrl; + + // then + assert.strictEqual(url, null); + }); + }); + + module('when there is a custom link', function () { + test('should return the custom link', async function (assert) { + // given + const store = this.owner.lookup('service:store'); + + const component = createGlimmerComponent( + 'campaigns/assessment/results/evaluation-results-hero/custom-organization-block', + ); + + component.args.campaign = store.createRecord('campaign', { + customResultPageButtonUrl: 'https://pix.org/', + customResultPageButtonText: 'custom label', + }); + component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', {}); + + // when + const url = component.customButtonUrl; + + // then + assert.strictEqual(url, 'https://pix.org/'); + }); + + module('when there is a mastery rate', function () { + test('should return the custom link with a rounded mastery percentage search param', async function (assert) { + // given + const store = this.owner.lookup('service:store'); + + const component = createGlimmerComponent( + 'campaigns/assessment/results/evaluation-results-hero/custom-organization-block', + ); + + component.args.campaign = store.createRecord('campaign', { + customResultPageButtonUrl: 'https://pix.org/', + customResultPageButtonText: 'custom label', + }); + component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', { + masteryRate: 0.755, + }); + + // when + const url = component.customButtonUrl; + + // then + assert.strictEqual(url, 'https://pix.org/?masteryPercentage=76'); + }); + }); + + module('when there is an external id', function () { + test('should return the custom link with external id search param', async function (assert) { + // given + const store = this.owner.lookup('service:store'); + + const component = createGlimmerComponent( + 'campaigns/assessment/results/evaluation-results-hero/custom-organization-block', + ); + + component.args.campaign = store.createRecord('campaign', { + customResultPageButtonUrl: 'https://pix.org/', + customResultPageButtonText: 'custom label', + }); + component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', { + participantExternalId: 'externalId', + }); + + // when + const url = component.customButtonUrl; + + // then + assert.strictEqual(url, 'https://pix.org/?externalId=externalId'); + }); + }); + + module('when there is a stage', function () { + test('should return the custom link with stage threshold search param', async function (assert) { + // given + const store = this.owner.lookup('service:store'); + + const component = createGlimmerComponent( + 'campaigns/assessment/results/evaluation-results-hero/custom-organization-block', + ); + + component.args.campaign = store.createRecord('campaign', { + customResultPageButtonUrl: 'https://pix.org/', + customResultPageButtonText: 'custom label', + }); + const reachedStage = store.createRecord('reached-stage', { + threshold: 5, + }); + component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', { + reachedStage, + }); + + // when + const url = component.customButtonUrl; + + // then + assert.strictEqual(url, 'https://pix.org/?stage=5'); + }); + }); + + module('when there is all parameters', function () { + test('should return the custom link with all parameters', async function (assert) { + // given + const store = this.owner.lookup('service:store'); + + const component = createGlimmerComponent( + 'campaigns/assessment/results/evaluation-results-hero/custom-organization-block', + ); + + component.args.campaign = store.createRecord('campaign', { + customResultPageButtonUrl: 'https://pix.org/', + customResultPageButtonText: 'custom label', + }); + const reachedStage = store.createRecord('reached-stage', { + threshold: 5, + }); + component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', { + reachedStage, + masteryRate: 0.75, + participantExternalId: 'externalId', + }); + + // when + const url = component.customButtonUrl; + + // then + assert.strictEqual(url, 'https://pix.org/?masteryPercentage=75&externalId=externalId&stage=5'); + }); + }); + }); + }); +});