Merge lp:~rharding/launchpad/bug_yui35_four into lp:launchpad

Proposed by Richard Harding on 2012-06-28
Status: Merged
Approved by: j.c.sackett on 2012-06-28
Approved revision: no longer in the source branch.
Merged at revision: 15526
Proposed branch: lp:~rharding/launchpad/bug_yui35_four
Merge into: lp:launchpad
Diff against target: 1322 lines (+594/-643)
7 files modified
lib/lp/bugs/javascript/filebug_dupefinder.js (+1/-1)
lib/lp/bugs/javascript/tests/test_filebug_dupefinder.html (+1/-1)
lib/lp/bugs/javascript/tests/test_filebug_dupefinder.js (+311/-319)
lib/lp/bugs/javascript/tests/test_me_too.html (+1/-1)
lib/lp/bugs/javascript/tests/test_me_too.js (+202/-217)
lib/lp/bugs/javascript/tests/test_pre_search.html (+1/-1)
lib/lp/bugs/javascript/tests/test_pre_search.js (+77/-103)
To merge this branch: bzr merge lp:~rharding/launchpad/bug_yui35_four
Reviewer Review Type Date Requested Status
j.c.sackett (community) 2012-06-28 Approve on 2012-06-28
Review via email: mp+112609@code.launchpad.net

Commit Message

Update the rest of the bugs test files to run properly in YUI 3.5.

Description of the Change

= Summary =

This branch helps update the rest of the bugs test suites in the bug JS to work in YUI3.5 and to use our common test runner.

== Implementation Notes ==

Updating the tests is mostly just reorganizing them to add an actual module.

== Tests ==

./bin/test -x -cvv --layer=YUITestLayer

== Lint ==

Updated for lint since we indented a lot of code.

== LoC Qualification ==

It's a negative LoC change.

To post a comment you must log in.
j.c.sackett (jcsackett) wrote :

