Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#6390): update phone widget to allow not checking for dupes #9340

Merged
merged 8 commits into from
Aug 22, 2024
18 changes: 1 addition & 17 deletions tests/e2e/default/enketo/enketo-widgets.wdio-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('Enketo Widgets', () => {
);
};

const verifyReport = async (selectMultiple, selectOne, country, city, neighborhood, uuid, id, name, phoneNumber) => {
const verifyReport = async (selectMultiple, selectOne, country, city, neighborhood, uuid, id, name) => {
const firstReport = await reportsPage.firstReport();
const firstReportInfo = await reportsPage.getListReportInfo(firstReport);

Expand All @@ -73,7 +73,6 @@ describe('Enketo Widgets', () => {
expect((await reportsPage.getDetailReportRowContent('patient_uuid')).rowValues[0]).to.equal(uuid);
expect((await reportsPage.getDetailReportRowContent('patient_id')).rowValues[0]).to.equal(id);
expect((await reportsPage.getDetailReportRowContent('patient_name')).rowValues[0]).to.equal(name);
expect((await reportsPage.getDetailReportRowContent('phone')).rowValues[0]).to.equal(phoneNumber);
};

before(async () => {
Expand Down Expand Up @@ -101,20 +100,6 @@ describe('Enketo Widgets', () => {
expect(await enketoWidgetsPage.getDropdownValue(await enketoWidgetsPage.selectOneDropdown()))
.to.equal('option d');

// try to move to next page without filling the mandatory phone number field
await genericForm.nextPage(1, false);
expect(await enketoWidgetsPage.phoneFieldRequiredMessage().getAttribute('data-i18n'))
.to.equal('constraint.required');

// try to move to next page with an invalid phone number
await commonEnketoPage.setInputValue('Phone Number', '+4076');
await genericForm.nextPage(1, false);
expect(await enketoWidgetsPage.phoneFieldConstraintMessage().getAttribute('data-itext-id'))
.to.equal('/enketo_widgets_test/enketo_test_select/phone:jr:constraintMsg');

// finally set a valid phone number and continue
await commonEnketoPage.setInputValue('Phone Number', phoneNumber);

await genericForm.nextPage();
await fillCascadingWidgetsSection('usa', 'nyc', 'bronx', 3, 2);
await genericForm.submitForm();
Expand Down Expand Up @@ -149,7 +134,6 @@ describe('Enketo Widgets', () => {
await enketoWidgetsPage.selectDropdownOptions(await enketoWidgetsPage.selectOneDropdown(), 'radio', 'a');
expect(await enketoWidgetsPage.getDropdownValue(await enketoWidgetsPage.selectOneDropdown()))
.to.equal('option a');
await commonEnketoPage.setInputValue('Phone Number', phoneNumber);

await genericForm.nextPage();
await fillCascadingWidgetsSection('nl', 'dro', 'havendr', 3, 1);
Expand Down
Binary file modified tests/e2e/default/enketo/forms/enketo_widgets_test.xlsx
Binary file not shown.
95 changes: 42 additions & 53 deletions tests/e2e/default/enketo/forms/enketo_widgets_test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@
<text id="/enketo_widgets_test/cascading_widgets:label">
<value>Cascading Select widgets</value>
</text>
<text id="/enketo_widgets_test/enketo_test_select/phone:jr:constraintMsg">
<value>Please enter a valid local number, or use the standard international format, which includes a plus sign (+) and country code. For example: +254712345678</value>
</text>
<text id="/enketo_widgets_test/enketo_test_select/phone:label">
<value>Phone Number</value>
</text>
<text id="/enketo_widgets_test/enketo_test_select/select1_spinner/a:label">
<value>option a</value>
</text>
Expand Down Expand Up @@ -173,11 +167,10 @@
</translation>
</itext>
<instance>
<enketo_widgets_test delimiter="#" id="enketo_widgets_test" prefix="J1!enketo_widgets_test!" version="2023-09-11 00:00:00">
<enketo_widgets_test delimiter="#" id="enketo_widgets_test" prefix="J1!enketo_widgets_test!" version="2024-08-16 00:00:00">
<enketo_test_select>
<select_spinner/>
<select1_spinner/>
<phone/>
</enketo_test_select>
<cascading_widgets>
<group1>
Expand Down Expand Up @@ -217,6 +210,38 @@
</enketo_widgets_test>
</instance>
<instance id="contact-summary"/>
<instance id="list">
<root>
<item>
<itextId>static_instance-list-0</itextId>
<name>a</name>
</item>
<item>
<itextId>static_instance-list-1</itextId>
<name>b</name>
</item>
<item>
<itextId>static_instance-list-2</itextId>
<name>c</name>
</item>
<item>
<itextId>static_instance-list-3</itextId>
<name>d</name>
</item>
</root>
</instance>
<instance id="countries">
<root>
<item>
<itextId>static_instance-countries-0</itextId>
<name>nl</name>
</item>
<item>
<itextId>static_instance-countries-1</itextId>
<name>usa</name>
</item>
</root>
</instance>
<instance id="cities">
<root>
<item>
Expand Down Expand Up @@ -251,99 +276,66 @@
</item>
</root>
</instance>
<instance id="list">
<root>
<item>
<itextId>static_instance-list-0</itextId>
<name>a</name>
</item>
<item>
<itextId>static_instance-list-1</itextId>
<name>b</name>
</item>
<item>
<itextId>static_instance-list-2</itextId>
<name>c</name>
</item>
<item>
<itextId>static_instance-list-3</itextId>
<name>d</name>
</item>
</root>
</instance>
<instance id="neighborhoods">
<root>
<item>
<itextId>static_instance-neighborhoods-0</itextId>
<country>usa</country>
<name>bronx</name>
<city>nyc</city>
<name>bronx</name>
</item>
<item>
<itextId>static_instance-neighborhoods-1</itextId>
<country>usa</country>
<name>harlem</name>
<city>nyc</city>
<name>harlem</name>
</item>
<item>
<itextId>static_instance-neighborhoods-2</itextId>
<country>usa</country>
<name>belair</name>
<city>la</city>
<name>belair</name>
</item>
<item>
<itextId>static_instance-neighborhoods-3</itextId>
<country>nl</country>
<name>wes</name>
<city>ams</city>
<name>wes</name>
</item>
<item>
<itextId>static_instance-neighborhoods-4</itextId>
<country>usa</country>
<name>parkhill</name>
<city>den</city>
<name>parkhill</name>
</item>
<item>
<itextId>static_instance-neighborhoods-5</itextId>
<country>nl</country>
<name>haven</name>
<city>rot</city>
<name>haven</name>
</item>
<item>
<itextId>static_instance-neighborhoods-6</itextId>
<country>nl</country>
<name>dam</name>
<city>ams</city>
<name>dam</name>
</item>
<item>
<itextId>static_instance-neighborhoods-7</itextId>
<country>nl</country>
<name>centrum</name>
<city>rot</city>
<name>centrum</name>
</item>
<item>
<itextId>static_instance-neighborhoods-8</itextId>
<country>nl</country>
<name>havendr</name>
<city>dro</city>
</item>
</root>
</instance>
<instance id="countries">
<root>
<item>
<itextId>static_instance-countries-0</itextId>
<name>nl</name>
</item>
<item>
<itextId>static_instance-countries-1</itextId>
<name>usa</name>
<name>havendr</name>
</item>
</root>
</instance>
<bind nodeset="/enketo_widgets_test/enketo_test_select/select_spinner" type="select"/>
<bind nodeset="/enketo_widgets_test/enketo_test_select/select1_spinner" type="select1"/>
<bind constraint="true()" jr:constraintMsg="jr:itext('/enketo_widgets_test/enketo_test_select/phone:jr:constraintMsg')" nodeset="/enketo_widgets_test/enketo_test_select/phone" required="true()" type="tel"/>
<bind nodeset="/enketo_widgets_test/cascading_widgets/group1/country" type="select1"/>
<bind nodeset="/enketo_widgets_test/cascading_widgets/group1/city" type="select1"/>
<bind nodeset="/enketo_widgets_test/cascading_widgets/group1/neighborhood" type="select1"/>
Expand Down Expand Up @@ -405,9 +397,6 @@
<value>d</value>
</item>
</select1>
<input ref="/enketo_widgets_test/enketo_test_select/phone">
<label ref="jr:itext('/enketo_widgets_test/enketo_test_select/phone:label')"/>
</input>
</group>
<group appearance="field-list" ref="/enketo_widgets_test/cascading_widgets">
<label ref="jr:itext('/enketo_widgets_test/cascading_widgets:label')"/>
Expand Down
Binary file added tests/e2e/default/enketo/forms/phone_widget.xlsx
Binary file not shown.
60 changes: 60 additions & 0 deletions tests/e2e/default/enketo/forms/phone_widget.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:cht="https://communityhealthtoolkit.org" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:orx="http://openrosa.org/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<h:head>
<h:title>Phone Widget</h:title>
<model>
<itext>
<translation lang="en">
<text id="/phone_widget/phone_widgets/deprecated_phone:jr:constraintMsg">
<value>Please enter a valid local number, or use the standard international format, which includes a plus sign (+) and country code. For example: +254712345678</value>
</text>
<text id="/phone_widget/phone_widgets/deprecated_phone:label">
<value>Deprecated Phone</value>
</text>
<text id="/phone_widget/phone_widgets/phone:jr:constraintMsg">
<value>Please enter a valid local number, or use the standard international format, which includes a plus sign (+) and country code. For example: +254712345678</value>
</text>
<text id="/phone_widget/phone_widgets/phone:label">
<value>Phone – allow duplicates</value>
</text>
<text id="/phone_widget/phone_widgets/phone_unique:jr:constraintMsg">
<value>Please enter a valid local number, or use the standard international format, which includes a plus sign (+) and country code. For example: +254712345678</value>
</text>
<text id="/phone_widget/phone_widgets/phone_unique:label">
<value>Phone – unique</value>
</text>
</translation>
</itext>
<instance>
<phone_widget delimiter="#" id="phone_widget" prefix="J1!phone_widget!" version="2024-08-16 00:00:00">
<phone_widgets>
<deprecated_phone/>
<phone/>
<phone_unique cht:unique_tel="true"/>
</phone_widgets>
<meta tag="hidden">
<instanceID/>
</meta>
</phone_widget>
</instance>
<instance id="contact-summary"/>
<bind constraint="true()" jr:constraintMsg="jr:itext('/phone_widget/phone_widgets/deprecated_phone:jr:constraintMsg')" nodeset="/phone_widget/phone_widgets/deprecated_phone" required="true()" type="tel"/>
<bind constraint="true()" jr:constraintMsg="jr:itext('/phone_widget/phone_widgets/phone:jr:constraintMsg')" nodeset="/phone_widget/phone_widgets/phone" type="string"/>
<bind constraint="true()" jr:constraintMsg="jr:itext('/phone_widget/phone_widgets/phone_unique:jr:constraintMsg')" nodeset="/phone_widget/phone_widgets/phone_unique" required="true()" type="string"/>
<bind calculate="concat('uuid:', uuid())" nodeset="/phone_widget/meta/instanceID" readonly="true()" type="string"/>
</model>
</h:head>
<h:body class="pages">
<group appearance="field-list" ref="/phone_widget/phone_widgets">
<input ref="/phone_widget/phone_widgets/deprecated_phone">
<label ref="jr:itext('/phone_widget/phone_widgets/deprecated_phone:label')"/>
</input>
<input appearance="numbers tel" ref="/phone_widget/phone_widgets/phone">
<label ref="jr:itext('/phone_widget/phone_widgets/phone:label')"/>
</input>
<input appearance="numbers tel" ref="/phone_widget/phone_widgets/phone_unique">
<label ref="jr:itext('/phone_widget/phone_widgets/phone_unique:label')"/>
</input>
</group>
</h:body>
</h:html>
78 changes: 78 additions & 0 deletions tests/e2e/default/enketo/phone-widget.wdio-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
const commonPage = require('@page-objects/default/common/common.wdio.page');
const reportsPage = require('@page-objects/default/reports/reports.wdio.page');
const utils = require('@utils');
const loginPage = require('@page-objects/default/login/login.wdio.page');
const genericForm = require('@page-objects/default/enketo/generic-form.wdio.page');
const contactsPage = require('@page-objects/default/contacts/contacts.wdio.page');
const commonEnketoPage = require('@page-objects/default/enketo/common-enketo.wdio.page');
const personFactory = require('@factories/cht/contacts/person');
const { expect } = require('chai');

describe('Phone widget', () => {
const phone = '+254712345678';
const person0 = personFactory.build({ phone });
const person1 = personFactory.build({ phone: '+254712345679' });

before(async () => {
await commonEnketoPage.uploadForm('phone_widget');
await utils.saveDocs([person0, person1]);
await loginPage.cookieLogin();
await commonPage.hideSnackbar();
});

// Only testing the duplicate checking logic here.
// The rest of the phone widget logic is covered by the cht-form integration tests

it('duplicate phone numbers violate constraint when configured in app form', async () => {
await commonPage.goToReports();

await commonPage.openFastActionReport('phone_widget', false);

await commonEnketoPage.setInputValue('Deprecated Phone', phone);
await commonEnketoPage.setInputValue('Phone – allow duplicates', phone);
await commonEnketoPage.setInputValue('Phone – unique', phone);

expect(await commonEnketoPage.isConstraintMessageDisplayed('Deprecated Phone')).to.be.true;
expect(await commonEnketoPage.isConstraintMessageDisplayed('Phone – allow duplicates')).to.be.false;
expect(await commonEnketoPage.isConstraintMessageDisplayed('Phone – unique')).to.be.true;

await commonEnketoPage.setInputValue('Deprecated Phone', '+254712345671');
await commonEnketoPage.setInputValue('Phone – unique', '+254712345674');

expect(await commonEnketoPage.isConstraintMessageDisplayed('Deprecated Phone')).to.be.false;
expect(await commonEnketoPage.isConstraintMessageDisplayed('Phone – unique')).to.be.false;

await genericForm.submitForm();

const reportId = await reportsPage.getCurrentReportId();
const { fields } = await utils.getDoc(reportId);
expect(fields).excluding(['meta']).to.deep.equal({
phone_widgets: {
deprecated_phone: '+254712345671',
phone,
phone_unique: '+254712345674',
}
});
});

it('can use duplicate phone number when editing contact with same number', async () => {
await commonPage.goToPeople(person1._id);
await contactsPage.openEditContactForm();

await (await genericForm.nextPage());
// Try setting phone to number of the other person
await commonEnketoPage.setInputValue('Phone Number', person0.phone);

expect(await commonEnketoPage.isConstraintMessageDisplayed('Phone Number')).to.be.true;

// Reset phone back to original value for this person
await commonEnketoPage.setInputValue('Phone Number', person1.phone);

expect(await commonEnketoPage.isConstraintMessageDisplayed('Phone Number')).to.be.false;

await genericForm.submitForm();

const editedPerson = await utils.getDoc(person1._id);
expect(editedPerson.phone).to.equal(person1.phone);
});
});
16 changes: 0 additions & 16 deletions tests/integration/cht-form/default/enketo-widgets.wdio-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,6 @@ describe('cht-form web component - Enketo Widgets', () => {
expect(await enketoWidgetsPage.getDropdownValue(await enketoWidgetsPage.selectOneDropdown()))
.to.equal('option d');

// try to move to next page without filling the mandatory phone number field
await genericForm.nextPage(1, false);
expect(await enketoWidgetsPage.phoneFieldRequiredMessage().getAttribute('data-i18n'))
.to.equal('constraint.required');

// try to move to next page with an invalid phone number
await commonEnketoPage.setInputValue('Phone Number', '+4076');
await genericForm.nextPage(1, false);
expect(await enketoWidgetsPage.phoneFieldConstraintMessage().getAttribute('data-itext-id'))
.to.equal('/enketo_widgets_test/enketo_test_select/phone:jr:constraintMsg');

// finally set a valid phone number and continue
await commonEnketoPage.setInputValue('Phone Number', '+40766565656');

await $('.form-footer').click();
await genericForm.nextPage();

await commonEnketoPage.selectRadioButton('Country', 'United States');
Expand Down Expand Up @@ -76,7 +61,6 @@ describe('cht-form web component - Enketo Widgets', () => {
expect(jsonObj.patient_name).to.equal('Elias');
expect(jsonObj.enketo_test_select.select_spinner).to.equal('a c');
expect(jsonObj.enketo_test_select.select1_spinner).to.equal('d');
expect(jsonObj.enketo_test_select.phone).to.equal('+40766565656');
expect(jsonObj.cascading_widgets.group1.country).to.equal('usa');
expect(jsonObj.cascading_widgets.group1.city).to.equal('nyc');
expect(jsonObj.cascading_widgets.group1.neighborhood).to.equal('bronx');
Expand Down
Loading