Skip to content

Commit c063a3a

Browse files
authored
feat(mon-pix): custom organization results block should accept search params
1 parent 215b4d6 commit c063a3a

File tree

4 files changed

+254
-54
lines changed

4 files changed

+254
-54
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,59 @@
11
import PixButtonLink from '@1024pix/pix-ui/components/pix-button-link';
2+
import Component from '@glimmer/component';
23
import { t } from 'ember-intl';
3-
import { and } from 'ember-truth-helpers';
44

55
import MarkdownToHtml from '../../../../markdown-to-html';
66

7-
<template>
8-
<div class="evaluation-results-hero__organization-block">
9-
<h3 class="evaluation-results-hero-organization-block__title">
10-
{{t "pages.skill-review.organization-message"}}
11-
</h3>
12-
{{#if @customResultPageText}}
13-
<MarkdownToHtml
14-
class="evaluation-results-hero-organization-block__message"
15-
@isInline={{true}}
16-
@markdown={{@customResultPageText}}
17-
/>
18-
{{/if}}
19-
{{#if (and @customResultPageButtonUrl @customResultPageButtonText)}}
20-
<PixButtonLink
21-
class="evaluation-results-hero-organization-block__link"
22-
@href={{@customResultPageButtonUrl}}
23-
@variant="secondary"
24-
>
25-
{{@customResultPageButtonText}}
26-
</PixButtonLink>
27-
{{/if}}
28-
</div>
29-
</template>
7+
export default class EvaluationResultsCustomOrganizationBlock extends Component {
8+
get customButtonUrl() {
9+
if (this.args.campaign.customResultPageButtonUrl && this.args.campaign.customResultPageButtonText) {
10+
const params = {};
11+
12+
if (Number.isFinite(this.args.campaignParticipationResult.masteryRate)) {
13+
params.masteryPercentage = Number(this.args.campaignParticipationResult.masteryRate * 100).toFixed(0);
14+
}
15+
params.externalId = this.args.campaignParticipationResult.participantExternalId ?? undefined;
16+
params.stage = this.args.campaignParticipationResult.reachedStage?.get('threshold') ?? undefined;
17+
18+
return buildUrl(this.args.campaign.customResultPageButtonUrl, params);
19+
} else {
20+
return null;
21+
}
22+
}
23+
24+
<template>
25+
<div class="evaluation-results-hero__organization-block">
26+
<h3 class="evaluation-results-hero-organization-block__title">
27+
{{t "pages.skill-review.organization-message"}}
28+
</h3>
29+
{{#if @campaign.customResultPageText}}
30+
<MarkdownToHtml
31+
class="evaluation-results-hero-organization-block__message"
32+
@isInline={{true}}
33+
@markdown={{@campaign.customResultPageText}}
34+
/>
35+
{{/if}}
36+
{{#if this.customButtonUrl}}
37+
<PixButtonLink
38+
class="evaluation-results-hero-organization-block__link"
39+
@href={{this.customButtonUrl}}
40+
@variant="secondary"
41+
>
42+
{{@campaign.customResultPageButtonText}}
43+
</PixButtonLink>
44+
{{/if}}
45+
</div>
46+
</template>
47+
}
48+
49+
function buildUrl(baseUrl, params) {
50+
const Url = new URL(baseUrl);
51+
const urlParams = new URLSearchParams(Url.search);
52+
for (const key in params) {
53+
if (params[key] !== undefined) {
54+
urlParams.set(key, params[key]);
55+
}
56+
}
57+
Url.search = urlParams.toString();
58+
return Url.toString();
59+
}

mon-pix/app/components/campaigns/assessment/results/evaluation-results-hero/index.gjs

+2-3
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,8 @@ export default class EvaluationResultsHero extends Component {
210210
</div>
211211
{{#if this.showCustomOrganizationBlock}}
212212
<CustomOrganizationBlock
213-
@customResultPageText={{@campaign.customResultPageText}}
214-
@customResultPageButtonText={{@campaign.customResultPageButtonText}}
215-
@customResultPageButtonUrl={{@campaign.customResultPageButtonUrl}}
213+
@campaign={{@campaign}}
214+
@campaignParticipationResult={{@campaignParticipationResult}}
216215
/>
217216
{{/if}}
218217
{{#if @campaignParticipationResult.canRetry}}

mon-pix/tests/integration/components/campaigns/assessment/results/hero/custom-organization-block-test.js

+35-27
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ module(
1111
setupIntlRenderingTest(hooks);
1212

1313
test('displays the block title', async function (assert) {
14+
// given
15+
this.set('campaign', {});
16+
1417
// when
1518
const screen = await render(
16-
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock />`,
19+
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock @campaign={{this.campaign}} />`,
1720
);
1821

1922
// then
@@ -25,13 +28,14 @@ module(
2528
test('displays organization custom text', async function (assert) {
2629
// given
2730
const customResultPageText = 'My custom result page text';
28-
this.set('customResultPageText', customResultPageText);
31+
32+
this.set('campaign', {
33+
customResultPageText,
34+
});
2935

3036
// when
3137
const screen = await render(
32-
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock
33-
@customResultPageText={{this.customResultPageText}}
34-
/>`,
38+
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock @campaign={{this.campaign}} />`,
3539
);
3640

3741
// then
@@ -42,13 +46,13 @@ module(
4246
module('when organization custom text is not defined', function () {
4347
test('not display organization custom text', async function (assert) {
4448
// given
45-
this.set('customResultPageText', null);
49+
this.set('campaign', {
50+
customResultPageText: null,
51+
});
4652

4753
// when
4854
const screen = await render(
49-
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock
50-
@customResultPageText={{this.customResultPageText}}
51-
/>`,
55+
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock @campaign={{this.campaign}} />`,
5256
);
5357

5458
// then
@@ -62,23 +66,29 @@ module(
6266
test('displays organization custom link', async function (assert) {
6367
// given
6468
const customResultPageButtonUrl = 'https://pix.org/';
65-
this.set('customResultPageButtonUrl', customResultPageButtonUrl);
66-
6769
const customResultPageButtonText = 'My custom button';
68-
this.set('customResultPageButtonText', customResultPageButtonText);
70+
71+
this.set('campaign', {
72+
customResultPageButtonUrl,
73+
customResultPageButtonText,
74+
});
75+
76+
this.set('campaignParticipationResult', {
77+
masteryRate: 0.75,
78+
});
6979

7080
// when
7181
const screen = await render(
7282
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock
73-
@customResultPageButtonUrl={{this.customResultPageButtonUrl}}
74-
@customResultPageButtonText={{this.customResultPageButtonText}}
83+
@campaign={{this.campaign}}
84+
@campaignParticipationResult={{this.campaignParticipationResult}}
7585
/>`,
7686
);
7787

7888
// then
7989
assert.strictEqual(
8090
screen.getByRole('link', { name: customResultPageButtonText }).href,
81-
customResultPageButtonUrl,
91+
`${customResultPageButtonUrl}?masteryPercentage=75`,
8292
);
8393
});
8494
});
@@ -87,16 +97,14 @@ module(
8797
test('not display organization custom link', async function (assert) {
8898
// given
8999
const customResultPageButtonUrl = 'https://pix.org/';
90-
this.set('customResultPageButtonUrl', customResultPageButtonUrl);
91100

92-
this.set('customResultPageButtonText', null);
101+
this.set('campaign', {
102+
customResultPageButtonUrl,
103+
});
93104

94105
// when
95106
const screen = await render(
96-
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock
97-
@customResultPageButtonUrl={{this.customResultPageButtonUrl}}
98-
@customResultPageButtonText={{this.customResultPageButtonText}}
99-
/>`,
107+
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock @campaign={{this.campaign}} />`,
100108
);
101109

102110
// then
@@ -107,15 +115,15 @@ module(
107115
module('when organization custom link label is defined but url is not', function () {
108116
test('not display organization custom link', async function (assert) {
109117
// given
110-
this.set('customResultPageButtonUrl', null);
111-
this.set('customResultPageButtonText', 'Some custom button text');
118+
119+
this.set('campaign', {
120+
customResultPageButtonUrl: null,
121+
customResultPageButtonText: 'Some custom button text',
122+
});
112123

113124
// when
114125
const screen = await render(
115-
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock
116-
@customResultPageButtonUrl={{this.customResultPageButtonUrl}}
117-
@customResultPageButtonText={{this.customResultPageButtonText}}
118-
/>`,
126+
hbs`<Campaigns::Assessment::Results::EvaluationResultsHero::CustomOrganizationBlock @campaign={{this.campaign}} />`,
119127
);
120128

121129
// then
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import { setupTest } from 'ember-qunit';
2+
import { module, test } from 'qunit';
3+
4+
import createGlimmerComponent from '../../../../../helpers/create-glimmer-component';
5+
6+
module('Unit | Component | Campaigns | Assessment | Results | Hero | Custom Organization Block', function (hooks) {
7+
setupTest(hooks);
8+
9+
module('#customButtonUrl', function () {
10+
module('when there is no custom link', function () {
11+
test('should return null', async function (assert) {
12+
// given
13+
const store = this.owner.lookup('service:store');
14+
15+
const component = createGlimmerComponent(
16+
'campaigns/assessment/results/evaluation-results-hero/custom-organization-block',
17+
);
18+
19+
component.args.campaign = store.createRecord('campaign', {
20+
customResultPageButtonUrl: null,
21+
customResultPageButtonText: 'useless label',
22+
});
23+
24+
// when
25+
const url = component.customButtonUrl;
26+
27+
// then
28+
assert.strictEqual(url, null);
29+
});
30+
});
31+
32+
module('when there is a custom link', function () {
33+
test('should return the custom link', async function (assert) {
34+
// given
35+
const store = this.owner.lookup('service:store');
36+
37+
const component = createGlimmerComponent(
38+
'campaigns/assessment/results/evaluation-results-hero/custom-organization-block',
39+
);
40+
41+
component.args.campaign = store.createRecord('campaign', {
42+
customResultPageButtonUrl: 'https://pix.org/',
43+
customResultPageButtonText: 'custom label',
44+
});
45+
component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', {});
46+
47+
// when
48+
const url = component.customButtonUrl;
49+
50+
// then
51+
assert.strictEqual(url, 'https://pix.org/');
52+
});
53+
54+
module('when there is a mastery rate', function () {
55+
test('should return the custom link with a rounded mastery percentage search param', async function (assert) {
56+
// given
57+
const store = this.owner.lookup('service:store');
58+
59+
const component = createGlimmerComponent(
60+
'campaigns/assessment/results/evaluation-results-hero/custom-organization-block',
61+
);
62+
63+
component.args.campaign = store.createRecord('campaign', {
64+
customResultPageButtonUrl: 'https://pix.org/',
65+
customResultPageButtonText: 'custom label',
66+
});
67+
component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', {
68+
masteryRate: 0.755,
69+
});
70+
71+
// when
72+
const url = component.customButtonUrl;
73+
74+
// then
75+
assert.strictEqual(url, 'https://pix.org/?masteryPercentage=76');
76+
});
77+
});
78+
79+
module('when there is an external id', function () {
80+
test('should return the custom link with external id search param', async function (assert) {
81+
// given
82+
const store = this.owner.lookup('service:store');
83+
84+
const component = createGlimmerComponent(
85+
'campaigns/assessment/results/evaluation-results-hero/custom-organization-block',
86+
);
87+
88+
component.args.campaign = store.createRecord('campaign', {
89+
customResultPageButtonUrl: 'https://pix.org/',
90+
customResultPageButtonText: 'custom label',
91+
});
92+
component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', {
93+
participantExternalId: 'externalId',
94+
});
95+
96+
// when
97+
const url = component.customButtonUrl;
98+
99+
// then
100+
assert.strictEqual(url, 'https://pix.org/?externalId=externalId');
101+
});
102+
});
103+
104+
module('when there is a stage', function () {
105+
test('should return the custom link with stage threshold search param', async function (assert) {
106+
// given
107+
const store = this.owner.lookup('service:store');
108+
109+
const component = createGlimmerComponent(
110+
'campaigns/assessment/results/evaluation-results-hero/custom-organization-block',
111+
);
112+
113+
component.args.campaign = store.createRecord('campaign', {
114+
customResultPageButtonUrl: 'https://pix.org/',
115+
customResultPageButtonText: 'custom label',
116+
});
117+
const reachedStage = store.createRecord('reached-stage', {
118+
threshold: 5,
119+
});
120+
component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', {
121+
reachedStage,
122+
});
123+
124+
// when
125+
const url = component.customButtonUrl;
126+
127+
// then
128+
assert.strictEqual(url, 'https://pix.org/?stage=5');
129+
});
130+
});
131+
132+
module('when there is all parameters', function () {
133+
test('should return the custom link with all parameters', async function (assert) {
134+
// given
135+
const store = this.owner.lookup('service:store');
136+
137+
const component = createGlimmerComponent(
138+
'campaigns/assessment/results/evaluation-results-hero/custom-organization-block',
139+
);
140+
141+
component.args.campaign = store.createRecord('campaign', {
142+
customResultPageButtonUrl: 'https://pix.org/',
143+
customResultPageButtonText: 'custom label',
144+
});
145+
const reachedStage = store.createRecord('reached-stage', {
146+
threshold: 5,
147+
});
148+
component.args.campaignParticipationResult = store.createRecord('campaign-participation-result', {
149+
reachedStage,
150+
masteryRate: 0.75,
151+
participantExternalId: 'externalId',
152+
});
153+
154+
// when
155+
const url = component.customButtonUrl;
156+
157+
// then
158+
assert.strictEqual(url, 'https://pix.org/?masteryPercentage=75&externalId=externalId&stage=5');
159+
});
160+
});
161+
});
162+
});
163+
});

0 commit comments

Comments
 (0)