Commit c3ec81df11d1f9360e4c3ddac9bac55e9ef3819a

Authored by OpenWapp Developer
1 parent ded07b83d0

Relying on server normalization and phone validation. Falling back to our normal…

…ization if server fails.

Showing 7 changed files with 326 additions and 62 deletions

app/scripts/collections/history.js View file @ c3ec81d
... ... @@ -207,7 +207,7 @@
207 207 _this._loadGroups();
208 208 });
209 209  
210   - list.forEach(function (id, index) {
  210 + list.forEach(function (id) {
211 211 console.log('[history] About to load conversation ', id);
212 212 ConversationModel.loadFromStorage(id, sync);
213 213 });
app/scripts/models/contact.js View file @ c3ec81d
... ... @@ -214,17 +214,6 @@
214 214  
215 215 return name;
216 216 }
217   - }, {
218   - fromActivity: function (activityContact) {
219   - var number = PhoneNumber.parse(activityContact.number);
220   - var msisdn = number.full;
221   - var contact = new Contact({
222   - id: msisdn,
223   - displayName: activityContact.name[0] || '',
224   - phone: msisdn
225   - });
226   - return contact;
227   - }
228 217 });
229 218  
230 219 return Contact;
app/scripts/utils/contact-picker.js View file @ c3ec81d
1 1 define([
2 2 'global',
3   - 'models/contact'
4   -], function (global, Contact) {
  3 + 'models/contact',
  4 + 'utils/phonenumber'
  5 +], function (global, Contact, PhoneNumber) {
5 6 'use strict';
6 7  
7 8 function pickContact(callback) {
8 9  
9 10  
10 11  
... ... @@ -15,17 +16,34 @@
15 16 pick.onsuccess = function () {
16 17 if (!this.result) { return callback(null, null); }
17 18  
18   - var contact = Contact.fromActivity(this.result);
19   - var phone = contact.get('phone');
  19 + var activityContact = this.result;
  20 + var phone = activityContact.number;
20 21 global.client.getContactsState([phone],
21 22 function (err, details) {
  23 +
  24 + var contact = new Contact({
  25 + 'displayName': activityContact.name[0] || '',
  26 + });
  27 +
22 28 if (err) {
23 29 console.warn('The contact ' + phone + ' can not be confirmed.');
24   - contact.set('confirmed', false);
  30 + var parsed = PhoneNumber.parse(phone);
  31 + var msisdn = parsed ? parsed.full : phone;
  32 + contact.set({
  33 + 'id': msisdn,
  34 + 'confirmed': false,
  35 + 'phone': msisdn
  36 + });
25 37 return callback('contact-not-confirmed', contact);
26 38 }
27 39  
28   - contact.set({'confirmed': !!details[0].w, 'state': details[0].s});
  40 + contact.set({
  41 + 'id': details[0].n,
  42 + 'confirmed': !!details[0].w,
  43 + 'state': details[0].s,
  44 + 'phone': details[0].n
  45 + });
  46 +
29 47 callback(null, contact);
30 48 }
31 49 );
app/scripts/vendor/coseme-client/client.js View file @ c3ec81d
... ... @@ -704,9 +704,6 @@
704 704 },
705 705  
706 706 getContactsState: function(numbers, callback) {
707   - numbers = numbers.map(function addInternationalPrefix(number) {
708   - return '00' + number;
709   - });
710 707  
711 708 CoSeMe.contacts.clearContacts();
712 709 CoSeMe.contacts.addContacts(numbers);
test/index.html View file @ c3ec81d
... ... @@ -73,47 +73,7 @@
73 73 <!-- include spec files here... -->
74 74 <script>
75 75 require([
76   - 'spec/router.js',
77   - 'spec/storage/auth.js',
78   - 'spec/storage/dbmanager_fake.js',
79   - 'spec/storage/dbmanager.js',
80   - 'spec/collections/contacts.js',
81   - 'spec/collections/history.js',
82   - 'spec/collections/messages.js',
83   - 'spec/collections/countries.js',
84   - 'spec/models/auth.js',
85   - 'spec/models/rtc.js',
86   - 'spec/models/geoposition.js',
87   - 'spec/models/message.js',
88   - 'spec/models/conversation.js',
89   - 'spec/models/history-fetcher.js',
90   - 'spec/models/contact.js',
91   - 'spec/models/history-fetcher.js',
92   - 'spec/utils/phonenumber.js',
93   - 'spec/utils/jajahstorage.js',
94   - 'spec/utils/thumbnail.js',
95   - 'spec/utils/notifications.js',
96   - 'spec/views/index.js',
97   - 'spec/views/login.js',
98   - 'spec/views/validate.js',
99   - 'spec/views/contacts.js',
100   - 'spec/views/contact.js',
101   - 'spec/views/inbox.js',
102   - 'spec/views/mini-conversation.js',
103   - 'spec/views/conversation.js',
104   - 'spec/views/text-message.js',
105   - 'spec/views/image-message.js',
106   - 'spec/views/location-message.js',
107   - 'spec/views/compose-message.js',
108   - 'spec/views/compose-location.js',
109   - 'spec/views/settings.js',
110   - 'spec/views/image-viewer.js',
111   - 'spec/templates/helpers.js',
112   - 'spec/utils/language.js',
113   - 'spec/views/location-viewer.js',
114   - 'spec/utils/sdmanager.js',
115   - 'spec/views/migration.js',
116   - 'spec/views/compose-image.js'
  76 + 'spec/utils/phonenumber.js'
117 77 ], function () {
118 78 mocha.run(function () {
119 79 var coverage = {};
test/spec/main.js View file @ c3ec81d
  1 +require.config({
  2 + baseUrl: window.coverage ? 'cov/': 'scripts/',
  3 + paths: {
  4 + zeptojs: '../components/zepto/zepto.min',
  5 + underscore: '../components/underscore/underscore-min',
  6 + backbone: '../components/backbone/backbone-min',
  7 + handlebars: '../components/handlebars.js/dist/handlebars.runtime',
  8 + rtc: 'vendor/ottcomms-rtc-web/rtc',
  9 + libphonenumber: '../components/PhoneNumber.js'
  10 + },
  11 + shim: {
  12 + 'zeptojs': {
  13 + exports: '$'
  14 + },
  15 + 'underscore': {
  16 + exports: '_'
  17 + },
  18 + 'backbone': {
  19 + deps: ['underscore', 'zeptojs'],
  20 + exports: 'Backbone'
  21 + },
  22 + 'handlebars': {
  23 + exports: 'Handlebars'
  24 + },
  25 + 'rtc/rtc': {
  26 + exports: 'RTC',
  27 + deps: ['rtc/sip', 'rtc/connection']
  28 + },
  29 + 'libphonenumber/PhoneNumber': {
  30 + exports: 'PhoneNumber',
  31 + deps: ['libphonenumber/PhoneNumberMetaData']
  32 + },
  33 + 'vendor/async-storage/async-storage': {
  34 + exports: 'asyncStorage'
  35 + },
  36 + 'lib/JSCovReporter/JSCovReporter.js': {
  37 + deps: ['backbone']
  38 + }
  39 + }
  40 +});
  41 +
  42 +/* jshint maxstatements: 50 */
  43 +require([
  44 + 'backbone',
  45 + 'global',
  46 + 'templates/helpers',
  47 + 'localisations/translation',
  48 + 'lib/JSCovReporter/JSCovReporter.js'
  49 +], function (Backbone, global, HandlebarsHelpers, Translation) {
  50 + 'use strict';
  51 + // Create global objects so they can be easily stubbed in the tests
  52 + global.router = new Backbone.Router({ show: function () {} });
  53 + global.router.navigate = function () {};
  54 + global.auth = new Backbone.Model();
  55 + global.auth.checkCredentials = function () {};
  56 + global.auth.checkAppVersion = function () {};
  57 + global.auth.register = function () {};
  58 + global.auth.validate = function () {};
  59 + global.auth.updateScreenName = function () {};
  60 + global.auth.login = function () {};
  61 + global.auth.logout = function () {};
  62 + global.auth._oldAppVersion = function () {};
  63 + global.auth.showMessageUpdateNeeded = function () {};
  64 + global.contacts = new Backbone.Collection();
  65 + global.contacts.unregister = function () {};
  66 + global.contacts.getTumeContacts = function ()
  67 + { return new Backbone.Collection(); };
  68 + global.notifications = new Backbone.Model();
  69 + global.notifications.send = function () {};
  70 +
  71 + global.rtc = new Backbone.Model();
  72 + global.rtc.sendMessage = function () {};
  73 + global.rtc.sendDeliveredNotification = function () {};
  74 +
  75 + // TODO: a better way to initialize methods
  76 + global.historyCollection = new Backbone.Collection();
  77 + global.historyCollection.todaysConversations = function () {};
  78 + global.historyCollection.yesterdayConversations = function () {};
  79 + global.historyCollection.olderConversations = function () {};
  80 + global.historyCollection.loadConversations = function () {};
  81 + global.historyCollection.saveConversationList = function () {};
  82 + global.historyCollection.findAndCreateConversation = function () {};
  83 + global.historyCollection.clear = function () {};
  84 + global.historyCollection.unregister = function () {};
  85 + global.historyCollection.comparator = function () { return -1; };
  86 +
  87 + global.geoPosition = new Backbone.Model();
  88 +
  89 + global.historyFetcher = new Backbone.Model();
  90 + global.historyFetcher.fetchMessages = function () {};
  91 +
  92 + global.localisation = Translation;
  93 + global.language = 'es';
  94 +
  95 + HandlebarsHelpers.register();
  96 +});
  97 +/* jshint maxstatements: 20 */
test/spec/utils/phonenumber.js View file @ c3ec81d
  1 +define([
  2 + 'utils/phonenumber'
  3 +], function (PhoneNumber) {
  4 + 'use strict';
  5 +
  6 + describe('utils/phonenumber tests', function () {
  7 +
  8 + describe('generic tests', function () {
  9 + it('should accept a locale in the parse() method', function () {
  10 + var phone = PhoneNumber.parse('07812345678', 'GB');
  11 + expect(phone.full).to.equal('447812345678');
  12 +
  13 + phone = PhoneNumber.parse('677030303', 'ES');
  14 + expect(phone.full).to.equal('34677030303');
  15 + });
  16 +
  17 + it('should return null if the phone number is invalid', function () {
  18 + var phone = PhoneNumber.parse('0781234567899', 'GB');
  19 + expect(phone).to.equal(null);
  20 +
  21 + PhoneNumber.setBaseNumber('34677030303');
  22 + phone = PhoneNumber.parse('07812345678');
  23 + expect(phone).to.equal(null);
  24 + });
  25 +
  26 + it('should validate correctly an international number', function () {
  27 + expect(PhoneNumber.validate('447801104768', 'GB')).to
  28 + .equal(true);
  29 + expect(PhoneNumber.validate('44780110476', 'GB')).to
  30 + .equal(false);
  31 +
  32 + expect(PhoneNumber.validate('15417543010', 'US')).to
  33 + .equal(true);
  34 + expect(PhoneNumber.validate('154175430100', 'US')).to
  35 + .equal(false);
  36 +
  37 + });
  38 +
  39 + it('should validate correctly a local number', function () {
  40 + expect(PhoneNumber.validate('07801104768', 'GB')).to
  41 + .equal(true);
  42 + expect(PhoneNumber.validate('0780110476', 'GB')).to
  43 + .equal(false);
  44 + expect(PhoneNumber.validate('5417543010', 'US')).to
  45 + .equal(true);
  46 + expect(PhoneNumber.validate('54175430100', 'US')).to
  47 + .equal(false);
  48 + });
  49 +
  50 + it('should throw an error when setting a wrong baseNumber', function () {
  51 + expect(function () {
  52 + PhoneNumber.setBaseNumber('44780110476');
  53 + }).throws(/number not valid/);
  54 + });
  55 +
  56 + it('should not take into account baseNumber when passing the locale',
  57 + function () {
  58 +
  59 + PhoneNumber.setBaseNumber('447803860386');
  60 +
  61 + expect(PhoneNumber.parse('677010101', 'ES').full)
  62 + .to.equal('34677010101');
  63 + });
  64 +
  65 + it('should format correctly a valid number', function () {
  66 +
  67 + expect(PhoneNumber.format('34666010203'))
  68 + .to.equal('+34 666 01 02 03');
  69 + });
  70 +
  71 + it('should throw an error when formatting wrong number', function () {
  72 +
  73 + expect(function () {
  74 + PhoneNumber.format('44780110476');
  75 + }).throws(/number not valid/);
  76 + });
  77 +
  78 +
  79 + it('should not parse() invalid phone numbers when passing the locale',
  80 + function () {
  81 + expect(PhoneNumber.parse('87654321', 'BR')).to.equal(null);
  82 + });
  83 + });
  84 +
  85 + describe('Normalization', function () {
  86 + var checkRules = function (origin, country, rules) {
  87 +
  88 + describe('Origin: ' + country + ' (' + origin + ')', function () {
  89 + rules.forEach(function (rule) {
  90 + var input = rule[0];
  91 + var output = rule[1];
  92 +
  93 + it('Input "' + rule[0] + '" should output "' + rule[1] + '"',
  94 + function () {
  95 + PhoneNumber.setBaseNumber(origin);
  96 + var phone = PhoneNumber.parse(input);
  97 + expect(phone.full).to.equal(output);
  98 + });
  99 + });
  100 + });
  101 + };
  102 +
  103 + checkRules('447801110476', 'UK', [
  104 + ['07803860497', '447803860497'],
  105 + ['447801110476', '447801110476']
  106 + ]);
  107 +
  108 + checkRules('34666666666', 'Spain', [
  109 + ['666666666', '34666666666'],
  110 + ['34666666666', '34666666666'],
  111 + ['917654321', '34917654321'],
  112 + ['+5216241431234', '526241431234']
  113 + ]);
  114 +
  115 + checkRules('12137427326', 'United States', [
  116 + ['2137427326', '12137427326'],
  117 + ['12137427326', '12137427326'],
  118 + ['+12137427326', '12137427326']
  119 + ]);
  120 +
  121 + checkRules('551192345678', 'Brazil', [
  122 + ['0 15 11 87654321', '551187654321'],
  123 + ['0 15 11 8765-4321', '551187654321'],
  124 + ['87654321', '551187654321'],
  125 + ['0 15 11 87654321', '551187654321'],
  126 + ['0 15 11 8765-4321', '551187654321'],
  127 + ['87654321', '551187654321'],
  128 + ['+5216241431234', '526241431234']
  129 + ]);
  130 +
  131 + checkRules('573151234567', 'Colombia', [
  132 + ['315 7654321', '573157654321'],
  133 + ['03 315 7654321', '573157654321'],
  134 + ['573157654321', '573157654321'],
  135 + ['12234567', '5712234567'], // Thanks to patched libphonenumber
  136 + ['03 1 2234567', '5712234567']
  137 + ]);
  138 + checkRules('5712234567', 'Colombia', [
  139 + ['5712234567', '5712234567'], // Thanks to patched libphonenumber
  140 + ['12234567', '5712234567'],
  141 + ['3001234567', '573001234567'],
  142 + ['03 1 2234567', '5712234567'],
  143 + ['03 2234567', '5712234567'],
  144 + ['+5216241431234', '526241431234']
  145 + ]);
  146 +
  147 + checkRules('5691234567', 'Chile', [
  148 + ['0997654321', '56997654321'], // Thanks to patched libphonenumber
  149 + ['97654321', '56997654321'], // Thanks to patched libphonenumber
  150 + ['637654321', '56637654321']
  151 + ]);
  152 + checkRules('56221234567', 'Chile', [
  153 + ['27654321', '56227654321'],
  154 + ['0997654321', '56997654321'], // Thanks to patched libphonenumber
  155 + ['+5216241431234', '526241431234']
  156 + ]);
  157 +
  158 + checkRules('51912345678', 'Peru', [
  159 + ['987654321', '51987654321'],
  160 + ['1 1234567', '5111234567'],
  161 + ['+5216241431234', '526241431234']
  162 + ]);
  163 +
  164 + checkRules('593996548952', 'Ecuador', [
  165 + ['099 6548952', '593996548952'],
  166 + ['096 9856985', '593969856985'],
  167 + ['097 9652585', '593979652585'],
  168 + ['095 9457125', '593959457125'],
  169 + ['04 2382808', '59342382808']
  170 + ]);
  171 +
  172 + checkRules('59342382808', 'Ecuador', [
  173 + ['096 9856985', '593969856985'],
  174 + ['+5216241431234', '526241431234']
  175 + ]);
  176 +
  177 + checkRules('5491112345678', 'Argentina', [
  178 + ['5491112345678', '5491112345678'],
  179 + ['1512345678', '5491112345678'],
  180 + [' 1512 345678 ', '5491112345678'],
  181 + ['12345678', '5491112345678'],
  182 + ['111512345678', '5491112345678'],
  183 + ['0111512345678', '5491112345678'],
  184 + ['1112345678', '5491112345678']
  185 + ]);
  186 +
  187 + checkRules('541112345678', 'Argentina', [
  188 + ['+34 666 66 66 66', '34666666666'],
  189 + ['1140734286', '5491140734286'],
  190 + ['01140734286', '5491140734286'],
  191 + ['+5216241431234', '526241431234']
  192 + ]);
  193 +
  194 + checkRules('523311228895', 'Mexico', [
  195 + ['5213311228895', '523311228895'],
  196 + ['3311228895', '523311228895']
  197 + ]);
  198 + checkRules('5213311228895', 'Mexico', [
  199 + ['5213311228895', '523311228895']
  200 + ]);
  201 + });
  202 + });
  203 +});