launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #00683
[Merge] lp:~gmb/launchpad/new-subscriptions-widget-bug-616653 into lp:launchpad/devel
Graham Binns has proposed merging lp:~gmb/launchpad/new-subscriptions-widget-bug-616653 into lp:launchpad/devel.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers): code
Related bugs:
#616653 Add a subscription widget
https://bugs.launchpad.net/bugs/616653
This branch adds the beginnings of a new subscription widget. It isn't actually hooked up to anything yet.
The widget will first be used for bug subscriptions before being converted to work for both individual bugs *and* structural subscriptions. It will eventually be used for subscriptions-to-searches, too.
The widget isn't, as I said, hooked up to anything; this branch is about giving us a good base to work from for the rest of the development work.
I've added a simple test to check that the values used for the bug notification level radio buttons are valid, but tests will become more thorough as more development work is carried out, since we'll be able to add Windmill tests, too.
--
https://code.launchpad.net/~gmb/launchpad/new-subscriptions-widget-bug-616653/+merge/33215
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~gmb/launchpad/new-subscriptions-widget-bug-616653 into lp:launchpad/devel.
=== added file 'lib/lp/bugs/javascript/bug_subscription_widget.js'
--- lib/lp/bugs/javascript/bug_subscription_widget.js 1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/javascript/bug_subscription_widget.js 2010-08-20 13:55:34 +0000
@@ -0,0 +1,85 @@
+/* Copyright 2009 Canonical Ltd. This software is licensed under the
+ * GNU Affero General Public License version 3 (see the file LICENSE).
+ *
+ * Handling of the bug subscription form overlay widget.
+ *
+ * @module bugs
+ * @submodule bug_subscription_widget
+ */
+YUI.add('lp.bugs.bug_subscription_widget', function(Y) {
+
+var namespace = Y.namespace('lp.bugs.bug_subscription_widget');
+
+var submit_button_html =
+ '<button type="submit" name="field.actions.subscribe" ' +
+ 'value="Subscribe"' +
+ 'class="lazr-pos lazr-btn" >OK</button>';
+var cancel_button_html =
+ '<button type="button" name="field.actions.cancel" ' +
+ 'class="lazr-neg lazr-btn" >Cancel</button>';
+
+namespace.create_subscription_overlay = function() {
+ // Construct the form. This is a bit hackish but it saves us from
+ // having to try to get information from TAL into JavaScript and all
+ // the horror that entails.
+ var subscribe_form_body =
+ '<div>' +
+ ' <p>Tell me when</p>' +
+ ' <table>' +
+ ' <tr>' +
+ ' <td>' +
+ ' <input type="radio" name="field.bug_notification_level" ' +
+ ' id="bug-notification-level-comments"' +
+ ' value="Discussion"' +
+ ' class="bug-notification-level" />' +
+ ' </td>' +
+ ' <td>' +
+ ' <label for="bug-notification-level-comments">' +
+ ' A change is made or a comment is added to this bug' +
+ ' </label>' +
+ ' </td>' +
+ ' </tr>' +
+ ' <tr>' +
+ ' <td>' +
+ ' <input type="radio" name="field.bug_notification_level" ' +
+ ' id="bug-notification-level-metadata" value="Details"' +
+ ' class="bug-notification-level" />' +
+ ' </td>' +
+ ' <td>' +
+ ' <label for="bug-notification-level-metadata">' +
+ ' A change is made to the bug (do not notify me about ' +
+ ' new comments).' +
+ ' </label>' +
+ ' </td>' +
+ ' </tr>' +
+ ' <tr>' +
+ ' <td>' +
+ ' <input type="radio" name="field.bug_notification_level" ' +
+ ' id="bug-notification-level-lifecycle" value="Lifecycle"' +
+ ' class="bug-notification-level" />' +
+ ' </td>' +
+ ' <td>' +
+ ' <label for="bug-notification-level-lifecycle">' +
+ ' Changes are made to the bug\'s status.' +
+ ' </label>' +
+ ' </td>' +
+ ' </tr>' +
+ ' </table>' +
+ '</div>';
+
+ // Create the do-you-want-to-subscribe FormOverlay.
+ var subscribe_form_overlay = new Y.lazr.FormOverlay({
+ headerContent: '<h2>Subscribe to this bug</h2>',
+ form_content: subscribe_form_body,
+ form_submit_button: Y.Node.create(submit_button_html),
+ form_cancel_button: Y.Node.create(cancel_button_html),
+ centered: true,
+ visible: false
+ });
+ subscribe_form_overlay.render('#subscribe-overlay');
+
+ return subscribe_form_overlay;
+};
+
+}, "0.1", {"requires": [
+ "base", "io", "oop", "node", "event", "lazr.formoverlay", "lazr.effects"]});
=== added file 'lib/lp/bugs/javascript/tests/test_bug_subscription_widget.html'
--- lib/lp/bugs/javascript/tests/test_bug_subscription_widget.html 1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/javascript/tests/test_bug_subscription_widget.html 2010-08-20 13:55:34 +0000
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <title>Bug Subscription Widget</title>
+
+ <!-- YUI 3.0 Setup -->
+ <script type="text/javascript" src="../../../../canonical/launchpad/icing/yui/yui/yui.js"></script>
+ <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssreset/reset.css"/>
+ <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssfonts/fonts.css"/>
+ <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssbase/base.css"/>
+
+ <!-- Dependency -->
+ <script type="text/javascript"
+ src="../../../../canonical/launchpad/icing/lazr/build/lazr.js"></script>
+ <script type="text/javascript"
+ src="../../../../canonical/launchpad/icing/lazr/build/overlay/overlay.js">
+ </script>
+ <script type="text/javascript"
+ src="../../../../canonical/launchpad/icing/lazr/build/choiceedit/choiceedit.js">
+ </script>
+ <script type="text/javascript"
+ src="../../../../canonical/launchpad/javascript/client/client.js"></script>
+
+ <!-- The module under test -->
+ <script type="text/javascript" src="../bug_subscription_widget.js"></script>
+
+ <!-- The test suite -->
+ <script type="text/javascript" src="test_bug_subscription_widget.js"></script>
+
+ <!-- Test layout -->
+ <link rel="stylesheet"
+ href="../../../../canonical/launchpad/javascript/test.css" />
+ <style type="text/css">
+ /* CSS classes specific to this test */
+ .unseen { display: none; }
+ </style>
+</head>
+<body class="yui-skin-sam">
+ <div id="log"></div>
+</body>
+</html>
=== added file 'lib/lp/bugs/javascript/tests/test_bug_subscription_widget.js'
--- lib/lp/bugs/javascript/tests/test_bug_subscription_widget.js 1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/javascript/tests/test_bug_subscription_widget.js 2010-08-20 13:55:34 +0000
@@ -0,0 +1,92 @@
+/* Copyright (c) 2008, Canonical Ltd. All rights reserved. */
+
+YUI({
+ base: '../../../../canonical/launchpad/icing/yui/',
+ filter: 'raw',
+ combine: false
+ }).use(
+ 'event', 'lp.bugs.bug_subscription_widget', 'node', 'test',
+ 'widget-stack', 'console', function(Y) {
+
+// Local aliases
+var Assert = Y.Assert,
+ ArrayAssert = Y.ArrayAssert;
+
+/*
+ * A wrapper for the Y.Event.simulate() function. The wrapper accepts
+ * CSS selectors and Node instances instead of raw nodes.
+ */
+function simulate(widget, selector, evtype, options) {
+ var rawnode = Y.Node.getDOMNode(widget.one(selector));
+ Y.Event.simulate(rawnode, evtype, options);
+}
+
+/* Helper function to clean up a dynamically added widget instance. */
+function cleanup_widget(widget) {
+ // Nuke the boundingBox, but only if we've touched the DOM.
+ if (widget.get('rendered')) {
+ var bb = widget.get('boundingBox');
+ if (bb.get('parentNode')) {
+ bb.get('parentNode').removeChild(bb);
+ }
+ }
+ // Kill the widget itself.
+ widget.destroy();
+}
+
+var suite = new Y.Test.Suite("Bug subscription widget tests");
+
+suite.add(new Y.Test.Case({
+
+ name: 'bug_subscription_widget_basics',
+
+ setUp: function() {
+ // Monkeypatch LP.client to avoid network traffic and to make
+ // some things work as expected.
+ LP.client.Launchpad.prototype.named_post =
+ function(url, func, config) {
+ config.on.success();
+ };
+ LP.client.cache.bug = {
+ self_link: "http://bugs.example.com/bugs/1234"
+ };
+ this.subscribe_overlay =
+ Y.lp.bugs.bug_subscription_widget.create_subscription_overlay();
+ this.subscribe_overlay.show();
+ },
+
+ test_bug_notification_level_values: function() {
+ // The bug_notification_level field will have a value that's one
+ // of [Discussion, Details, Lifecycle].
+ var form_node = this.subscribe_overlay.form_node;
+ var notification_level_radio_buttons = form_node.queryAll(
+ 'input[name=field.bug_notification_level]');
+ Y.each(notification_level_radio_buttons, function(obj) {
+ var value = obj.getAttribute('value');
+ Assert.isTrue(
+ value == 'Discussion' ||
+ value == 'Details' ||
+ value == 'Lifecycle');
+ });
+ }
+
+}));
+
+var handle_complete = function(data) {
+ status_node = Y.Node.create(
+ '<p id="complete">Test status: complete</p>');
+ Y.get('body').appendChild(status_node);
+ };
+Y.Test.Runner.on('complete', handle_complete);
+Y.Test.Runner.add(suite);
+
+var yconsole = new Y.Console({
+ newestOnTop: false
+});
+yconsole.render('#log');
+
+Y.on('domready', function() {
+ Y.Test.Runner.run();
+});
+
+});