From 8f5a591ab08ee430fbdfd53c56eddcaee31cba16 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 27 Apr 2012 10:06:07 +0200 Subject: [PATCH] [TESTS] completion call on various widgets, fixed corresponding implementations bzr revid: xmo@openerp.com-20120427080607-1bw1jpmu7h6zxdin --- addons/web/static/src/js/search.js | 44 +++++---- addons/web/static/test/search.js | 142 ++++++++++++++++++++++++++++- 2 files changed, 167 insertions(+), 19 deletions(-) diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 5ef6db42f2b..8780e1cbd81 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -1076,9 +1076,12 @@ instance.web.search.CharField = instance.web.search.Field.extend( /** @lends ins field: '' + this.attrs.string + '', value: '' + _.str.escapeHTML(value) + ''}); return $.when([{ - category: this.attrs.string, label: label, - value: [{label: label, value: value}] + facet: { + category: this.attrs.string, + field: this, + values: [{label: value, value: value}] + } }]); } }); @@ -1158,16 +1161,18 @@ instance.web.search.SelectionField = instance.web.search.Field.extend(/** @lends return label.toLowerCase().indexOf(needle.toLowerCase()) !== -1; }) .map(function (sel) { - // FIXME fucking repetition man, find something better return { - category: self.attrs.string, - value: sel[1], - values: [{value: sel[0], label: sel[1]}] + label: sel[1], + facet: { + category: self.attrs.string, + field: self, + values: [{value: sel[0], label: sel[1]}] + } }; }).value(); if (_.isEmpty(results)) { return $.when(null); } - return $.when.apply(null, [{ - category: this.attrs.string + return $.when.call(null, [{ + label: this.attrs.string }].concat(results)); }, facet_for: function (value) { @@ -1216,16 +1221,18 @@ instance.web.search.DateField = instance.web.search.Field.extend(/** @lends inst complete: function (needle) { var d = Date.parse(needle); if (!d) { return $.when(null); } - var value = instance.web.format_value(d, this.attrs); + var date_string = instance.web.format_value(d, this.attrs); var label = _.str.sprintf(_.str.escapeHTML( _t("Search %(field)s at: %(value)s")), { field: '' + this.attrs.string + '', - value: '' + value + ''}); + value: '' + date_string + ''}); return $.when([{ - category: this.attrs.string, label: label, - // FIXME: brain broken - values: [{label: value, value: d}] + facet: { + category: this.attrs.string, + field: this, + values: [{label: date_string, value: d}] + } }]); } }); @@ -1260,12 +1267,15 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({ context: {} }).pipe(function (results) { if (_.isEmpty(results)) { return null; } - return [{category: self.attrs.string}].concat( + return [{label: self.attrs.string}].concat( _(results).map(function (result) { return { - category: self.attrs.string, - value: result[1], - values: [{label: result[1], value: result[0]}] + label: result[1], + facet: { + category: self.attrs.string, + field: self, + values: [{label: result[1], value: result[0]}] + } }; })); }); diff --git a/addons/web/static/test/search.js b/addons/web/static/test/search.js index 8f15b86b2e7..53f32e875d2 100644 --- a/addons/web/static/test/search.js +++ b/addons/web/static/test/search.js @@ -153,6 +153,8 @@ $(document).ready(function () { window.openerp.web.coresetup(instance); window.openerp.web.chrome(instance); window.openerp.web.data(instance); + // date complete + window.openerp.web.formats(instance); window.openerp.web.search(instance); instance.web.qweb.add_template(doc); @@ -373,7 +375,6 @@ $(document).ready(function () { ok(!facet, "an invalid m2o default should yield a non-facet"); }); }); - // TODO: test defaults for various built-in widgets? asyncTest('completion calling', 4, function () { var view = makeSearchView({ complete: function () { @@ -406,7 +407,7 @@ $(document).ready(function () { }); }); }); - // TODO: test completions for various built-in widgets? + asyncTest('completion facet selection', 2, function () { var completion = { label: "Dummy", @@ -462,6 +463,143 @@ $(document).ready(function () { "should have added selected value to old one"); }); }); + asyncTest('Field completion', 1, function () { + var view = {inputs: []}; + var f = new instance.web.search.Field({attrs: {}}, {}, view); + f.complete('foo') + .always(start) + .fail(function (error) { ok(false, error.message); }) + .done(function (completions) { + ok(_(completions).isEmpty(), "field should not provide any completion"); + }); + }); + asyncTest('CharField completion', 6, function () { + var view = {inputs: []}; + var f = new instance.web.search.CharField( + {attrs: {string: "Dummy"}}, {}, view); + f.complete('foo<') + .always(start) + .fail(function (error) { ok(false, error.message); }) + .done(function (completions) { + equal(completions.length, 1, "should provide a single completion"); + var c = completions[0]; + equal(c.label, "Search Dummy for: foo<", + "should propose a fuzzy matching/searching, with the" + + " value escaped"); + ok(c.facet, "completion should contain a facet proposition"); + var facet = new instance.web.search.Facet(c.facet); + equal(facet.get('category'), f.attrs.string, + "completion facet should bear the field's name"); + strictEqual(facet.get('field'), f, + "completion facet should yield the field"); + deepEqual(facet.values.toJSON(), [{label: 'foo<', value: 'foo<'}], + "facet should have single value using completion item"); + }); + }); + asyncTest('Selection completion: match found', 14, function () { + var view = {inputs: []}; + var f = new instance.web.search.SelectionField( + {attrs: {string: "Dummy"}}, + {selection: [[1, "Foo"], [2, "Bar"], [3, "Baz"], [4, "Bazador"]]}, + view); + f.complete("ba") + .always(start) + .fail(function (error) { ok(false, error.message); }) + .done(function (completions) { + equal(completions.length, 4, + "should provide two completions and a section title"); + deepEqual(completions[0], {label: "Dummy"}); + + var c1 = completions[1]; + equal(c1.label, "Bar"); + equal(c1.facet.category, f.attrs.string); + strictEqual(c1.facet.field, f); + deepEqual(c1.facet.values, [{label: "Bar", value: 2}]); + + var c2 = completions[2]; + equal(c2.label, "Baz"); + equal(c2.facet.category, f.attrs.string); + strictEqual(c2.facet.field, f); + deepEqual(c2.facet.values, [{label: "Baz", value: 3}]); + + var c3 = completions[3]; + equal(c3.label, "Bazador"); + equal(c3.facet.category, f.attrs.string); + strictEqual(c3.facet.field, f); + deepEqual(c3.facet.values, [{label: "Bazador", value: 4}]); + }); + }); + asyncTest('Selection completion: no match', 1, function () { + var view = {inputs: []}; + var f = new instance.web.search.SelectionField( + {attrs: {string: "Dummy"}}, + {selection: [[1, "Foo"], [2, "Bar"], [3, "Baz"], [4, "Bazador"]]}, + view); + f.complete("qux") + .always(start) + .fail(function (error) { ok(false, error.message); }) + .done(function (completions) { + ok(!completions, "if no value matches the needle, no completion shall be provided"); + }); + }); + asyncTest('Date completion', 6, function () { + instance.web._t.database.parameters = { + date_format: '%Y-%m-%d', + time_format: '%H:%M:%S' + }; + var view = {inputs: []}; + var f = new instance.web.search.DateField( + {attrs: {string: "Dummy"}}, {type: 'datetime'}, view); + f.complete('2012-05-21T21:21:21') + .always(start) + .fail(function (error) { ok(false, error.message); }) + .done(function (completions) { + equal(completions.length, 1, "should provide a single completion"); + var c = completions[0]; + equal(c.label, "Search Dummy at: 2012-05-21 21:21:21"); + var facet = new instance.web.search.Facet(c.facet); + equal(facet.get('category'), f.attrs.string); + equal(facet.get('field'), f); + var value = facet.values.at(0); + equal(value.get('label'), "2012-05-21 21:21:21"); + equal(value.get('value').getTime(), + new Date(2012, 4, 21, 21, 21, 21).getTime()); + }); + }); + asyncTest("M2O completion", 15, function () { + instance.connection.responses['/web/dataset/call_kw'] = function (req) { + equal(req.params.method, "name_search"); + equal(req.params.model, "dummy.model"); + deepEqual(req.params.args, []); + deepEqual(req.params.kwargs.name, 'bob'); + return {result: [[42, "choice 1"], [43, "choice @"]]} + }; + + var view = {inputs: []}; + var f = new instance.web.search.ManyToOneField( + {attrs: {string: 'Dummy'}}, {relation: 'dummy.model'}, view); + f.complete("bob") + .always(start) + .fail(function (error) { ok(false, error.message); }) + .done(function (c) { + equal(c.length, 3, "should return results + title"); + var title = c[0]; + equal(title.label, f.attrs.string, "title should match field name"); + ok(!title.facet, "title should not have a facet"); + + var f1 = new instance.web.search.Facet(c[1].facet); + equal(c[1].label, "choice 1"); + equal(f1.get('category'), f.attrs.string); + equal(f1.get('field'), f); + deepEqual(f1.values.toJSON(), [{label: 'choice 1', value: 42}]); + + var f2 = new instance.web.search.Facet(c[2].facet); + equal(c[2].label, "choice @"); + equal(f2.get('category'), f.attrs.string); + equal(f2.get('field'), f); + deepEqual(f2.values.toJSON(), [{label: 'choice @', value: 43}]); + }); + }); // TODO: test drawer rendering // TODO: UI tests?