Looks fine. Thanks, Rick.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/javascript/filebug_dupefinder.js'
2--- lib/lp/bugs/javascript/filebug_dupefinder.js 2012-06-26 00:15:11 +0000
3+++ lib/lp/bugs/javascript/filebug_dupefinder.js 2012-06-28 18:18:19 +0000
4@@ -210,7 +210,7 @@
5
6 // Copy the value from the search field into the title field
7 // on the filebug form.
8- Y.one('#bug-reporting-form input[name=field.title]').set(
9+ Y.one('#bug-reporting-form input[name="field.title"]').set(
10 'value', search_field.get('value'));
11
12 // Finally, change the label on the search button and show it again.
13
14=== modified file 'lib/lp/bugs/javascript/tests/test_filebug_dupefinder.html'
15--- lib/lp/bugs/javascript/tests/test_filebug_dupefinder.html 2012-03-14 04:41:36 +0000
16+++ lib/lp/bugs/javascript/tests/test_filebug_dupefinder.html 2012-06-28 18:18:19 +0000
17@@ -54,7 +54,7 @@
18 <body class="yui3-skin-sam">
19 <ul id="suites">
20 <!-- <li>lp.large_indicator.test</li> -->
21- <li>lp.filebug_dupefinder.test</li>
22+ <li>lp.bugs.filebug_dupefinder.test</li>
23 </ul>
24
25 <!-- Example markup required by test suite -->
26
27=== modified file 'lib/lp/bugs/javascript/tests/test_filebug_dupefinder.js'
28--- lib/lp/bugs/javascript/tests/test_filebug_dupefinder.js 2012-02-10 17:21:16 +0000
29+++ lib/lp/bugs/javascript/tests/test_filebug_dupefinder.js 2012-06-28 18:18:19 +0000
30@@ -1,341 +1,333 @@
31-YUI({
32- base: '../../../../canonical/launchpad/icing/yui/',
33- filter: 'raw', combine: false, fetchCSS: false
34- }).use('test', 'console', 'lp.bugs.filebug_dupefinder',
35- 'node-event-simulate', function(Y) {
36-
37-var suite = new Y.Test.Suite("lp.bugs.filebug_dupefinder Tests");
38-var module = Y.lp.bugs.filebug_dupefinder;
39-
40-/*
41- * A wrapper for the Y.Event.simulate() function. The wrapper accepts
42- * CSS selectors and Node instances instead of raw nodes.
43- */
44-function simulate(widget, selector, evtype, options) {
45- var node_to_use = widget;
46- if (selector !== undefined) {
47- node_to_use = widget.one(selector);
48- }
49- var rawnode = Y.Node.getDOMNode(node_to_use);
50- Y.Event.simulate(rawnode, evtype, options);
51-}
52-
53-/**
54- * A stub io handler.
55- */
56-function IOStub(test_case){
57- if (!(this instanceof IOStub)) {
58- throw new Error("Constructor called as a function");
59- }
60- this.calls = [];
61- this.io = function(url, config) {
62- this.calls.push(url);
63- var response = {responseText: ''};
64- // We may have been passed text to use in the response.
65- if (Y.Lang.isValue(arguments.callee.responseText)) {
66- response.responseText = arguments.callee.responseText;
67- }
68- // We currently only support calling the success handler.
69- config.on.success(undefined, response, arguments.callee.args);
70- // After calling the handler, resume the test.
71- if (Y.Lang.isFunction(arguments.callee.doAfter)) {
72- test_case.resume(arguments.callee.doAfter);
73- }
74- };
75-}
76-
77-suite.add(new Y.Test.Case({
78- name: 'Test filebug form manipulation.',
79-
80- setUp: function() {
81- // Reset the HTML elements.
82- Y.one("#possible-duplicates").set('innerHTML', '');
83- Y.one(Y.DOM.byId('field.comment')).set('value', '');
84- var node = Y.one(Y.DOM.byId('field.search'));
85- if (node !== null) {
86- node.set('value', '');
87- }
88- node = Y.one(Y.DOM.byId('field.title'));
89- if (node !== null) {
90- node.set('value', '');
91- }
92- Y.one('#filebug-form-container').addClass('transparent')
93- .setStyles({opacity: '0', display: 'none'});
94-
95- this.config = {};
96- this.config.yio = new IOStub(this);
97- module.setup_config(this.config);
98- },
99-
100- tearDown: function() {
101- Y.one('#filebug-form').set(
102- 'action', 'https://bugs.launchpad.dev/foo/+filebug');
103- },
104-
105- /**
106- * Some helper functions
107- */
108- selectNode: function(node, selector) {
109- if (!Y.Lang.isValue(node)) {
110- node = Y.one('#test-root');
111- }
112- var node_to_use = node;
113- if (Y.Lang.isValue(selector)) {
114- node_to_use = node.one(selector);
115- }
116- return node_to_use;
117- },
118-
119- assertIsVisible: function(node, selector) {
120- node = this.selectNode(node, selector);
121- Y.Assert.areNotEqual('none', node.getStyle('display'));
122- },
123-
124- assertIsNotVisible: function(node, selector) {
125- node = this.selectNode(node, selector);
126- Y.Assert.areEqual('none', node.getStyle('display'));
127- },
128-
129- assertNodeText: function(node, selector, text) {
130- node = this.selectNode(node, selector);
131- Y.Assert.areEqual(text, node.get('innerHTML'));
132- },
133-
134-
135- /**
136- * A user first searches for duplicate bugs. If there are no duplicates
137- * the file bug form should be visible for bug details to be entered.
138- */
139- test_no_dups_search_shows_filebug_form: function() {
140- // filebug container should not initially be visible
141- this.assertIsNotVisible(null, '#filebug-form-container');
142- var search_text = Y.one(Y.DOM.byId('field.search'));
143- search_text.set('value', 'foo');
144- var search_button = Y.one(Y.DOM.byId('field.actions.search'));
145- // The search button should initially say 'Next'
146- Y.Assert.areEqual('Next', search_button.get('value'));
147- this.config.yio.io.responseText = 'No similar bug reports.';
148- this.config.yio.io.doAfter = function() {
149- // Check the expected io calls have been made.
150- Y.ArrayAssert.itemsAreEqual(
151- ['https://bugs.launchpad.dev/' +
152- 'foo/+filebug-show-similar?title=foo'],
153- this.config.yio.calls);
154- // filebug container should be visible after the dup search
155- this.assertIsVisible(null, '#filebug-form-container');
156- var dups_node = Y.one("#possible-duplicates");
157- this.assertNodeText(
158- dups_node, undefined, 'No similar bug reports.');
159+/* Copyright (c) 2012, Canonical Ltd. All rights reserved. */
160+YUI.add('lp.bugs.filebug_dupefinder.test', function (Y) {
161+ var module = Y.lp.bugs.filebug_dupefinder;
162+
163+ /*
164+ * A wrapper for the Y.Event.simulate() function. The wrapper accepts
165+ * CSS selectors and Node instances instead of raw nodes.
166+ */
167+ function simulate(widget, selector, evtype, options) {
168+ var node_to_use = widget;
169+ if (selector !== undefined) {
170+ node_to_use = widget.one(selector);
171+ }
172+ var rawnode = Y.Node.getDOMNode(node_to_use);
173+ Y.Event.simulate(rawnode, evtype, options);
174+ }
175+
176+ /**
177+ * A stub io handler.
178+ */
179+ function IOStub(test_case){
180+ if (!(this instanceof IOStub)) {
181+ throw new Error("Constructor called as a function");
182+ }
183+ this.calls = [];
184+ this.io = function(url, config) {
185+ this.calls.push(url);
186+ var response = {responseText: ''};
187+ // We may have been passed text to use in the response.
188+ if (Y.Lang.isValue(arguments.callee.responseText)) {
189+ response.responseText = arguments.callee.responseText;
190+ }
191+ // We currently only support calling the success handler.
192+ config.on.success(undefined, response, arguments.callee.args);
193+ // After calling the handler, resume the test.
194+ if (Y.Lang.isFunction(arguments.callee.doAfter)) {
195+ test_case.resume(arguments.callee.doAfter);
196+ }
197 };
198- simulate(search_button, undefined, 'click');
199- this.wait();
200- },
201-
202- /**
203- * A user first searches for duplicate bugs. If there are duplicates
204- * the dups should be listed and the file bug form should not be visible.
205- */
206- test_dups_search_shows_dup_info: function() {
207- // filebug container should not initially be visible
208- this.assertIsNotVisible(null, '#filebug-form-container');
209- var search_text = Y.one(Y.DOM.byId('field.search'));
210- search_text.set('value', 'foo');
211- var search_button = Y.one(Y.DOM.byId('field.actions.search'));
212- this.config.yio.io.responseText = ([
213- '<table><tr><td id="bug-details-expander" ',
214- 'class="bug-already-reported-expander"></td></tr></table>',
215- '<input type="button" value="No, I need to report a new bug"',
216- ' name="field.bug_already_reported_as"',
217- ' id="bug-not-already-reported" style="display: block">',
218- ].join(''));
219- this.config.yio.io.doAfter = function() {
220- // filebug container should not be visible when there are dups
221+ }
222+
223+ // Configure the javascript module under test. In production, the
224+ // setup_dupe_finder() is called from the page template. We need to pass
225+ // in a stub io handler here so that the XHR call made during set up is
226+ // ignored.
227+ var config = {};
228+ config.yio = new IOStub();
229+ module.setup_config(config);
230+ module.setup_dupe_finder();
231+
232+ var tests = Y.namespace('lp.bugs.filebug_dupefinder.test');
233+ tests.suite = new Y.Test.Suite('bugs.filebug_dupefinder Tests');
234+
235+ tests.suite.add(new Y.Test.Case({
236+ name: 'Test filebug form manipulation.',
237+
238+ setUp: function() {
239+ // Reset the HTML elements.
240+ Y.one("#possible-duplicates").set('innerHTML', '');
241+ Y.one(Y.DOM.byId('field.comment')).set('value', '');
242+ var node = Y.one(Y.DOM.byId('field.search'));
243+ if (node !== null) {
244+ node.set('value', '');
245+ }
246+ node = Y.one(Y.DOM.byId('field.title'));
247+ if (node !== null) {
248+ node.set('value', '');
249+ }
250+ Y.one('#filebug-form-container').addClass('transparent')
251+ .setStyles({opacity: '0', display: 'none'});
252+
253+ this.config = {};
254+ this.config.yio = new IOStub(this);
255+ module.setup_config(this.config);
256+ },
257+
258+ tearDown: function() {
259+ Y.one('#filebug-form').set(
260+ 'action', 'https://bugs.launchpad.dev/foo/+filebug');
261+ },
262+
263+ /**
264+ * Some helper functions
265+ */
266+ selectNode: function(node, selector) {
267+ if (!Y.Lang.isValue(node)) {
268+ node = Y.one('#test-root');
269+ }
270+ var node_to_use = node;
271+ if (Y.Lang.isValue(selector)) {
272+ node_to_use = node.one(selector);
273+ }
274+ return node_to_use;
275+ },
276+
277+ assertIsVisible: function(node, selector) {
278+ node = this.selectNode(node, selector);
279+ Y.Assert.areNotEqual('none', node.getStyle('display'));
280+ },
281+
282+ assertIsNotVisible: function(node, selector) {
283+ node = this.selectNode(node, selector);
284+ Y.Assert.areEqual('none', node.getStyle('display'));
285+ },
286+
287+ assertNodeText: function(node, selector, text) {
288+ node = this.selectNode(node, selector);
289+ Y.Assert.areEqual(text, node.get('innerHTML'));
290+ },
291+
292+
293+ /**
294+ * A user first searches for duplicate bugs. If there are no duplicates
295+ * the file bug form should be visible for bug details to be entered.
296+ */
297+ test_no_dups_search_shows_filebug_form: function() {
298+ // filebug container should not initially be visible
299 this.assertIsNotVisible(null, '#filebug-form-container');
300- // we should have a 'new bug' button
301- this.assertIsVisible(null, '#bug-not-already-reported');
302- // The search button should say 'Check again'
303- Y.Assert.areEqual('Check again', search_button.get('value'));
304- };
305- simulate(search_button, undefined, 'click');
306- this.wait();
307- },
308-
309- /**
310- * A user first searches for duplicate bugs. They can start typing in some
311- * detail. They can search again for dups and their input should be
312- * retained.
313- */
314- test_dups_search_retains_user_input_when_no_dups: function() {
315- // filebug container should not initially be visible
316- this.assertIsNotVisible(null, '#filebug-form-container');
317- var search_text = Y.one(Y.DOM.byId('field.search'));
318- search_text.set('value', 'foo');
319- var search_button = Y.one(Y.DOM.byId('field.actions.search'));
320- this.config.yio.io.responseText = 'No similar bug reports.';
321- this.config.yio.io.doAfter = function() {
322- var comment_text = Y.one(Y.DOM.byId('field.comment'));
323- comment_text.set('value', 'an error occurred');
324+ var search_text = Y.one(Y.DOM.byId('field.search'));
325+ search_text.set('value', 'foo');
326+ var search_button = Y.one(Y.DOM.byId('field.actions.search'));
327+ // The search button should initially say 'Next'
328+ Y.Assert.areEqual('Next', search_button.get('value'));
329+ this.config.yio.io.responseText = 'No similar bug reports.';
330 this.config.yio.io.doAfter = function() {
331- // The user input should be retained
332- Y.Assert.areEqual(
333- 'an error occurred', comment_text.get('value'));
334+ // Check the expected io calls have been made.
335+ Y.ArrayAssert.itemsAreEqual(
336+ ['https://bugs.launchpad.dev/' +
337+ 'foo/+filebug-show-similar?title=foo'],
338+ this.config.yio.calls);
339+ // filebug container should be visible after the dup search
340+ this.assertIsVisible(null, '#filebug-form-container');
341+ var dups_node = Y.one("#possible-duplicates");
342+ this.assertNodeText(
343+ dups_node, undefined, 'No similar bug reports.');
344 };
345 simulate(search_button, undefined, 'click');
346 this.wait();
347- };
348- simulate(search_button, undefined, 'click');
349- this.wait();
350- },
351+ },
352
353- /**
354- * A user first searches for duplicate bugs and there are none.
355- * They can start typing in some detail. They can search again for dups
356- * and their input should be retained even when there are dups and they
357- * have to click the "No, this is a new bug" button.
358- */
359- test_dups_search_retains_user_input_when_dups: function() {
360- // filebug container should not initially be visible
361- this.assertIsNotVisible(null, '#filebug-form-container');
362- var search_text = Y.one(Y.DOM.byId('field.search'));
363- search_text.set('value', 'foo');
364- var search_button = Y.one(Y.DOM.byId('field.actions.search'));
365- this.config.yio.io.responseText = 'No similar bug reports.';
366- this.config.yio.io.doAfter = function() {
367- var comment_text = Y.one(Y.DOM.byId('field.comment'));
368- comment_text.set('value', 'an error occurred');
369+ /**
370+ * A user first searches for duplicate bugs. If there are duplicates
371+ * the dups should be listed and the file bug form should not be
372+ * visible.
373+ */
374+ test_dups_search_shows_dup_info: function() {
375+ // filebug container should not initially be visible
376+ this.assertIsNotVisible(null, '#filebug-form-container');
377+ var search_text = Y.one(Y.DOM.byId('field.search'));
378+ search_text.set('value', 'foo');
379+ var search_button = Y.one(Y.DOM.byId('field.actions.search'));
380 this.config.yio.io.responseText = ([
381- '<img id="bug-details-expander" ',
382- 'class="bug-already-reported-expander" ',
383- 'src="/@@/treeCollapsed">',
384- '<input type="button" value="No, I need to report a bug"',
385- ' name="field.bug_already_reported_as"',
386+ '<table><tr><td id="bug-details-expander" ',
387+ 'class="bug-already-reported-expander"></td></tr></table>',
388+ '<input type="button" value="No, I need to report a new',
389+ ' bug" name="field.bug_already_reported_as"',
390 ' id="bug-not-already-reported" style="display: block">'
391 ].join(''));
392 this.config.yio.io.doAfter = function() {
393- var new_bug_button = Y.one('#bug-not-already-reported');
394- simulate(new_bug_button, undefined, 'click');
395- // filebug container should be visible
396- this.assertIsVisible(null, '#filebug-form-container');
397- // The user input should be retained
398- Y.Assert.areEqual(
399- 'an error occurred', comment_text.get('value'));
400- };
401- simulate(search_button, undefined, 'click');
402- this.wait();
403- };
404- simulate(search_button, undefined, 'click');
405- this.wait();
406- },
407-
408- /**
409- * The filebug form url is correctly set when the page loads.
410- */
411- test_project_initial_filebug_form_action: function() {
412- Y.Assert.areEqual(
413- 'https://bugs.launchpad.dev/foo/+filebug',
414- Y.one('#filebug-form').get('action'));
415- },
416-
417- add_project_selector: function() {
418- var project_selector = Y.Node.create([
419- '<tr>',
420- ' <td>',
421- ' <label for="field.product">Project:</label>',
422- ' <select size="1" name="field.product" id="field.product">',
423- ' <option value="foo">Foo</option>',
424- ' <option value="bar">Bar</option>',
425- ' </select>',
426- ' </td>',
427- '</tr>'
428- ].join(''));
429- Y.one('#search-field').insert(project_selector, 'before');
430- module.setup_product_urls();
431- },
432-
433- /**
434- * The filebug form url is correctly updated when the project changes.
435- */
436- test_project_change_filebug_form_action: function() {
437- this.add_project_selector();
438- var project = Y.one(Y.DOM.byId('field.product'));
439- project.set('value', 'bar');
440- simulate(project, undefined, 'change');
441- Y.Assert.areEqual(
442- 'https://bugs.launchpad.dev/bar/+filebug',
443- Y.one('#filebug-search-form').get('action'));
444- },
445-
446- /**
447- * A user first searches for duplicate bugs and there are none.
448- * They can start typing in some detail. They change the project and
449- * perform a new search. Their input should be retained.
450- */
451- test_project_change_retains_user_input_after_dups_serach: function() {
452- Y.one(Y.DOM.byId('field.product')).set('value', 'foo');
453- module.setup_product_urls();
454- // filebug container should not initially be visible
455- this.assertIsNotVisible(null, '#filebug-form-container');
456- var search_text = Y.one(Y.DOM.byId('field.search'));
457- search_text.set('value', 'foo');
458- var search_button = Y.one(Y.DOM.byId('field.actions.search'));
459- this.config.yio.io.responseText = 'No similar bug reports.';
460- this.config.yio.io.doAfter = function() {
461- var comment_text = Y.one(Y.DOM.byId('field.comment'));
462- comment_text.set('value', 'an error occurred');
463-
464- this.config.yio.io.responseText = 'Bug filing details';
465+ // filebug container should not be visible when there are dups
466+ this.assertIsNotVisible(null, '#filebug-form-container');
467+ // we should have a 'new bug' button
468+ this.assertIsVisible(null, '#bug-not-already-reported');
469+ // The search button should say 'Check again'
470+ Y.Assert.areEqual('Check again', search_button.get('value'));
471+ };
472+ simulate(search_button, undefined, 'click');
473+ this.wait();
474+ },
475+
476+ /**
477+ * A user first searches for duplicate bugs. They can start typing in
478+ * some detail. They can search again for dups and their input should
479+ * be retained.
480+ */
481+ test_dups_search_retains_user_input_when_no_dups: function() {
482+ // filebug container should not initially be visible
483+ this.assertIsNotVisible(null, '#filebug-form-container');
484+ var search_text = Y.one(Y.DOM.byId('field.search'));
485+ search_text.set('value', 'foo');
486+ var search_button = Y.one(Y.DOM.byId('field.actions.search'));
487+ this.config.yio.io.responseText = 'No similar bug reports.';
488+ this.config.yio.io.doAfter = function() {
489+ var comment_text = Y.one(Y.DOM.byId('field.comment'));
490+ comment_text.set('value', 'an error occurred');
491+ this.config.yio.io.doAfter = function() {
492+ // The user input should be retained
493+ Y.Assert.areEqual(
494+ 'an error occurred', comment_text.get('value'));
495+ };
496+ simulate(search_button, undefined, 'click');
497+ this.wait();
498+ };
499+ simulate(search_button, undefined, 'click');
500+ this.wait();
501+ },
502+
503+ /**
504+ * A user first searches for duplicate bugs and there are none.
505+ * They can start typing in some detail. They can search again for dups
506+ * and their input should be retained even when there are dups and they
507+ * have to click the "No, this is a new bug" button.
508+ */
509+ test_dups_search_retains_user_input_when_dups: function() {
510+ // filebug container should not initially be visible
511+ this.assertIsNotVisible(null, '#filebug-form-container');
512+ var search_text = Y.one(Y.DOM.byId('field.search'));
513+ search_text.set('value', 'foo');
514+ var search_button = Y.one(Y.DOM.byId('field.actions.search'));
515+ this.config.yio.io.responseText = 'No similar bug reports.';
516+ this.config.yio.io.doAfter = function() {
517+ var comment_text = Y.one(Y.DOM.byId('field.comment'));
518+ comment_text.set('value', 'an error occurred');
519+ this.config.yio.io.responseText = ([
520+ '<img id="bug-details-expander" ',
521+ 'class="bug-already-reported-expander" ',
522+ 'src="/@@/treeCollapsed">',
523+ '<input type="button" value="No, I need to report a',
524+ ' bug" name="field.bug_already_reported_as"',
525+ ' id="bug-not-already-reported" style="display: block">'
526+ ].join(''));
527+ this.config.yio.io.doAfter = function() {
528+ var new_bug_button = Y.one('#bug-not-already-reported');
529+ simulate(new_bug_button, undefined, 'click');
530+ // filebug container should be visible
531+ this.assertIsVisible(null, '#filebug-form-container');
532+ // The user input should be retained
533+ Y.Assert.areEqual(
534+ 'an error occurred', comment_text.get('value'));
535+ };
536+ simulate(search_button, undefined, 'click');
537+ this.wait();
538+ };
539+ simulate(search_button, undefined, 'click');
540+ this.wait();
541+ },
542+
543+ /**
544+ * The filebug form url is correctly set when the page loads.
545+ */
546+ test_project_initial_filebug_form_action: function() {
547+ Y.Assert.areEqual(
548+ 'https://bugs.launchpad.dev/foo/+filebug',
549+ Y.one('#filebug-form').get('action'));
550+ },
551+
552+ add_project_selector: function() {
553+ var project_selector = Y.Node.create([
554+ '<tr>',
555+ ' <td>',
556+ ' <label for="field.product">Project:</label>',
557+ ' <select size="1" name="field.product" id="field.product">',
558+ ' <option value="foo">Foo</option>',
559+ ' <option value="bar">Bar</option>',
560+ ' </select>',
561+ ' </td>',
562+ '</tr>'
563+ ].join(''));
564+ Y.one('#search-field').insert(project_selector, 'before');
565+ module.setup_product_urls();
566+ },
567+
568+ /**
569+ * The filebug form url is correctly updated when the project changes.
570+ */
571+ test_project_change_filebug_form_action: function() {
572+ this.add_project_selector();
573 var project = Y.one(Y.DOM.byId('field.product'));
574 project.set('value', 'bar');
575 simulate(project, undefined, 'change');
576- // filebug container should be visible
577- this.assertIsVisible(null, '#filebug-form-container');
578-
579- // Search button should day 'Check again' because we have already
580- // done a search.
581- var search_button = (Y.one(Y.DOM.byId('field.actions.search')));
582- Y.Assert.areEqual('Check again', search_button.get('value'));
583-
584+ Y.Assert.areEqual(
585+ 'https://bugs.launchpad.dev/bar/+filebug',
586+ Y.one('#filebug-search-form').get('action'));
587+ },
588+
589+ /**
590+ * A user first searches for duplicate bugs and there are none.
591+ * They can start typing in some detail. They change the project and
592+ * perform a new search. Their input should be retained.
593+ */
594+ test_project_change_retains_user_input_after_dups_serach: function() {
595+ Y.one(Y.DOM.byId('field.product')).set('value', 'foo');
596+ module.setup_product_urls();
597+ // filebug container should not initially be visible
598+ this.assertIsNotVisible(null, '#filebug-form-container');
599+ var search_text = Y.one(Y.DOM.byId('field.search'));
600+ search_text.set('value', 'foo');
601+ var search_button = Y.one(Y.DOM.byId('field.actions.search'));
602 this.config.yio.io.responseText = 'No similar bug reports.';
603 this.config.yio.io.doAfter = function() {
604+ var comment_text = Y.one(Y.DOM.byId('field.comment'));
605+ comment_text.set('value', 'an error occurred');
606+
607+ this.config.yio.io.responseText = 'Bug filing details';
608+ var project = Y.one(Y.DOM.byId('field.product'));
609+ project.set('value', 'bar');
610+ simulate(project, undefined, 'change');
611 // filebug container should be visible
612 this.assertIsVisible(null, '#filebug-form-container');
613- // The user input should be retained
614- Y.Assert.areEqual(
615- 'an error occurred', comment_text.get('value'));
616- Y.ArrayAssert.itemsAreEqual(
617- ['https://bugs.launchpad.dev/' +
618- 'foo/+filebug-show-similar?title=foo',
619- 'https://bugs.launchpad.dev/' +
620- 'bar/+filebug-show-similar?title=foo'],
621- this.config.yio.calls);
622+
623+ // Search button should day 'Check again' because we have
624+ // already done a search.
625+ var search_button = (Y.one(Y.DOM.byId('field.actions.search')));
626+ Y.Assert.areEqual('Check again', search_button.get('value'));
627+
628+ this.config.yio.io.responseText = 'No similar bug reports.';
629+ this.config.yio.io.doAfter = function() {
630+ // filebug container should be visible
631+ this.assertIsVisible(null, '#filebug-form-container');
632+ // The user input should be retained
633+ Y.Assert.areEqual(
634+ 'an error occurred', comment_text.get('value'));
635+ Y.ArrayAssert.itemsAreEqual(
636+ ['https://bugs.launchpad.dev/' +
637+ 'foo/+filebug-show-similar?title=foo',
638+ 'https://bugs.launchpad.dev/' +
639+ 'bar/+filebug-show-similar?title=foo'],
640+ this.config.yio.calls);
641+ };
642+ simulate(search_button, undefined, 'click');
643+ this.wait();
644 };
645 simulate(search_button, undefined, 'click');
646 this.wait();
647- };
648- simulate(search_button, undefined, 'click');
649- this.wait();
650- }
651-
652-}));
653-
654-var handle_complete = function(data) {
655- window.status = '::::' + JSON.stringify(data);
656- };
657-Y.Test.Runner.on('complete', handle_complete);
658-Y.Test.Runner.add(suite);
659-
660-var console = new Y.Console({newestOnTop: false});
661-console.render('#log');
662-
663-// Configure the javascript module under test. In production, the
664-// setup_dupe_finder() is called from the page template. We need to pass in
665-// a stub io handler here so that the XHR call made during set up is ignored.
666-var config = {};
667-config.yio = new IOStub();
668-module.setup_config(config);
669-module.setup_dupe_finder();
670-
671-Y.on('domready', function(e) {
672- Y.Test.Runner.run();
673-});
674+ }
675+
676+ }));
677+
678+
679+}, '0.1', {
680+ requires: ['test', 'lp.testing.helpers', 'console',
681+ 'lp.bugs.filebug_dupefinder', 'node-event-simulate']
682 });
683
684=== modified file 'lib/lp/bugs/javascript/tests/test_me_too.html'
685--- lib/lp/bugs/javascript/tests/test_me_too.html 2012-03-27 04:36:24 +0000
686+++ lib/lp/bugs/javascript/tests/test_me_too.html 2012-06-28 18:18:19 +0000
687@@ -58,7 +58,7 @@
688 <body class="yui3-skin-sam">
689 <ul id="suites">
690 <!-- <li>lp.large_indicator.test</li> -->
691- <li>lp.bugtask_index.test</li>
692+ <li>lp.bugs.bugtask_index.test_me_too</li>
693 </ul>
694 </body>
695 </html>
696
697=== modified file 'lib/lp/bugs/javascript/tests/test_me_too.js'
698--- lib/lp/bugs/javascript/tests/test_me_too.js 2011-06-08 16:16:32 +0000
699+++ lib/lp/bugs/javascript/tests/test_me_too.js 2012-06-28 18:18:19 +0000
700@@ -1,219 +1,204 @@
701-/* Copyright (c) 2008, Canonical Ltd. All rights reserved. */
702-
703-YUI({
704- base: '../../../../canonical/launchpad/icing/yui/',
705- filter: 'raw',
706- combine: false,
707- fetchCSS: false
708- }).use('event', 'lp.bugs.bugtask_index', 'lp.client', 'node',
709- 'test', 'widget-stack', 'console', function(Y) {
710-
711-// Local aliases
712-var Assert = Y.Assert,
713- ArrayAssert = Y.ArrayAssert;
714-
715-/*
716- * A wrapper for the Y.Event.simulate() function. The wrapper accepts
717- * CSS selectors and Node instances instead of raw nodes.
718- */
719-function simulate(widget, selector, evtype, options) {
720- var rawnode = Y.Node.getDOMNode(widget.one(selector));
721- Y.Event.simulate(rawnode, evtype, options);
722-}
723-
724-var suite = new Y.Test.Suite("Bugtask Me-Too Choice Edit Tests");
725-
726-suite.add(new Y.Test.Case({
727-
728- name: 'me_too_choice_edit_basics',
729-
730- setUp: function() {
731- // Monkeypatch LP to avoid network traffic and to make
732- // some things work as expected.
733- Y.lp.client.Launchpad.prototype.named_post =
734- function(url, func, config) {
735- config.on.success();
736- };
737- LP = {
738- 'cache': {
739- 'bug': {
740- self_link: "http://bugs.example.com/bugs/1234"
741- }}};
742- // add the in-page HTML
743- var inpage = Y.Node.create([
744- '<span id="affectsmetoo">',
745- ' <span class="static">',
746- ' <img src="https://bugs.launchpad.net/@@/flame-icon" alt=""/>',
747- ' This bug affects me too',
748- ' <a href="+affectsmetoo">',
749- ' <img class="editicon" alt="Edit"',
750- ' src="https://bugs.launchpad.net/@@/edit" />',
751- ' </a>',
752- ' </span>',
753- ' <span class="dynamic unseen">',
754- ' <img class="editicon" alt="Edit"',
755- ' src="https://bugs.launchpad.net/@@/edit" />',
756- ' <a href="+affectsmetoo" class="js-action"',
757- ' ><span class="value">Does this bug affect you?</span></a>',
758- ' <img src="https://bugs.launchpad.net/@@/flame-icon" alt=""/>',
759- ' </span>',
760- '</span>'].join(''));
761- Y.one("body").appendChild(inpage);
762- var me_too_content = Y.one('#affectsmetoo');
763- this.config = {
764- contentBox: me_too_content, value: null,
765- elementToFlash: me_too_content, others_affected_count: 5
766- };
767- this.choice_edit = new Y.lp.bugs.bugtask_index._MeTooChoiceSource(
768- this.config);
769- this.choice_edit.render();
770- },
771-
772- tearDown: function() {
773- var status = Y.one("document").one("#affectsmetoo");
774- if (status) {
775- status.get("parentNode").removeChild(status);
776+/* Copyright (c) 2008-2012 Canonical Ltd. All rights reserved. */
777+
778+YUI.add('lp.bugs.bugtask_index.test_me_too', function (Y) {
779+ // Local aliases
780+ var Assert = Y.Assert,
781+ ArrayAssert = Y.ArrayAssert;
782+
783+ /*
784+ * A wrapper for the Y.Event.simulate() function. The wrapper accepts
785+ * CSS selectors and Node instances instead of raw nodes.
786+ */
787+ function simulate(widget, selector, evtype, options) {
788+ var rawnode = Y.Node.getDOMNode(widget.one(selector));
789+ Y.Event.simulate(rawnode, evtype, options);
790+ }
791+
792+ var tests = Y.namespace('lp.bugs.bugtask_index.test_me_too');
793+ tests.suite = new Y.Test.Suite('MeToo Tests');
794+
795+ tests.suite.add(new Y.Test.Case({
796+
797+ name: 'me_too_choice_edit_basics',
798+
799+ setUp: function() {
800+ // Monkeypatch LP to avoid network traffic and to make
801+ // some things work as expected.
802+ Y.lp.client.Launchpad.prototype.named_post =
803+ function(url, func, config) {
804+ config.on.success();
805+ };
806+ LP = {
807+ 'cache': {
808+ 'bug': {
809+ self_link: "http://bugs.example.com/bugs/1234"
810+ }}};
811+ // add the in-page HTML
812+ var inpage = Y.Node.create([
813+ '<span id="affectsmetoo">',
814+ ' <span class="static">',
815+ ' <img src="https://bugs.launchpad.net/@@/flame-icon" alt=""/>',
816+ ' This bug affects me too',
817+ ' <a href="+affectsmetoo">',
818+ ' <img class="editicon" alt="Edit"',
819+ ' src="https://bugs.launchpad.net/@@/edit" />',
820+ ' </a>',
821+ ' </span>',
822+ ' <span class="dynamic unseen">',
823+ ' <img class="editicon" alt="Edit"',
824+ ' src="https://bugs.launchpad.net/@@/edit" />',
825+ ' <a href="+affectsmetoo" class="js-action"',
826+ ' ><span class="value">Does this bug affect you?</span></a>',
827+ ' <img src="https://bugs.launchpad.net/@@/flame-icon" alt=""/>',
828+ ' </span>',
829+ '</span>'].join(''));
830+ Y.one("body").appendChild(inpage);
831+ var me_too_content = Y.one('#affectsmetoo');
832+ this.config = {
833+ contentBox: me_too_content, value: null,
834+ elementToFlash: me_too_content, others_affected_count: 5
835+ };
836+ this.choice_edit = new Y.lp.bugs.bugtask_index._MeTooChoiceSource(
837+ this.config);
838+ this.choice_edit.render();
839+ },
840+
841+ tearDown: function() {
842+ var status = Y.one("document").one("#affectsmetoo");
843+ if (status) {
844+ status.get("parentNode").removeChild(status);
845+ }
846+ },
847+
848+ /**
849+ * The choice edit should be displayed inline.
850+ */
851+ test_is_inline: function() {
852+ var display =
853+ this.choice_edit.get('boundingBox').getStyle('display');
854+ Assert.areEqual(
855+ display, 'inline',
856+ "Not displayed inline, display is: " + display);
857+ },
858+
859+ /**
860+ * The .static area should be hidden by adding the "unseen" class.
861+ */
862+ test_hide_static: function() {
863+ var static_area = this.choice_edit.get('contentBox').one('.static');
864+ Assert.isTrue(
865+ static_area.hasClass('unseen'), "Static area is not hidden.");
866+ },
867+
868+ /**
869+ * The .dynamic area should be shown by removing the "unseen" class.
870+ */
871+ test_hide_dynamic: function() {
872+ var dynamic_area =
873+ this.choice_edit.get('contentBox').one('.dynamic');
874+ Assert.isFalse(
875+ dynamic_area.hasClass('unseen'), "Dynamic area is hidden.");
876+ },
877+
878+ /**
879+ * The UI should be in a waiting state while the save process is
880+ * executing and return to a non-waiting state once it has
881+ * finished.
882+ */
883+ test_ui_waiting_for_success: function() {
884+ this.do_test_ui_waiting('success');
885+ },
886+
887+ /**
888+ * The UI should be in a waiting state while the save process is
889+ * executing and return to a non-waiting state even if the process
890+ * fails.
891+ */
892+ test_ui_waiting_for_failure: function() {
893+ this.do_test_ui_waiting('failure');
894+ },
895+
896+ /**
897+ * Helper function that does the leg work for the
898+ * test_ui_waiting_* methods.
899+ */
900+ do_test_ui_waiting: function(callback) {
901+ var edit_icon = this.choice_edit.get('editicon');
902+ // The spinner should not be displayed at first.
903+ Assert.isNull(
904+ edit_icon.get('src').match(/\/spinner$/),
905+ "The edit icon is displaying a spinner at rest.");
906+ // The spinner should not be displayed after opening the
907+ // choice list.
908+ simulate(this.choice_edit.get('boundingBox'), '.value', 'click');
909+ Assert.isNull(
910+ edit_icon.get('src').match(/\/spinner$/),
911+ "The edit icon is displaying a spinner after opening the " +
912+ "choice list.");
913+ // The spinner should be visible during the interval between a
914+ // choice being made and a response coming back from Launchpad
915+ // that the choice has been saved.
916+ var edit_icon_src_during_save;
917+ // Patch the named_post method to simulate success or failure,
918+ // as determined by the callback argument. We cannot make
919+ // assertions in this method because exceptions are swallowed
920+ // somewhere. Instead, we save something testable to a local
921+ // var.
922+ Y.lp.client.Launchpad.prototype.named_post =
923+ function(url, func, config) {
924+ edit_icon_src_during_save = edit_icon.get('src');
925+ config.on[callback]();
926+ };
927+ simulate(this.choice_edit._choice_list.get('boundingBox'),
928+ 'li a[href$=true]', 'click');
929+ Assert.isNotNull(
930+ edit_icon_src_during_save.match(/\/spinner$/),
931+ "The edit icon is not displaying a spinner during save.");
932+ // The spinner should not be displayed once a choice has been
933+ // saved.
934+ Assert.isNull(
935+ edit_icon.get('src').match(/\/spinner$/),
936+ "The edit icon is displaying a spinner once the choice has " +
937+ "been made.");
938+ },
939+
940+ test__getSourceNames: function() {
941+ var names;
942+ // No other users affected.
943+ names = this.choice_edit._getSourceNames(0);
944+ Assert.areEqual(
945+ 'This bug affects you', names[true]);
946+ Assert.areEqual(
947+ "This bug doesn't affect you", names[false]);
948+ // 1 other user affected.
949+ names = this.choice_edit._getSourceNames(1);
950+ Assert.areEqual(
951+ 'This bug affects you and 1 other person', names[true]);
952+ Assert.areEqual(
953+ 'This bug affects 1 person, but not you', names[false]);
954+ // 2 other users affected.
955+ names = this.choice_edit._getSourceNames(2);
956+ Assert.areEqual(
957+ 'This bug affects you and 2 other people', names[true]);
958+ Assert.areEqual(
959+ 'This bug affects 2 people, but not you', names[false]);
960+ },
961+
962+ test_new_names_are_applied: function() {
963+ var names = {};
964+ Y.each(this.choice_edit.get('items'), function(item) {
965+ names[item.value] = item.source_name;
966+ });
967+ Assert.areEqual(
968+ 'This bug affects you and 5 other people', names[true]);
969+ Assert.areEqual(
970+ 'This bug affects 5 people, but not you', names[false]);
971 }
972- },
973-
974- /**
975- * The choice edit should be displayed inline.
976- */
977- test_is_inline: function() {
978- var display = this.choice_edit.get('boundingBox').getStyle('display');
979- Assert.areEqual(
980- display, 'inline',
981- "Not displayed inline, display is: " + display);
982- },
983-
984- /**
985- * The .static area should be hidden by adding the "unseen" class.
986- */
987- test_hide_static: function() {
988- var static_area = this.choice_edit.get('contentBox').one('.static');
989- Assert.isTrue(
990- static_area.hasClass('unseen'), "Static area is not hidden.");
991- },
992-
993- /**
994- * The .dynamic area should be shown by removing the "unseen" class.
995- */
996- test_hide_dynamic: function() {
997- var dynamic_area = this.choice_edit.get('contentBox').one('.dynamic');
998- Assert.isFalse(
999- dynamic_area.hasClass('unseen'), "Dynamic area is hidden.");
1000- },
1001-
1002- /**
1003- * The UI should be in a waiting state while the save process is
1004- * executing and return to a non-waiting state once it has
1005- * finished.
1006- */
1007- test_ui_waiting_for_success: function() {
1008- this.do_test_ui_waiting('success');
1009- },
1010-
1011- /**
1012- * The UI should be in a waiting state while the save process is
1013- * executing and return to a non-waiting state even if the process
1014- * fails.
1015- */
1016- test_ui_waiting_for_failure: function() {
1017- this.do_test_ui_waiting('failure');
1018- },
1019-
1020- /**
1021- * Helper function that does the leg work for the
1022- * test_ui_waiting_* methods.
1023- */
1024- do_test_ui_waiting: function(callback) {
1025- var edit_icon = this.choice_edit.get('editicon');
1026- // The spinner should not be displayed at first.
1027- Assert.isNull(
1028- edit_icon.get('src').match(/\/spinner$/),
1029- "The edit icon is displaying a spinner at rest.");
1030- // The spinner should not be displayed after opening the
1031- // choice list.
1032- simulate(this.choice_edit.get('boundingBox'), '.value', 'click');
1033- Assert.isNull(
1034- edit_icon.get('src').match(/\/spinner$/),
1035- "The edit icon is displaying a spinner after opening the " +
1036- "choice list.");
1037- // The spinner should be visible during the interval between a
1038- // choice being made and a response coming back from Launchpad
1039- // that the choice has been saved.
1040- var edit_icon_src_during_save;
1041- // Patch the named_post method to simulate success or failure,
1042- // as determined by the callback argument. We cannot make
1043- // assertions in this method because exceptions are swallowed
1044- // somewhere. Instead, we save something testable to a local
1045- // var.
1046- Y.lp.client.Launchpad.prototype.named_post =
1047- function(url, func, config) {
1048- edit_icon_src_during_save = edit_icon.get('src');
1049- config.on[callback]();
1050- };
1051- simulate(this.choice_edit._choice_list.get('boundingBox'),
1052- 'li a[href$=true]', 'click');
1053- Assert.isNotNull(
1054- edit_icon_src_during_save.match(/\/spinner$/),
1055- "The edit icon is not displaying a spinner during save.");
1056- // The spinner should not be displayed once a choice has been
1057- // saved.
1058- Assert.isNull(
1059- edit_icon.get('src').match(/\/spinner$/),
1060- "The edit icon is displaying a spinner once the choice has " +
1061- "been made.");
1062- },
1063-
1064- test__getSourceNames: function() {
1065- var names;
1066- // No other users affected.
1067- names = this.choice_edit._getSourceNames(0);
1068- Assert.areEqual(
1069- 'This bug affects you', names[true]);
1070- Assert.areEqual(
1071- "This bug doesn't affect you", names[false]);
1072- // 1 other user affected.
1073- names = this.choice_edit._getSourceNames(1);
1074- Assert.areEqual(
1075- 'This bug affects you and 1 other person', names[true]);
1076- Assert.areEqual(
1077- 'This bug affects 1 person, but not you', names[false]);
1078- // 2 other users affected.
1079- names = this.choice_edit._getSourceNames(2);
1080- Assert.areEqual(
1081- 'This bug affects you and 2 other people', names[true]);
1082- Assert.areEqual(
1083- 'This bug affects 2 people, but not you', names[false]);
1084- },
1085-
1086- test_new_names_are_applied: function() {
1087- var names = {};
1088- Y.each(this.choice_edit.get('items'), function(item) {
1089- names[item.value] = item.source_name;
1090- });
1091- Assert.areEqual(
1092- 'This bug affects you and 5 other people', names[true]);
1093- Assert.areEqual(
1094- 'This bug affects 5 people, but not you', names[false]);
1095- }
1096-
1097-}));
1098-
1099-var handle_complete = function(data) {
1100- window.status = '::::' + JSON.stringify(data);
1101- };
1102-Y.Test.Runner.on('complete', handle_complete);
1103-Y.Test.Runner.add(suite);
1104-
1105-var yconsole = new Y.Console({
1106- newestOnTop: false
1107-});
1108-yconsole.render('#log');
1109-
1110-Y.on('domready', function() {
1111- Y.Test.Runner.run();
1112-});
1113-
1114+
1115+ }));
1116+
1117+}, '0.1', {
1118+ requires: ['test', 'lp.testing.helpers', 'console',
1119+ 'lp.bugs.bugtask_index', 'lp.client', 'node', 'widget-stack',
1120+ 'event']
1121 });
1122
1123=== modified file 'lib/lp/bugs/javascript/tests/test_pre_search.html'
1124--- lib/lp/bugs/javascript/tests/test_pre_search.html 2012-03-27 04:36:24 +0000
1125+++ lib/lp/bugs/javascript/tests/test_pre_search.html 2012-06-28 18:18:19 +0000
1126@@ -53,7 +53,7 @@
1127 <body class="yui3-skin-sam">
1128 <ul id="suites">
1129 <!-- <li>lp.large_indicator.test</li> -->
1130- <li>lp.bugtask_index.test</li>
1131+ <li>lp.bugs.bugtask_index.test_pre_search</li>
1132 </ul>
1133 </body>
1134 </html>
1135
1136=== modified file 'lib/lp/bugs/javascript/tests/test_pre_search.js'
1137--- lib/lp/bugs/javascript/tests/test_pre_search.js 2011-07-28 18:59:52 +0000
1138+++ lib/lp/bugs/javascript/tests/test_pre_search.js 2012-06-28 18:18:19 +0000
1139@@ -1,106 +1,80 @@
1140-/* Copyright (c) 2011, Canonical Ltd. All rights reserved. */
1141-
1142-YUI({
1143- base: '../../../../canonical/launchpad/icing/yui/',
1144- filter: 'raw',
1145- combine: false,
1146- fetchCSS: false
1147- }).use('event', 'lp.bugs.bugtask_index', 'lp.client', 'node',
1148- 'test', 'widget-stack', 'console', function(Y) {
1149-
1150-// Local aliases
1151-var Assert = Y.Assert,
1152- ArrayAssert = Y.ArrayAssert;
1153-
1154-// A picker implementation that records method calls for testing.
1155-function FauxPicker() {
1156- this.events = [];
1157-}
1158-
1159-FauxPicker.prototype.get = function(name) {
1160- this.events.push('get ' + name);
1161- return 47;
1162-};
1163-
1164-FauxPicker.prototype.set = function(name, value) {
1165- this.events.push('set ' + name + ' = ' + value);
1166-};
1167-
1168-FauxPicker.prototype.fire = function(name, value) {
1169- this.events.push('fire ' + name + ' with ' + value);
1170-};
1171-
1172-
1173-var suite = new Y.Test.Suite("Link a related branch preemptive search.");
1174-var module = Y.lp.bugs.bugtask_index;
1175-
1176-suite.add(new Y.Test.Case({
1177-
1178- name: 'pre_search',
1179-
1180- setUp: function() {
1181- },
1182-
1183- tearDown: function() {
1184- },
1185-
1186- /**
1187- * A loading message is added to the footer slot.
1188- */
1189- test_loading_message: function() {
1190- picker = new FauxPicker();
1191- module._do_pre_search(picker, 'BUG-ID');
1192- ArrayAssert.contains(
1193- 'set footer_slot = Loading suggestions...',
1194- picker.events);
1195- },
1196-
1197- /**
1198- * Because some bug numbers are short strings, the minimum search
1199- * character limit has to be set to zero and then reset to its original
1200- * value.
1201- */
1202- test_min_search_length: function() {
1203- picker = new FauxPicker();
1204- module._do_pre_search(picker, 'BUG-ID');
1205- ArrayAssert.contains(
1206- 'get min_search_chars',
1207- picker.events);
1208- ArrayAssert.contains(
1209- 'set min_search_chars = 47',
1210- picker.events);
1211- },
1212-
1213- /**
1214- * After the search event is fired, search_mode has to be (immediately)
1215- * disbled so the user can enter a search.
1216- */
1217- test_disable_search_mode: function() {
1218- picker = new FauxPicker();
1219- module._do_pre_search(picker, 'BUG-ID');
1220- ArrayAssert.contains(
1221- 'fire search with BUG-ID',
1222- picker.events);
1223- ArrayAssert.contains(
1224- 'set search_mode = false',
1225- picker.events);
1226+/* Copyright (c) 2011-2012, Canonical Ltd. All rights reserved. */
1227+
1228+YUI.add('lp.bugs.bugtask_index.test_pre_search', function (Y) {
1229+ var module = Y.lp.bugs.bugtask_index;
1230+ // Local aliases
1231+ var Assert = Y.Assert,
1232+ ArrayAssert = Y.ArrayAssert;
1233+
1234+ // A picker implementation that records method calls for testing.
1235+ function FauxPicker() {
1236+ this.events = [];
1237 }
1238
1239-}));
1240-
1241-var handle_complete = function(data) {
1242- window.status = '::::' + JSON.stringify(data);
1243- };
1244-Y.Test.Runner.on('complete', handle_complete);
1245-Y.Test.Runner.add(suite);
1246-
1247-var yconsole = new Y.Console({
1248- newestOnTop: false
1249-});
1250-yconsole.render('#log');
1251-
1252-Y.on('domready', function() {
1253- Y.Test.Runner.run();
1254-});
1255-
1256+ FauxPicker.prototype.get = function(name) {
1257+ this.events.push('get ' + name);
1258+ return 47;
1259+ };
1260+
1261+ FauxPicker.prototype.set = function(name, value) {
1262+ this.events.push('set ' + name + ' = ' + value);
1263+ };
1264+
1265+ FauxPicker.prototype.fire = function(name, value) {
1266+ this.events.push('fire ' + name + ' with ' + value);
1267+ };
1268+
1269+ var tests = Y.namespace('lp.bugs.bugtask_index.test_pre_search');
1270+ tests.suite = new Y.Test.Suite('Pre Search Tests');
1271+ tests.suite.add(new Y.Test.Case({
1272+
1273+ name: 'pre_search',
1274+
1275+ /**
1276+ * A loading message is added to the footer slot.
1277+ */
1278+ test_loading_message: function() {
1279+ picker = new FauxPicker();
1280+ module._do_pre_search(picker, 'BUG-ID');
1281+ ArrayAssert.contains(
1282+ 'set footer_slot = Loading suggestions...',
1283+ picker.events);
1284+ },
1285+
1286+ /**
1287+ * Because some bug numbers are short strings, the minimum search
1288+ * character limit has to be set to zero and then reset to its original
1289+ * value.
1290+ */
1291+ test_min_search_length: function() {
1292+ picker = new FauxPicker();
1293+ module._do_pre_search(picker, 'BUG-ID');
1294+ ArrayAssert.contains(
1295+ 'get min_search_chars',
1296+ picker.events);
1297+ ArrayAssert.contains(
1298+ 'set min_search_chars = 47',
1299+ picker.events);
1300+ },
1301+
1302+ /**
1303+ * After the search event is fired, search_mode has to be (immediately)
1304+ * disbled so the user can enter a search.
1305+ */
1306+ test_disable_search_mode: function() {
1307+ picker = new FauxPicker();
1308+ module._do_pre_search(picker, 'BUG-ID');
1309+ ArrayAssert.contains(
1310+ 'fire search with BUG-ID',
1311+ picker.events);
1312+ ArrayAssert.contains(
1313+ 'set search_mode = false',
1314+ picker.events);
1315+ }
1316+
1317+ }));
1318+
1319+}, '0.1', {
1320+ requires: ['test', 'lp.testing.helpers', 'console', 'event',
1321+ 'lp.bugs.bugtask_index', 'lp.client', 'node', 'widget-stack']
1322 });