From 4eb2245c5d47d04e2177d4aa4d8edd265898dca3 Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Tue, 14 Mar 2017 11:03:12 +0100 Subject: [PATCH] [ADD] web: add phone widget tests and documentation --- .../web/static/src/js/fields/basic_fields.js | 41 +++- .../static/test/fields/basic_fields_tests.js | 197 ++++++++++++++++++ 2 files changed, 231 insertions(+), 7 deletions(-) diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index f168d8cc69f..d08c628c164 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -620,26 +620,53 @@ var EmailWidget = InputField.extend({ var FieldPhone = EmailWidget.extend({ prefix: 'tel', + + /** + * The phone widget is an extension of email, with the distinction that, in + * some cases, we do not want to show a clickable widget in readonly. + * In particular, we only want to make it clickable if the device can call + * this particular number. This is controlled by the _canCall function. + * + * @override + */ init: function () { this._super.apply(this, arguments); - if (this.mode === 'readonly' && !this._can_call()) { + if (this.mode === 'readonly' && !this._canCall()) { this.tagName = 'span'; } }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * In readonly, we only make the widget clickable if the device can call it. + * Additionally, we obfuscate the phone number to prevent Skype from seeing it. + * + * @override + * @private + */ _renderReadonly: function () { this._super(); - if(this._can_call()) { + if(this._canCall()) { var text = this.$el.text(); this.$el.html(text.substr(0, text.length/2) + "­" + text.substr(text.length/2)); // To prevent Skype app to find the phone number } else { this.$el.removeClass('o_form_uri'); } }, - _can_call: function () { - // Phone fields are clickable in readonly on small screens ~= on phones - // This can be overriden by call-capable modules to display a clickable - // link in different situations, like always regardless of screen size, - // or only allow national calls for example. + + /** + * Phone fields are clickable in readonly on small screens ~= on phones. + * This can be overriden by call-capable modules to display a clickable + * link in different situations, like always regardless of screen size, + * or only allow national calls for example. + * + * @override + * @private + */ + _canCall: function () { return config.device.size_class <= config.device.SIZES.XS; } }); diff --git a/addons/web/static/test/fields/basic_fields_tests.js b/addons/web/static/test/fields/basic_fields_tests.js index c4d1fa32d50..374cda02fad 100644 --- a/addons/web/static/test/fields/basic_fields_tests.js +++ b/addons/web/static/test/fields/basic_fields_tests.js @@ -1170,6 +1170,203 @@ QUnit.module('basic_fields', { form.destroy(); }); + + QUnit.module('PhoneWidget'); + + QUnit.test('phone field in form view on extra small screens', function (assert) { + assert.expect(7); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '' + + '' + + '' + + '' + + '
', + res_id: 1, + config: { + device: { + size_class: 0, // Screen XS + SIZES: { XS: 0, SM: 1, MD: 2, LG: 3 }, + } + }, + }); + + var $phoneLink = form.$('a.o_form_uri.o_form_field.o_text_overflow'); + assert.strictEqual($phoneLink.length, 1, + "should have a anchor with correct classes"); + assert.strictEqual($phoneLink.text(), 'y\u00ADop', + "value should be displayed properly as text with the skype obfuscation"); + assert.strictEqual($phoneLink.attr('href'), 'tel:yop', + "should have proper tel prefix"); + + // switch to edit mode and check the result + form.$buttons.find('.o_form_button_edit').click(); + assert.strictEqual(form.$('input[type="text"].o_form_input.o_form_field').length, 1, + "should have an input for the phone field"); + assert.strictEqual(form.$('input[type="text"].o_form_input.o_form_field').val(), 'yop', + "input should contain field value in edit mode"); + + // change value in edit mode + form.$('input[type="text"].o_form_input.o_form_field').val('new').trigger('input'); + + // save + form.$buttons.find('.o_form_button_save').click(); + $phoneLink = form.$('a.o_form_uri.o_form_field.o_text_overflow'); + assert.strictEqual($phoneLink.text(), 'n\u00ADew', + "new value should be displayed properly as text with the skype obfuscation"); + assert.strictEqual($phoneLink.attr('href'), 'tel:new', + "should still have proper tel prefix"); + + form.destroy(); + }); + + QUnit.test('phone field in editable list view on extra small screens', function(assert) { + assert.expect(10); + + var list = createView({ + View: ListView, + model: 'partner', + data: this.data, + arch: '', + config: { + device: { + size_class: 0, // Screen XS + SIZES: { XS: 0, SM: 1, MD: 2, LG: 3 }, + } + }, + }); + + assert.strictEqual(list.$('tbody td:not(.o_list_record_selector)').length, 5, + "should have 5 cells"); + assert.strictEqual(list.$('tbody td:not(.o_list_record_selector)').first().text(), 'y\u00ADop', + "value should be displayed properly as text with the skype obfuscation"); + + var $phoneLink = list.$('a.o_form_uri.o_field_widget.o_text_overflow'); + assert.strictEqual($phoneLink.length, 5, + "should have anchors with correct classes"); + assert.strictEqual($phoneLink.first().attr('href'), 'tel:yop', + "should have proper tel prefix"); + + // Edit a line and check the result + var $cell = list.$('tbody td:not(.o_list_record_selector)').first(); + $cell.click(); + assert.ok($cell.hasClass('o_edit_mode'), 'should be set as edit mode'); + assert.strictEqual($cell.find('input').val(), 'yop', + 'should have the corect value in internal input'); + $cell.find('input').val('new').trigger('input');; + + // save + list.$buttons.find('.o_list_button_save').click(); + $cell = list.$('tbody td:not(.o_list_record_selector)').first(); + assert.ok(!$cell.hasClass('o_edit_mode'), 'should not be in edit mode anymore'); + assert.strictEqual(list.$('tbody td:not(.o_list_record_selector)').first().text(), 'n\u00ADew', + "value should be properly updated"); + $phoneLink = list.$('a.o_form_uri.o_field_widget.o_text_overflow'); + assert.strictEqual($phoneLink.length, 5, + "should still have anchors with correct classes"); + assert.strictEqual($phoneLink.first().attr('href'), 'tel:new', + "should still have proper tel prefix"); + + list.destroy(); + }); + + QUnit.test('phone field in form view on normal screens', function (assert) { + assert.expect(5); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
' + + '' + + '' + + '' + + '' + + '' + + '
', + res_id: 1, + config: { + device: { + size_class: 1, // Screen SM + SIZES: { XS: 0, SM: 1, MD: 2, LG: 3 }, + } + }, + }); + + var $phone = form.$('span.o_form_field.o_text_overflow:not(.o_form_uri)'); + assert.strictEqual($phone.length, 1, + "should have a simple span rather than a link"); + assert.strictEqual($phone.text(), 'yop', + "value should be displayed properly as text without skype obfuscation"); + + // switch to edit mode and check the result + form.$buttons.find('.o_form_button_edit').click(); + assert.strictEqual(form.$('input[type="text"].o_form_input.o_form_field').length, 1, + "should have an input for the phone field"); + assert.strictEqual(form.$('input[type="text"].o_form_input.o_form_field').val(), 'yop', + "input should contain field value in edit mode"); + + // change value in edit mode + form.$('input[type="text"].o_form_input.o_form_field').val('new').trigger('input'); + + // save + form.$buttons.find('.o_form_button_save').click(); + assert.strictEqual(form.$('span.o_form_field.o_text_overflow:not(.o_form_uri)').text(), 'new', + "new value should be displayed properly as text without skype obfuscation"); + + form.destroy(); + }); + + QUnit.test('phone field in editable list view on normal screens', function(assert) { + assert.expect(8); + + var list = createView({ + View: ListView, + model: 'partner', + data: this.data, + arch: '', + config: { + device: { + size_class: 1, // Screen SM + SIZES: { XS: 0, SM: 1, MD: 2, LG: 3 }, + } + }, + }); + + assert.strictEqual(list.$('tbody td:not(.o_list_record_selector)').length, 5, + "should have 5 cells"); + assert.strictEqual(list.$('tbody td:not(.o_list_record_selector)').first().text(), 'yop', + "value should be displayed properly as text without skype obfuscation"); + + assert.strictEqual(list.$('span.o_field_widget.o_text_overflow:not(.o_form_uri)').length, 5, + "should have spans with correct classes"); + + // Edit a line and check the result + var $cell = list.$('tbody td:not(.o_list_record_selector)').first(); + $cell.click(); + assert.ok($cell.hasClass('o_edit_mode'), 'should be set as edit mode'); + assert.strictEqual($cell.find('input').val(), 'yop', + 'should have the corect value in internal input'); + $cell.find('input').val('new').trigger('input');; + + // save + list.$buttons.find('.o_list_button_save').click(); + $cell = list.$('tbody td:not(.o_list_record_selector)').first(); + assert.ok(!$cell.hasClass('o_edit_mode'), 'should not be in edit mode anymore'); + assert.strictEqual(list.$('tbody td:not(.o_list_record_selector)').first().text(), 'new', + "value should be properly updated"); + assert.strictEqual(list.$('span.o_field_widget.o_text_overflow:not(.o_form_uri)').length, 5, + "should still have spans with correct classes"); + + list.destroy(); + }); + + QUnit.module('FieldDomain'); QUnit.test('basic domain field usage is ok', function (assert) {