launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #14156
[Merge] lp:~rharding/launchpad/wire_new_banner into lp:launchpad
Richard Harding has proposed merging lp:~rharding/launchpad/wire_new_banner into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~rharding/launchpad/wire_new_banner/+merge/133913
TBD
--
https://code.launchpad.net/~rharding/launchpad/wire_new_banner/+merge/133913
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~rharding/launchpad/wire_new_banner into lp:launchpad.
=== modified file 'buildout-templates/bin/combine-css.in'
--- buildout-templates/bin/combine-css.in 2012-08-23 19:56:15 +0000
+++ buildout-templates/bin/combine-css.in 2012-11-12 13:05:28 +0000
@@ -27,6 +27,7 @@
#'lazr/build/yui/cssgrids/grids.css',
'cssgrids/grids.css',
'build/ui/assets/skins/sam/lazr.css',
+ 'build/ui/assets/skins/sam/banner.css',
'build/inlineedit/assets/skins/sam/editor.css',
'build/autocomplete/assets/skins/sam/autocomplete.css',
'build/overlay/assets/skins/sam/pretty-overlay.css',
=== removed file 'lib/canonical/launchpad/icing/css/components/beta_banner.css'
--- lib/canonical/launchpad/icing/css/components/beta_banner.css 2012-05-16 20:32:47 +0000
+++ lib/canonical/launchpad/icing/css/components/beta_banner.css 1970-01-01 00:00:00 +0000
@@ -1,48 +0,0 @@
-/* ===========
- Beta banner
-*/
-.yui3-betabanner-content .global-notification {
- position: fixed;
- z-index: 9;
- top: 0;
- left: 0;
- right: 0;
- padding: 7px 20px;
- /* Define colour for browsers that don't support transparency */
- background-color: #606060;
- /* Set transparent background for browsers that support it */
- background-color: rgba(64, 64, 64, 0.9);
- box-shadow: 0 0 5px #333;
- color: #fff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
- font-size: 14px;
- line-height: 21px;
- text-align: left;
- }
-.beta-banner .info-link {
- color: #4884ef;
-}
-.beta-warning {
- padding: 3px 6px 4px 6px;
- margin-right: 12px;
- background-color: #be0000;
- font-weight: bold;
- font-size: 12px;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- border-radius: 5px;
- border-top: 1px solid #e20000;
- background-color: #c10000;
- background: linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- background: -o-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- background: -moz-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- background: -webkit-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- background: -ms-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- }
-.beta-feature {
- font-weight: bold;
- }
-.yui3-betabanner-content .global-notification-close,
-.yui3-betabanner-content .global-notification-close:active,
-.yui3-betabanner-content .global-notification-close:visited {
- color: #fff;
- }
=== modified file 'lib/lp/app/browser/tales.py'
--- lib/lp/app/browser/tales.py 2012-09-28 06:15:58 +0000
+++ lib/lp/app/browser/tales.py 2012-11-12 13:05:28 +0000
@@ -663,15 +663,16 @@
def global_css(self):
css_classes = set([])
view = self._context
+
+ # XXX: Bug #1076074
private = getattr(view, 'private', False)
if private:
css_classes.add('private')
- css_classes.add('global-notification-visible')
else:
css_classes.add('public')
beta = getattr(view, 'beta_features', [])
- if beta != []:
- css_classes.add('global-notification-visible')
+ if beta:
+ css_classes.add('beta')
return ' '.join(list(css_classes))
def _getSaneBreadcrumbDetail(self, breadcrumb):
=== removed directory 'lib/lp/app/javascript/banners'
=== removed file 'lib/lp/app/javascript/banners/banner.js'
--- lib/lp/app/javascript/banners/banner.js 2012-10-04 14:17:23 +0000
+++ lib/lp/app/javascript/banners/banner.js 1970-01-01 00:00:00 +0000
@@ -1,156 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd. This software is licensed under the
- * GNU Affero General Public License version 3 (see the file LICENSE).
- *
- * Notification banner widget
- *
- * @module lp.app.banner
- */
-
-YUI.add('lp.app.banner', function (Y) {
-var ns = Y.namespace('lp.app.banner');
-
-ns.Banner = Y.Base.create('banner', Y.Widget, [], {
-
- _getAnimTimes: function() {
- var anim_times;
- if (this.get('skip_animation')) {
- anim_times = {
- fade: 0.0,
- slide_out: 0.0
- };
- } else {
- anim_times = {
- fade: 0.3,
- slide_out: 0.2
- };
- }
- return anim_times;
- },
-
- _showBanner: function () {
- var body = Y.one('body');
- var global_notification = Y.one('.global-notification');
- var anim_times = this._getAnimTimes();
-
- body.addClass('global-notification-visible');
- global_notification.removeClass('hidden');
-
- var fade_in = new Y.Anim({
- node: global_notification,
- to: {opacity: 1},
- duration: anim_times.fade
- });
- var body_space = new Y.Anim({
- node: body,
- to: {'paddingTop': '40px'},
- duration: anim_times.slide_out,
- easing: Y.Easing.easeOut
- });
- var login_space = new Y.Anim({
- node: '.login-logout',
- to: {'top': '45px'},
- duration: anim_times.slide_out,
- easing: Y.Easing.easeOut
- });
- // For testing, we don't do the animations or else the tests will fail.
- if (anim_times.fade > 0) {
- fade_in.run();
- }
- if (anim_times.slide_out > 0) {
- body_space.run();
- login_space.run();
- }
- },
-
- _hideBanner: function () {
- var body = Y.one('body');
- var global_notification = Y.one('.global-notification');
- var anim_times = this._getAnimTimes();
-
- global_notification.addClass('transparent');
-
- var fade_out = new Y.Anim({
- node: global_notification,
- to: {opacity: 0},
- duration: anim_times.fade
- });
- var body_space = new Y.Anim({
- node: body,
- to: {'paddingTop': 0},
- duration: anim_times.slide_out,
- easing: Y.Easing.easeOut
- });
- var login_space = new Y.Anim({
- node: '.login-logout',
- to: {'top': '6px'},
- duration: anim_times.slide_out,
- easing: Y.Easing.easeOut
- });
- fade_out.on('end', function() {
- global_notification.addClass('hidden');
- });
- body_space.on('end', function() {
- body.removeClass('global-notification-visible');
- });
-
- fade_out.run();
- body_space.run();
- login_space.run();
- },
-
- bindUI: function() {
- this.after('visibleChange', function() {
- if (this.get('visible')) {
- this._showBanner();
- } else {
- this._hideBanner();
- }
- });
- },
-
- renderUI: function () {
- var banner_data = {
- badge: this.get('banner_icon'),
- text: this.get('notification_text')
- };
- var banner_html = Y.lp.mustache.to_html(
- this.get('banner_template'),
- banner_data);
- this.get('contentBox').append(banner_html);
- },
-
- updateText: function (new_text) {
- var text_node = this.get('contentBox').one('.banner-text');
- if (!Y.Lang.isValue(new_text)) {
- new_text = this.get('notification_text');
- }
-
- if (text_node) {
- text_node.set('text', new_text);
- } else {
- Y.log('No text node to update banner text.', 'error');
- }
- }
-
-}, {
- ATTRS: {
- banner_icon: { value: "<span></span>" },
- banner_template: {
- valueFn: function() {
- return [
- '<div class="global-notification transparent hidden">',
- '{{{ badge }}}',
- '<span class="banner-text">{{ text }}</span>',
- "</div>"].join('');
- }
- },
- notification_text: { value: "" },
- skip_animation: { value: false },
- visible: { value: false }
- }
-});
-
-}, '0.1', {
- requires: ['base', 'node', 'anim', 'widget', 'lp.mustache', 'yui-log']
-});
=== removed file 'lib/lp/app/javascript/banners/beta-notification.js'
--- lib/lp/app/javascript/banners/beta-notification.js 2012-09-25 18:47:19 +0000
+++ lib/lp/app/javascript/banners/beta-notification.js 1970-01-01 00:00:00 +0000
@@ -1,104 +0,0 @@
-/**
- * Add a BetaBanner widget for use.
- *
- * @namespace lp.app.banner
- * @module beta
- *
- */
-YUI.add('lp.app.banner.beta', function(Y) {
-
-var ns = Y.namespace('lp.app.banner.beta');
-var Banner = Y.lp.app.banner.Banner;
-
-// For the beta banner to work, it needs to have one instance, and one
-// instance only.
-window._singleton_beta_banner = null;
-
-ns.show_beta_if_needed = function () {
- if (window._singleton_beta_banner === null) {
- var src = Y.one('.yui3-betabanner');
- window._singleton_beta_banner = new ns.BetaBanner({ srcNode: src });
- }
- if (window._singleton_beta_banner.get('features').length !== 0) {
- window._singleton_beta_banner.render();
- window._singleton_beta_banner.show();
- }
-};
-
-
-/**
- * Banner to display for beta features.
- *
- * @class BetaBanner
- * @extends Banner
- *
- */
-ns.BetaBanner = Y.Base.create('betaBanner', Banner, [], {
-
- bindUI: function () {
- Banner.prototype.bindUI.apply(this, arguments);
- var close_box = Y.one('.global-notification-close');
- var that = this;
- close_box.on('click', function(e) {
- e.halt();
- that.hide();
- });
- },
-
- renderUI: function () {
- var banner_data = {
- badge: this.get('banner_icon'),
- text: this.get('notification_text'),
- features: this.get('features'),
- };
- var banner_html = Y.lp.mustache.to_html(
- this.get('banner_template'),
- banner_data);
- this.get('contentBox').append(banner_html);
- var beta_node = Y.one('.global-notification');
- var close_box = Y.Node.create(
- '<a href="#" class="global-notification-close">Hide' +
- '<span class="notification-close sprite" /></a>');
- beta_node.appendChild(close_box);
- }
-
-}, {
- ATTRS: {
- banner_icon: { value: '<span class="beta-warning">BETA!</span>' },
-
- banner_template: {
- valueFn: function() {
- return [
- '<div class="global-notification transparent hidden">',
- '{{{ badge }}}',
- '<span class="banner-text">',
- '{{ text }}{{{ features }}}',
- '</span>',
- "</div>"].join('');
- }
- },
-
- features: {
- valueFn: function () {
- var features_template = [
- '{{#features}}{{#is_beta}}',
- '<span class="beta-feature"> {{title}}',
- '{{#url}}',
- ' (<a href="{{url}}" class="info-link">read more</a>)',
- '{{/url}}',
- '</span>',
- '{{/is_beta}}{{/features}}'].join('');
- var feature_data = {
- features: Y.Object.values(LP.cache.related_features)
- };
- return Y.lp.mustache.to_html(features_template, feature_data);
- }
- },
-
- notification_text: { value: "Some parts of this page are in beta: " }
- }
-});
-
-
-}, '0.1', {'requires': ['base', 'node', 'anim', 'lp.mustache',
- 'lp.app.banner']});
=== removed file 'lib/lp/app/javascript/banners/privacy.js'
--- lib/lp/app/javascript/banners/privacy.js 2012-10-04 14:17:23 +0000
+++ lib/lp/app/javascript/banners/privacy.js 1970-01-01 00:00:00 +0000
@@ -1,119 +0,0 @@
-/**
- * Add a PrivacyBanner widget for use.
- *
- * @namespace lp.app.banner
- * @module privacy
- *
- */
-YUI.add('lp.app.banner.privacy', function(Y) {
-var ns = Y.namespace('lp.app.banner.privacy');
-var Banner = Y.lp.app.banner.Banner;
-
-ns.EV_SHOW = 'privacy_banner:show';
-ns.EV_HIDE = 'privacy_banner:hide';
-
-/**
- * Allow for adjusting the global instance of the Privacy Banner via events.
- *
- * @event privacy_banner:show
- * @param text The message to show
- */
-Y.publish(ns.EV_SHOW, {
- emitFacade: true
-});
-
-/**
- * Hide the global instance of the banner via events.
- *
- * @event privacy_banner:hide
- */
-Y.publish(ns.EV_HIDE, {
- emitFacade: true
-});
-
-
-// For the privacy banner to work, it needs to have one instance, and one
-// instance only.
-window._singleton_privacy_banner = null;
-ns.getPrivacyBanner = function (banner_text, skip_animation) {
- if (window._singleton_privacy_banner === null) {
- var src = Y.one('.yui3-privacybanner');
- window._singleton_privacy_banner = new ns.PrivacyBanner(
- { srcNode: src, skip_animation: skip_animation });
- window._singleton_privacy_banner.render();
- }
- if (Y.Lang.isValue(banner_text)) {
- window._singleton_privacy_banner.updateText(banner_text);
- }
- return window._singleton_privacy_banner;
-};
-
-
-/**
- * Banner to display when page contains private information.
- *
- * @class PrivacyBanner
- * @extends Banner
- *
- */
-ns.PrivacyBanner = Y.Base.create('privacyBanner', Banner, [], {
- _custom_message: function (ev) {
- var body = Y.one('body');
- body.replaceClass('public', 'private');
- if (!ev.text) {
- throw('A custom privacy banner must have a text attribute');
- }
- this.updateText(ev.text);
- this.show();
- },
-
- _make_public: function (ev) {
- var body = Y.one('body');
- body.replaceClass('private', 'public');
- this.hide();
- },
-
- _make_private: function (ev) {
- // Update the text in the banner before we show it.
- var body = Y.one('body');
- body.replaceClass('public', 'private');
-
- if (!ev.text) {
- throw('Showing a privacy banner must supply text for the banner');
- }
- this.updateText(ev.text);
- this.show();
- },
-
- bindUI: function () {
- var that = this;
- var info_type = Y.lp.app.information_type;
- Banner.prototype.bindUI.apply(this, arguments);
-
- // We care about changes to Information Type in the UI.
- Y.on(info_type.EV_ISPUBLIC, that._make_public, that);
- Y.on(info_type.EV_ISPRIVATE, that._make_private, that);
-
- // And provide our own manual events for the Security banner usage.
- Y.on(ns.EV_SHOW, that._custom_message, that);
- Y.on(ns.EV_HIDE, function (ev) {
- that.hide();
- }, that);
- }
-
-}, {
- ATTRS: {
- banner_icon: {
- value: '<span class="sprite notification-private"></span>'
- },
- notification_text: {
- value: "The information on this page is private."
- }
- }
-});
-
-}, "0.1", {
- requires: [
- "base", "node", "anim", "lp.app.banner",
- "lp.app.information_type"]
-});
=== removed directory 'lib/lp/app/javascript/banners/tests'
=== removed file 'lib/lp/app/javascript/banners/tests/test_banner.html'
--- lib/lp/app/javascript/banners/tests/test_banner.html 2012-10-26 09:54:28 +0000
+++ lib/lp/app/javascript/banners/tests/test_banner.html 1970-01-01 00:00:00 +0000
@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2012 Canonical Ltd. This software is licensed under the
-GNU Affero General Public License version 3 (see the file LICENSE).
--->
-
-<html>
- <head>
- <title>lp.app.banner Tests</title>
-
- <!-- YUI and test setup -->
- <script type="text/javascript"
- src="../../../../../../build/js/yui/yui/yui.js">
- </script>
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/console/assets/console-core.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test-console/assets/skins/sam/test-console.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test/assets/skins/sam/test.css" />
-
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/testing/testrunner.js"></script>
-
- <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" />
-
- <!-- Dependencies -->
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/mustache.js"></script>
-
- <!-- The module under test. -->
- <script type="text/javascript" src="../banner.js"></script>
-
- <!-- Placeholder for any css asset for this module. -->
- <!-- <link rel="stylesheet" href="../assets/${LIBRARY}-core.css" /> -->
-
- <!-- The test suite -->
- <script type="text/javascript" src="test_banner.js"></script>
-
- </head>
- <body class="yui3-skin-sam">
- <ul id="suites">
- <li>lp.app.banner.test</li>
- </ul>
- </body>
-</html>
=== removed file 'lib/lp/app/javascript/banners/tests/test_banner.js'
--- lib/lp/app/javascript/banners/tests/test_banner.js 2012-10-26 10:00:20 +0000
+++ lib/lp/app/javascript/banners/tests/test_banner.js 1970-01-01 00:00:00 +0000
@@ -1,110 +0,0 @@
-/* Copyright (c) 2012, Canonical Ltd. All rights reserved. */
-
-YUI.add('lp.app.banner.test', function (Y) {
-
- var tests = Y.namespace('lp.app.banner.test');
- tests.suite = new Y.Test.Suite('lp.app.banner Tests');
-
- tests.suite.add(new Y.Test.Case({
- name: 'banner_tests',
-
- setUp: function () {
- var main = Y.Node.create('<div id="maincontent"></div>');
- var login_logout = Y.Node.create('<div></div>')
- .addClass('login-logout');
- main.appendChild(login_logout);
- Y.one('body').appendChild(main);
- },
-
- tearDown: function () {
- Y.one('#maincontent').remove(true);
- Y.all('.yui3-banner').remove(true);
- },
-
- test_library_exists: function () {
- Y.Assert.isObject(Y.lp.app.banner,
- "Could not locate the lp.app.banner module");
- },
-
- test_init_without_config: function () {
- var banner = new Y.lp.app.banner.Banner();
- Y.Assert.areEqual("", banner.get('notification_text'));
- Y.Assert.areEqual("<span></span>", banner.get('banner_icon'));
- },
-
- test_init_with_config: function () {
- var cfg = {
- notification_text: "Some text.",
- banner_icon: '<span class="sprite"></span>'
- };
- var banner = new Y.lp.app.banner.Banner(cfg);
- Y.Assert.areEqual(
- cfg.notification_text,
- banner.get('notification_text'));
- Y.Assert.areEqual(cfg.banner_icon, banner.get('banner_icon'));
- },
-
- test_render_no_config: function () {
- var banner = new Y.lp.app.banner.Banner({ skip_animation: true });
- banner.render();
-
- var banner_node = Y.one(".global-notification");
- Y.Assert.isObject(banner_node);
- Y.Assert.isTrue(banner_node.hasClass('hidden'));
- },
-
- test_render_with_config: function () {
- var cfg = {
- notification_text: "Some text.",
- banner_icon: '<span class="sprite"></span>',
- skip_animation: true
- };
- var banner = new Y.lp.app.banner.Banner(cfg);
- banner.render();
-
- var banner_node = Y.one(".global-notification");
- var badge = banner_node.one('.sprite');
- Y.Assert.isObject(banner_node);
- Y.Assert.areEqual(cfg.notification_text, banner_node.get('text'));
- Y.Assert.isObject(badge);
- },
-
- test_show: function() {
- var banner = new Y.lp.app.banner.Banner({ skip_animation: true });
- banner.render();
- banner.show();
- var banner_node = Y.one(".global-notification");
- Y.Assert.isFalse(banner_node.hasClass('hidden'));
- },
-
- test_hide: function() {
- var banner = new Y.lp.app.banner.Banner({ skip_animation: true });
- banner.render();
- banner.show();
-
- // Even with animation times set to 0, this test needs a slight
- // delay in order for the animation end events to fire.
- var banner_node = Y.one(".global-notification");
- var wait_for_anim = 20;
- var check = function () {
- Y.Assert.isTrue(banner_node.hasClass('hidden'));
- };
- banner.hide();
- this.wait(check, wait_for_anim);
- },
-
- test_updateText: function() {
- var banner = new Y.lp.app.banner.Banner({ skip_animation: true });
- banner.render();
- var new_text = 'some new text';
- banner.updateText(new_text);
- var banner_node = Y.one(".global-notification");
- Y.Assert.areEqual(new_text, banner_node.get('text'));
-
- banner.updateText();
- banner_node = Y.one(".global-notification");
- Y.Assert.areEqual("", banner_node.get('text'));
- }
- }));
-
-}, '0.1', {'requires': ['test', 'test-console', 'lp.app.banner']});
=== removed file 'lib/lp/app/javascript/banners/tests/test_beta_notification.html'
--- lib/lp/app/javascript/banners/tests/test_beta_notification.html 2012-10-26 09:54:28 +0000
+++ lib/lp/app/javascript/banners/tests/test_beta_notification.html 1970-01-01 00:00:00 +0000
@@ -1,51 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2012 Canonical Ltd. This software is licensed under the
-GNU Affero General Public License version 3 (see the file LICENSE).
--->
-
-<html>
- <head>
- <title>Test beta-notification</title>
-
- <!-- YUI and test setup -->
- <script type="text/javascript"
- src="../../../../../../build/js/yui/yui/yui.js">
- </script>
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/console/assets/console-core.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test-console/assets/skins/sam/test-console.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test/assets/skins/sam/test.css" />
-
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/testing/testrunner.js"></script>
-
- <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" />
-
- <!-- Dependencies -->
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/banners/banner.js"></script>
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/mustache.js"></script>
-
- <!-- The module under test. -->
- <script type="text/javascript" src="../beta-notification.js"></script>
-
- <!-- Placeholder for any css asset for this module. -->
- <!-- <link rel="stylesheet" href="../assets/beta-notification-core.css" /> -->
-
- <!-- The test suite. -->
- <script type="text/javascript" src="test_beta_notification.js"></script>
-
- </head>
- <body class="yui3-skin-sam">
- <ul id="suites">
- <!-- <li>lp.large_indicator.test</li> -->
- <li>lp.app.banner.beta.test</li>
- </ul>
- <!-- The example markup required by the script to run. -->
- <div id="maincontent"></div>
- </body>
-</html>
=== removed file 'lib/lp/app/javascript/banners/tests/test_beta_notification.js'
--- lib/lp/app/javascript/banners/tests/test_beta_notification.js 2012-10-26 10:00:20 +0000
+++ lib/lp/app/javascript/banners/tests/test_beta_notification.js 1970-01-01 00:00:00 +0000
@@ -1,140 +0,0 @@
-/* Copyright (c) 2012, Canonical Ltd. All rights reserved. */
-
-// Set the "enabled" variable, normally set by base-layout-macros.
-// This must be a global variable for the code being tested to work.
-var privacy_notification_enabled = true;
-
-YUI.add('lp.app.banner.beta.test', function (Y) {
-
- var tests = Y.namespace('lp.app.banner.beta.test');
- tests.suite = new Y.Test.Suite('lp.app.banner.beta Tests');
-
- tests.suite.add(new Y.Test.Case({
- name: 'beta-notification',
-
- setUp: function () {
- var main = Y.Node.create('<div id="maincontent"></div>');
- var login_logout = Y.Node.create('<div></div>')
- .addClass('login-logout');
- main.appendChild(login_logout);
- Y.one('body').append(main);
- window.LP = {
- cache: {}
- };
- },
-
- tearDown: function () {
- Y.one('#maincontent').remove(true);
- Y.all('.yui3-banner').remove(true);
- },
-
- test_library_exists: function () {
- Y.Assert.isObject(Y.lp.app.banner.beta,
- "Could not locate the lp.app.banner.beta module");
- },
-
- test_beta_banner_one_beta_feature: function() {
- LP.cache.related_features = {
- '': {
- is_beta: true,
- title: 'A beta feature',
- url: 'http://lp.dev/LEP/one'
- }};
- var betabanner = new Y.lp.app.banner.beta.BetaBanner(
- {skip_animation: true});
- betabanner.render();
- betabanner.show();
-
- var body = Y.one('body');
- // The <body> node has the class global-notification-visible,
- // so that the element has enough padding for the beta banner.
- Y.Assert.isTrue(body.hasClass('global-notification-visible'));
-
- feature_info = Y.one('.beta-feature');
- // The message about a beta feature consists of the feature
- // title and a link to a page with more information about
- // the feature.
- Y.Assert.areEqual(
- ' A beta feature (read more)', feature_info.get('text'));
- info_link = feature_info.get('children').item(0);
- Y.Assert.areEqual('http://lp.dev/LEP/one', info_link.get('href'));
- },
-
- test_beta_banner_two_beta_features: function() {
- LP.cache.related_features = {
- '1': {
- is_beta: true,
- title: 'Beta feature 1',
- url: 'http://lp.dev/LEP/one'
- },
- '2': {
- is_beta: true,
- title: 'Beta feature 2',
- url: ''
- }};
- var betabanner = new Y.lp.app.banner.beta.BetaBanner(
- {skip_animation: true});
- betabanner.render();
- betabanner.show();
-
- var body = Y.one('body');
- Y.Assert.isTrue(body.hasClass('global-notification-visible'));
-
- // Notifications about several features can be displayed.
- feature_info = Y.all('.beta-feature').item(0);
- Y.Assert.areEqual(
- ' Beta feature 1 (read more)', feature_info.get('text'));
- info_link = feature_info.get('children').item(0);
- Y.Assert.areEqual('http://lp.dev/LEP/one', info_link.get('href'));
-
- // If an entry in LP.cache.related_features does not provide a
- // "read more" link, the corrsponding node is not added.
- feature_info = Y.all('.beta-feature').item(1);
- Y.Assert.areEqual(
- ' Beta feature 2', feature_info.get('text'));
- Y.Assert.isNull(feature_info.get('children').item(0));
- },
-
- test_beta_banner_no_beta_features_defined: function() {
- LP.cache.related_features = {
- foo_feature: {
- is_beta: false,
- title: 'Non-beta feature',
- url: 'http://example.org'
- }};
- Y.lp.app.banner.beta.show_beta_if_needed();
- Y.Assert.isNull(Y.one('.global-notification'));
- },
-
- test_hide_beta_banner: function() {
- LP.cache.related_features = {
- '': {
- is_beta: true,
- title: 'A beta feature',
- url: 'http://lp.dev/LEP/one'
- }};
- var betabanner = new Y.lp.app.banner.beta.BetaBanner(
- {skip_animation: true});
- betabanner.render();
- betabanner.show();
- var body = Y.one('body');
- var banner = Y.one('.global-notification');
- Y.Assert.isFalse(banner.hasClass('hidden'));
-
- // Even with animation times set to 0, this test needs a slight
- // delay in order for the animation end events to fire.
- var check = function() {
- Y.Assert.isTrue(banner.hasClass('hidden'));
- Y.Assert.isFalse(
- body.hasClass('global-notification-visible'));
- };
- close_link = Y.one('.global-notification-close');
- close_link.simulate('click');
- var wait_time = 20;
- this.wait(check, wait_time);
- }
- }));
-
-}, '0.1', { 'requires': ['test', 'test-console', 'node', 'lp.app.banner.beta',
- 'node-event-simulate']
-});
=== removed file 'lib/lp/app/javascript/banners/tests/test_privacy.html'
--- lib/lp/app/javascript/banners/tests/test_privacy.html 2012-10-26 09:54:28 +0000
+++ lib/lp/app/javascript/banners/tests/test_privacy.html 1970-01-01 00:00:00 +0000
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2012 Canonical Ltd. This software is licensed under the
-GNU Affero General Public License version 3 (see the file LICENSE).
--->
-
-<html>
- <head>
- <title>lp.app.banner.privacy Tests</title>
-
- <!-- YUI and test setup -->
- <script type="text/javascript"
- src="../../../../../../build/js/yui/yui/yui.js">
- </script>
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/console/assets/console-core.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test-console/assets/skins/sam/test-console.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test/assets/skins/sam/test.css" />
-
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/testing/testrunner.js"></script>
-
- <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" />
-
- <!-- Dependencies -->
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/mustache.js"></script>
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/banners/banner.js"></script>
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/information_type.js"></script>
-
- <!-- The module under test. -->
- <script type="text/javascript" src="../privacy.js"></script>
-
- <!-- The test suite. -->
- <script type="text/javascript" src="test_privacy.js"></script>
-
- </head>
- <body class="yui3-skin-sam">
- <ul id="suites">
- <li>lp.app.banner.privacy.test</li>
- </ul>
- </body>
-</html>
=== removed file 'lib/lp/app/javascript/banners/tests/test_privacy.js'
--- lib/lp/app/javascript/banners/tests/test_privacy.js 2012-10-26 10:00:20 +0000
+++ lib/lp/app/javascript/banners/tests/test_privacy.js 1970-01-01 00:00:00 +0000
@@ -1,117 +0,0 @@
-/* Copyright 2011-2012 Canonical Ltd. This software is licensed under the
- * GNU Affero General Public License version 3 (see the file LICENSE).
- */
-
-YUI.add('lp.app.banner.privacy.test', function (Y) {
-
- var tests = Y.namespace('lp.app.banner.privacy.test');
- tests.suite = new Y.Test.Suite('lp.app.banner.privacy Tests');
-
- tests.suite.add(new Y.Test.Case({
- name: 'privacy_tests',
-
- setUp: function () {
- var main = Y.Node.create('<div id="maincontent"></div>');
- var login_logout = Y.Node.create('<div></div>')
- .addClass('login-logout');
- main.appendChild(login_logout);
-
- var banner_node = Y.Node.create('<div></div>')
- .addClass('yui3-privacybanner');
- main.appendChild(banner_node);
- Y.one('body').appendChild(main);
- },
-
- tearDown: function () {
- Y.one('#maincontent').remove(true);
- window._singleton_privacy_banner = null;
- delete window.LP;
- },
-
- test_library_exists: function () {
- Y.Assert.isObject(Y.lp.app.banner.privacy,
- "Could not locate the lp.app.banner.privacy module");
- },
- test_init: function () {
- var banner = new Y.lp.app.banner.privacy.PrivacyBanner();
- Y.Assert.areEqual(
- "The information on this page is private.",
- banner.get('notification_text'));
- Y.Assert.areEqual(
- '<span class="sprite notification-private"></span>',
- banner.get('banner_icon'));
- },
-
- test_only_one_banner: function () {
- // getPrivacyBanner only returns one banner.
- var banner = Y.lp.app.banner.privacy.getPrivacyBanner();
- Y.Assert.areEqual(1, Y.all('.global-notification').size());
-
- var new_text = 'This is new text';
- banner = Y.lp.app.banner.privacy.getPrivacyBanner(new_text);
- Y.Assert.areEqual(1, Y.all('.global-notification').size());
- var banner_node = Y.one('.global-notification');
- Y.Assert.areEqual(
- new_text,
- Y.one('.global-notification').get('text'));
- },
-
- test_banner_with_custom_text: function () {
- var banner = Y.lp.app.banner.privacy.getPrivacyBanner();
- var new_text = 'New custom text';
-
- Y.fire('privacy_banner:show', {
- text: new_text
- });
- Y.Assert.areEqual(
- new_text,
- Y.one('.global-notification').get('text'));
- Y.Assert.isTrue(banner.get('visible'),
- 'Banner should be visible.');
- },
-
- test_banner_hide_event: function () {
- var banner = Y.lp.app.banner.privacy.getPrivacyBanner();
- var new_text = 'New custom text';
-
- Y.fire('privacy_banner:show', {
- text: new_text
- });
- Y.fire('privacy_banner:hide');
- Y.Assert.isFalse(banner.get('visible'),
- 'Banner should not be visible.');
- },
-
- test_info_type_private_event: function () {
- var banner = Y.lp.app.banner.privacy.getPrivacyBanner();
- var body = Y.one('body');
- var msg = 'Some private message';
- Y.fire('information_type:is_private', {
- text: msg,
- value: 'PROPRIETARY'
- });
- Y.Assert.areEqual(
- msg,
- Y.one('.global-notification').get('text'));
- Y.Assert.isTrue(body.hasClass('private'),
- 'Body should be private');
- Y.Assert.isTrue(banner.get('visible'),
- 'Banner should be visible.');
- },
-
- test_info_type_public_event: function () {
- var banner = Y.lp.app.banner.privacy.getPrivacyBanner();
- var new_text = 'New custom text';
-
- Y.fire('privacy_banner:show', {
- text: new_text
- });
- Y.fire('information_type:is_public');
- var body = Y.one('body');
- Y.Assert.isTrue(body.hasClass('public'), 'Body should be public');
- Y.Assert.isFalse(banner.get('visible'),
- 'Banner should not be visible.');
- }
- }));
-
-}, '0.1', {'requires': ['test', 'test-console', 'lp.app.banner.privacy']});
=== modified file 'lib/lp/app/javascript/information_type.js'
--- lib/lp/app/javascript/information_type.js 2012-10-04 14:17:23 +0000
+++ lib/lp/app/javascript/information_type.js 2012-11-12 13:05:28 +0000
@@ -44,6 +44,29 @@
emitFacade: true
});
+
+/**
+ * Provide some logic to check if this is a private inducing event. This could
+ * be due to a non-public information type or as security related information
+ * type/value.
+ */
+var is_private_event = function (value) {
+ var is_private = false;
+ if (ns.get_cache_data_from_key(value,
+ 'value',
+ 'is_private')) {
+
+ is_private = true;
+ }
+
+ if (value.indexOf('SECURITY') !== -1) {
+ is_private = true;
+ }
+
+ return is_private;
+};
+
+
/**
* Wire up a helper event so that if someone changes the event, we take care
* of also firing any is_private/is_public event shortcuts others want to
@@ -53,14 +76,13 @@
* instead of having each module needing to know the location in the LP.cache
* and such.
*/
+
Y.on(ns.EV_CHANGE, function (ev) {
if (!ev.value) {
throw('Information type change event without new value');
}
- if (ns.get_cache_data_from_key(ev.value,
- 'value',
- 'is_private')) {
+ if (is_private_event(ev.value)) {
Y.fire(ns.EV_ISPRIVATE, {
text: ns.get_banner_text(ev.value),
value: ev.value
@@ -155,16 +177,33 @@
};
ns.get_banner_text = function(value) {
- var text_template = "This page contains {info_type} information.";
- var info_type = ns.get_cache_data_from_key(value, 'value', 'name');
- return Y.Lang.sub(text_template, {'info_type': info_type});
+ // Construct a different message for security related banner content.
+ var text;
+ if (value.indexOf('SECURITY') !== -1) {
+ var security_text = "This report will be private " +
+ "because it is a security " +
+ "vulnerability. You can " +
+ "disclose it later.";
+ text = security_text;
+ } else {
+ var text_template = "This page contains {info_type} information.";
+ var info_type = ns.get_cache_data_from_key(value, 'value', 'name');
+ text = Y.Lang.sub(text_template, {'info_type': info_type});
+ }
+ return text;
};
ns.save_success = function(widget, context, value, subscribers_list,
result_data) {
context.information_type =
ns.get_cache_data_from_key(value, 'value', 'name');
- ns.update_privacy_banner(value);
+
+ // Let the world know the information type has been updated. Allows
+ // banners to update.
+ Y.fire(ns.EV_CHANGE, {
+ value: value
+ });
+
widget._showSucceeded();
if (Y.Lang.isObject(result_data)) {
var subscribers = result_data.subscription_data;
@@ -344,27 +383,7 @@
}
};
-/**
- * Update the privacy banner to display the specified information type value.
- *
- * @param value
- */
-ns.update_privacy_banner = function(value) {
- var body = Y.one('body');
- var privacy_banner = Y.lp.app.banner.privacy.getPrivacyBanner(
- undefined, skip_animation);
- var private_type = LP.cache.information_type_data[value].is_private;
- if (private_type) {
- body.replaceClass('public', 'private');
- var banner_text = ns.get_banner_text(value);
- privacy_banner.updateText(banner_text);
- privacy_banner.show();
- } else {
- body.replaceClass('private', 'public');
- privacy_banner.hide();
- }
-};
}, "0.1", {"requires": [
"base", "oop", "node", "event", "io-base", "lp.mustache", "lp.app.choice",
- "lp.bugs.bugtask_index", "lp.app.banner.privacy", "lp.ui.choiceedit"]});
+ "lp.bugs.bugtask_index", "lp.ui.choiceedit"]});
=== modified file 'lib/lp/app/javascript/tests/test_information_type.js'
--- lib/lp/app/javascript/tests/test_information_type.js 2012-10-26 10:00:20 +0000
+++ lib/lp/app/javascript/tests/test_information_type.js 2012-11-12 13:05:28 +0000
@@ -84,22 +84,6 @@
privacy_link, this.lp_client, LP.cache.bug, null, true);
},
- _shim_privacy_banner: function () {
- var old_func = Y.lp.app.banner.privacy.getPrivacyBanner;
- Y.lp.app.banner.privacy.getPrivacyBanner = function () {
- return {
- show: function () { Y.fire('test:banner:show'); },
- hide: function () { Y.fire('test:banner:hide'); },
- updateText: function () { Y.fire('test:banner:update'); }
- };
- };
- return old_func;
- },
-
- _unshim_privacy_banner: function (old_func) {
- Y.lp.app.banner.privacy.getPrivacyBanner = old_func;
- },
-
test_library_exists: function () {
Y.Assert.isObject(Y.lp.app.information_type,
"Cannot locate the lp.app.information_type module");
@@ -142,53 +126,9 @@
ns.save_success = orig_save_success;
},
- // Setting a private type shows the privacy banner.
- test_save_success_private: function() {
- this.makeWidget();
- var old_func = this._shim_privacy_banner();
- var hide_flag = false;
- var update_flag = false;
- Y.on('test:banner:show', function() {
- hide_flag = true;
- });
- Y.on('test:banner:update', function() {
- update_flag = true;
- });
-
- ns.save_success(this.widget, LP.cache.bug,
- 'PROPRIETARY');
- var body = Y.one('body');
- Y.Assert.isTrue(body.hasClass('private'));
- Y.Assert.isTrue(hide_flag);
- Y.Assert.isTrue(update_flag);
- Y.Assert.areEqual(
- 'Proprietary', LP.cache.bug.information_type);
- this._unshim_privacy_banner(old_func);
- },
-
- // Setting a public type hides the privacy banner.
- test_save_success_public: function() {
- this.makeWidget();
- var old_func = this._shim_privacy_banner();
- var flag = false;
- Y.on('test:banner:hide', function() {
- flag = true;
- });
- var summary = Y.one('#information-type-summary');
- summary.replaceClass('public', 'private');
-
- ns.save_success(this.widget, 'PUBLIC', 'PUBLIC');
- var body = Y.one('body');
- Y.Assert.isTrue(body.hasClass('public'));
- Y.Assert.isTrue(flag);
- Y.Assert.areEqual('Public', LP.cache.bug.information_type);
- this._unshim_privacy_banner(old_func);
- },
-
// A successful save updates the subscribers portlet.
test_save_success_with_subscribers_data: function() {
this.makeWidget();
- var old_func = this._shim_privacy_banner();
var flag = false;
Y.on('test:banner:hide', function() {
flag = true;
@@ -216,7 +156,6 @@
Y.Assert.isTrue(load_subscribers_called);
Y.Assert.areEqual('value1', window.LP.cache.item1);
Y.Assert.areEqual('value2', window.LP.cache.item2);
- this._unshim_privacy_banner(old_func);
},
// A successful save updates the task actions.
=== added file 'lib/lp/app/javascript/ui/assets/skins/sam/banner.css'
--- lib/lp/app/javascript/ui/assets/skins/sam/banner.css 1970-01-01 00:00:00 +0000
+++ lib/lp/app/javascript/ui/assets/skins/sam/banner.css 2012-11-12 13:05:28 +0000
@@ -0,0 +1,109 @@
+/* JS Banner styling */
+.yui3-banner {
+ /* Default to not visible so we can fade in */
+ opacity: 1;
+
+ /* Animations for fade-in/out */
+ -webkit-transition: opacity 0.3s ease-in;
+ -moz-transition: opacity 0.3s ease-in;
+ transition: opacity 0.3s ease-in;
+
+ width: 100%;
+}
+
+.yui3-banner.yui3-banner-hidden {
+ opacity: 0;
+}
+
+/* Nasty hack to get the bar moved since it's absolutely positioned
+ * This also needs to be updated
+ */
+body.beta #locationbar, body.private #locationbar {
+ top: 47px;
+}
+
+/* If we have both classes make room for two banners height */
+body.beta.private #locationbar {
+ top: 94px;
+}
+
+/* If the container exists make sure we start out with the rest of the page
+ * bumped down the starting distance to reduce flash effect
+ */
+.beta_banner_container, .private_banner_container {
+ min-height: 45px;
+}
+
+.yui3-banner-content {
+ box-shadow: 0 0 5px #333;
+ background-color: #666;
+ color: #fff;
+ display: block;
+ font-size: 14px;
+ font-weight: bold;
+ line-height: 21px;
+ padding: 8px 20px;
+ text-align: left;
+ text-shadow: 0 -1px 0 #631616;
+ z-index: 10;
+}
+
+.yui3-banner-content .badge {
+ display: inline-block;
+ height: 21px;
+ margin-right: 10px;
+ padding: 0;
+ vertical-align: middle;
+ width: 20px;
+}
+.yui3-banner-content .banner-content {}
+
+.yui3-banner-content.beta {
+ /* Some of these are required to override .beta CSS */
+
+ /* Defined for browsers that don't support transparency */
+ background-color: #606060;
+ /* Transparent background for browsers that support it */
+ background-color: rgba(64, 64, 64, 0.9);
+ height: auto;
+ margin-top: 0px;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
+ width: auto;
+}
+.yui3-banner-content.beta .yui3-banner-content-content {}
+.yui3-banner-content.beta .badge {
+ /* sprite-ref: icon-sprites */
+ background-color: #c10000;
+ background: linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
+ background: -moz-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
+ background: -ms-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
+ background: -o-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
+ background: -webkit-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
+ border-radius: 5px;
+ border-top: 1px solid #e20000;
+ font-size: 12px;
+ font-weight: bold;
+ margin-right: 12px;
+ padding: 3px 6px 4px 6px;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ width: auto;
+}
+
+.yui3-banner-content.beta .beta-feature {
+ font-weight: bold;
+}
+.yui3-banner-content.beta .info-link {
+ color: #4884ef;
+}
+
+.yui3-banner-content.private {
+ /* Define colour for browsers that don't support transparency */
+ background: #8d1f1f;
+ /* Set transparent background for browsers that support it */
+ background: rgba(125,0,0,0.9);
+}
+.yui3-banner-content.private .banner-content {}
+.yui3-banner-content.private .badge {
+ background: url(/@@/notification-private.png);
+ background-repeat: no-repeat;
+}
=== removed file 'lib/lp/app/javascript/ui/assets/skins/sam/banner.css'
--- lib/lp/app/javascript/ui/assets/skins/sam/banner.css 2012-11-09 19:06:16 +0000
+++ lib/lp/app/javascript/ui/assets/skins/sam/banner.css 1970-01-01 00:00:00 +0000
@@ -1,109 +0,0 @@
-/* JS Banner styling */
-.yui3-banner {
- /* Default to not visible so we can fade in */
- opacity: 1;
-
- /* Animations for fade-in/out */
- -webkit-transition: opacity 0.3s ease-in;
- -moz-transition: opacity 0.3s ease-in;
- transition: opacity 0.3s ease-in;
-
- width: 100%;
-}
-
-.yui3-banner.yui3-banner-hidden {
- opacity: 0;
-}
-
-/* Nasty hack to get the bar moved since it's absolutely positioned
- * This also needs to be updated
- */
-body.beta #locationbar, body.private #locationbar {
- top: 47px;
-}
-
-/* If we have both classes make room for two banners height */
-body.beta.private #locationbar {
- top: 94px;
-}
-
-/* If the container exists make sure we start out with the rest of the page
- * bumped down the starting distance to reduce flash effect
- */
-.beta_banner_container, .private_banner_container {
- min-height: 45px;
-}
-
-.yui3-banner-content {
- box-shadow: 0 0 5px #333;
- background-color: #666;
- color: #fff;
- display: block;
- font-size: 14px;
- font-weight: bold;
- line-height: 21px;
- padding: 8px 20px;
- text-align: left;
- text-shadow: 0 -1px 0 #631616;
- z-index: 10;
-}
-
-.yui3-banner-content .badge {
- display: inline-block;
- height: 21px;
- margin-right: 10px;
- padding: 0;
- vertical-align: middle;
- width: 20px;
-}
-.yui3-banner-content .banner-content {}
-
-.yui3-banner-content.beta {
- /* Some of these are required to override .beta CSS */
-
- /* Defined for browsers that don't support transparency */
- background-color: #606060;
- /* Transparent background for browsers that support it */
- background-color: rgba(64, 64, 64, 0.9);
- height: auto;
- margin-top: 0px;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
- width: auto;
-}
-.yui3-banner-content.beta .yui3-banner-content-content {}
-.yui3-banner-content.beta .badge {
- /* sprite-ref: icon-sprites */
- background-color: #c10000;
- background: linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- background: -moz-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- background: -ms-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- background: -o-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- background: -webkit-linear-gradient(bottom, rgb(158,0,0) 0%, rgb(193,0,0) 70%);
- border-radius: 5px;
- border-top: 1px solid #e20000;
- font-size: 12px;
- font-weight: bold;
- margin-right: 12px;
- padding: 3px 6px 4px 6px;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
- width: auto;
-}
-
-.yui3-banner-content.beta .beta-feature {
- font-weight: bold;
-}
-.yui3-banner-content.beta .info-link {
- color: #4884ef;
-}
-
-.yui3-banner-content.private {
- /* Define colour for browsers that don't support transparency */
- background: #8d1f1f;
- /* Set transparent background for browsers that support it */
- background: rgba(125,0,0,0.9);
-}
-.yui3-banner-content.private .banner-content {}
-.yui3-banner-content.private .badge {
- background: url(/@@/notification-private.png);
- background-repeat: no-repeat;
-}
=== added file 'lib/lp/app/javascript/ui/banner.js'
--- lib/lp/app/javascript/ui/banner.js 1970-01-01 00:00:00 +0000
+++ lib/lp/app/javascript/ui/banner.js 2012-11-12 13:05:28 +0000
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2012 Canonical Ltd. This software is licensed under the
+ * GNU Affero General Public License version 3 (see the file LICENSE).
+ *
+ * Notification banner widget
+ *
+ * @module lp.ui.banner
+ * @namespace lp.ui
+ * @module banner
+ */
+YUI.add('lp.ui.banner', function (Y) {
+
+ var ns = Y.namespace('lp.ui.banner');
+
+ // GLOBALS
+ ns.PRIVATE = 'private';
+ ns.BETA = 'beta';
+
+ /**
+ * Banner widget base class
+ *
+ * This is the base Banner, you're supposed to supply some message data to
+ * generate the banner in the proper method.
+ *
+ * This banner provides all shared functionality between the Privacy and
+ * Beta banners.
+ *
+ * @class Banner
+ * @extends Y.Widget
+ *
+ */
+ ns.Banner = Y.Base.create('banner', Y.Widget, [], {
+ template: [
+ '<div class="banner">',
+ '<span class="badge {{ banner_type }}">{{ badge_text }}</span>',
+ '<span class="banner-content">{{{ content }}}</span>',
+ '</div>'
+ ].join(''),
+
+
+ /**
+ * Bind events that our widget supports such as closing the banner.
+ *
+ * We also watch the destroy event to clean up side effect css we
+ * created.
+ *
+ * @method bindUI
+ */
+ bindUI: function () {
+ this.on('destroy', function (ev) {
+ // XXX: Bug #1076074
+ var body = Y.one('body');
+ var banner_type = this.get('banner_type');
+ body.removeClass(banner_type);
+
+ // Remove any container the page might have provided for us to
+ // start out with.
+ var container_class = '.' + banner_type + '_banner_container';
+ var container = Y.one(container_class);
+ if (container) {
+ Y.one(container_class).remove();
+ }
+ });
+
+ this.after('contentChange', function () {
+ this.renderUI();
+ });
+ },
+
+ /**
+ * Default initialize method.
+ *
+ * @method initialize
+ * @param {Object} cfg
+ */
+ initialize: function (cfg) {
+ },
+
+ /**
+ * Widget render method to generate the html of the widget.
+ *
+ * @method renderUI
+ */
+ renderUI: function () {
+ var contentBox = this.get('contentBox');
+ contentBox.addClass(this.get('banner_type'));
+ var html = Y.lp.mustache.to_html(this.template, this.getAttrs());
+ contentBox.setHTML(html);
+
+ // XXX: Bug #1076074
+ // Needs to get cleaned up. Only applies to the global
+ // banners and not to other ones which we're working to allow.
+ // This is currently required because the #locationbar is
+ // absolutely located and needs to be moved as banners change.
+ var body = Y.one('body');
+ body.addClass(this.get('banner_type'));
+
+ if (this.get('visible')) {
+ this.show();
+ }
+ },
+
+ /**
+ * We need to override show so that we force a browser repaint which
+ * allows our CSS3 animation to run. Otherwise the browser sees we
+ * added new DOM elements and jumps straight to the finished animation
+ * point.
+ *
+ * @method show
+ */
+ show: function () {
+ var _node = this.get('boundingBox')._node;
+ var getComputedStyle = document.defaultView.getComputedStyle;
+ _node.style.display = getComputedStyle(_node).display;
+ return this.set('visible', true);
+ }
+
+ }, {
+ ATTRS: {
+ /**
+ * Instead of a sprite we might have text such as the Beta banner.
+ *
+ * @attribute badge_text
+ * @default undefined
+ * @type {String}
+ */
+ badge_text: {},
+
+ /**
+ * The Banner is meant to house some message to the user provided
+ * by this content. It can be html and is not escaped for that
+ * reason.
+ *
+ * @attribute content
+ * @default undefined
+ * @type {String}
+ */
+ content: {},
+
+ /**
+ * This is listed to help aid in discovery of how the container
+ * node for the widget is determined. It's passed into the
+ * render() method and the Widget constructs itself inside of
+ * there.
+ *
+ * @attribute boundingBox
+ * @default undefined
+ * @type {Node}
+ */
+ boundingBox: {
+
+ },
+
+ /**
+ * Much of the Widget is determined by the type of banner it is.
+ * See the constants defined PRIVATE and BETA for two known types.
+ * If you set this manually you'll be able to provide custom
+ * styling as required because the type is used as a css class
+ * property.
+ *
+ * @attribute banner_type
+ * @default undefined
+ * @type {String}
+ */
+ banner_type: {},
+
+ /**
+ * Start out as not visible which should render as opacity 0, then
+ * we update it and it animates due to our css3.
+ *
+ * @attribute visible
+ * @default false
+ * @type {Bool}
+ */
+ visible: {
+ value: false
+ }
+ }
+ });
+
+ /**
+ * Beta Banner widget
+ *
+ * This is the Beta feature banner which needs to know about the title and
+ * url of the feature to construct the content correctly. Features are
+ * meant to be matched to the current LP.cache.related_features data
+ * available.
+ *
+ * @class BetaBanner
+ * @extends Banner
+ *
+ */
+ ns.BetaBanner = Y.Base.create('banner', ns.Banner, [], {
+
+ }, {
+ ATTRS: {
+ /**
+ * @attribute badge_text
+ * @default "BETA!"
+ * @type {String}
+ */
+ badge_text: {
+ value: 'BETA!'
+ },
+
+ /**
+ * The content for the beta banner is constructed from hard coded
+ * content and the list of enabled beta features currently
+ * relevant to the page.
+ *
+ * @attribute content
+ * @default {generated}
+ * @type {String}
+ */
+ content: {
+ getter: function () {
+ var content = "Some parts of this page are in beta: ";
+ var key;
+ // We need to process the features to build the features
+ // that apply.
+ var features = this.get('features');
+ for (key in features) {
+ if (features.hasOwnProperty(key)) {
+ var obj = features[key];
+ if (obj.is_beta) {
+ content = content + [
+ '<span class="beta-feature">',
+ obj.title,
+ ' <a class="info-link" href="',
+ obj.url + '">(read more)</a>',
+ '</span>'
+ ].join('');
+ }
+ }
+ }
+ return content;
+ }
+ },
+
+ /**
+ * features is a nested object of the beta features going. See
+ * LP.cache.related_features for the list of features. We only
+ * want those related features that are in beta.
+ * Ex: {
+ * disclosure.private_projects.enabled: {
+ * is_beta: true,
+ * title: "",
+ * url: "http://blog.ld.net/general/private-projects-beta",
+ * value: "true"
+ * }
+ * }
+ * @attribute features
+ * @default {}
+ * @type {Object}
+ */
+ features: {},
+
+ /**
+ * Manually force the banner type so users don't need to set it.
+ * This is a beta banner class.
+ *
+ * @attribute banner_type
+ * @default BETA
+ * @type {String}
+ */
+ banner_type: {
+ value: ns.BETA
+ }
+
+ }
+ });
+
+ /**
+ * Private Banner widget
+ *
+ * This is the Private feature banner which is pretty basic.
+ *
+ * Note that this doesn't automatically follow the information type code.
+ * Nor does it listen to the choice widgets and try to update. It's purely
+ * meant to function as told to do so. Most of the work around making sure
+ * the banner shows and works properly is in the View code in global.js.
+ *
+ * @class PrivateBanner
+ * @extends Banner
+ *
+ */
+ ns.PrivateBanner = Y.Base.create('banner', ns.Banner, [], {
+
+ }, {
+ ATTRS: {
+ badge_text: {
+ value: ''
+ },
+
+ content: {
+ value: 'The information on this page is private.'
+ },
+
+ /**
+ * Manually force the banner type so users don't need to set it.
+ * This is a beta banner class.
+ *
+ * @attribute banner_type
+ * @default BETA
+ * @type {String}
+ */
+ banner_type: {
+ value: ns.PRIVATE
+ }
+ }
+ });
+
+}, '0.1', {
+ requires: ['base', 'node', 'anim', 'widget', 'lp.mustache', 'yui-log']
+});
=== removed file 'lib/lp/app/javascript/ui/banner.js'
--- lib/lp/app/javascript/ui/banner.js 2012-11-09 18:55:02 +0000
+++ lib/lp/app/javascript/ui/banner.js 1970-01-01 00:00:00 +0000
@@ -1,315 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd. This software is licensed under the
- * GNU Affero General Public License version 3 (see the file LICENSE).
- *
- * Notification banner widget
- *
- * @module lp.ui.banner
- * @namespace lp.ui
- * @module banner
- */
-YUI.add('lp.ui.banner', function (Y) {
-
- var ns = Y.namespace('lp.ui.banner');
-
- // GLOBALS
- ns.PRIVATE = 'private';
- ns.BETA = 'beta';
-
- /**
- * Banner widget base class
- *
- * This is the base Banner, you're supposed to supply some message data to
- * generate the banner in the proper method.
- *
- * This banner provides all shared functionality between the Privacy and
- * Beta banners.
- *
- * @class Banner
- * @extends Y.Widget
- *
- */
- ns.Banner = Y.Base.create('banner', Y.Widget, [], {
- template: [
- '<div class="banner">',
- '<span class="badge {{ banner_type }}">{{ badge_text }}</span>',
- '<span class="banner-content">{{{ content }}}</span>',
- '</div>'
- ].join(''),
-
-
- /**
- * Bind events that our widget supports such as closing the banner.
- *
- * We also watch the destroy event to clean up side effect css we
- * created.
- *
- * @method bindUI
- */
- bindUI: function () {
- this.on('destroy', function (ev) {
- // XXX: Bug #1076074
- var body = Y.one('body');
- var banner_type = this.get('banner_type');
- body.removeClass(banner_type);
-
- // Remove any container the page might have provided for us to
- // start out with.
- var container_class = '.' + banner_type + '_banner_container';
- var container = Y.one(container_class);
- if (container) {
- Y.one(container_class).remove();
- }
- });
-
- this.after('contentChange', function () {
- this.renderUI();
- });
- },
-
- /**
- * Default initialize method.
- *
- * @method initialize
- * @param {Object} cfg
- */
- initialize: function (cfg) {
- },
-
- /**
- * Widget render method to generate the html of the widget.
- *
- * @method renderUI
- */
- renderUI: function () {
- var contentBox = this.get('contentBox');
- contentBox.addClass(this.get('banner_type'));
- var html = Y.lp.mustache.to_html(this.template, this.getAttrs());
- contentBox.setHTML(html);
-
- // XXX: Bug #1076074
- // Needs to get cleaned up. Only applies to the global
- // banners and not to other ones which we're working to allow.
- // This is currently required because the #locationbar is
- // absolutely located and needs to be moved as banners change.
- var body = Y.one('body');
- body.addClass(this.get('banner_type'));
-
- if (this.get('visible')) {
- this.show();
- }
- },
-
- /**
- * We need to override show so that we force a browser repaint which
- * allows our CSS3 animation to run. Otherwise the browser sees we
- * added new DOM elements and jumps straight to the finished animation
- * point.
- *
- * @method show
- */
- show: function () {
- var _node = this.get('boundingBox')._node;
- var getComputedStyle = document.defaultView.getComputedStyle;
- _node.style.display = getComputedStyle(_node).display;
- return this.set('visible', true);
- }
-
- }, {
- ATTRS: {
- /**
- * Instead of a sprite we might have text such as the Beta banner.
- *
- * @attribute badge_text
- * @default undefined
- * @type {String}
- */
- badge_text: {},
-
- /**
- * The Banner is meant to house some message to the user provided
- * by this content. It can be html and is not escaped for that
- * reason.
- *
- * @attribute content
- * @default undefined
- * @type {String}
- */
- content: {},
-
- /**
- * This is listed to help aid in discovery of how the container
- * node for the widget is determined. It's passed into the
- * render() method and the Widget constructs itself inside of
- * there.
- *
- * @attribute boundingBox
- * @default undefined
- * @type {Node}
- */
- boundingBox: {
-
- },
-
- /**
- * Much of the Widget is determined by the type of banner it is.
- * See the constants defined PRIVATE and BETA for two known types.
- * If you set this manually you'll be able to provide custom
- * styling as required because the type is used as a css class
- * property.
- *
- * @attribute banner_type
- * @default undefined
- * @type {String}
- */
- banner_type: {},
-
- /**
- * Start out as not visible which should render as opacity 0, then
- * we update it and it animates due to our css3.
- *
- * @attribute visible
- * @default false
- * @type {Bool}
- */
- visible: {
- value: false
- }
- }
- });
-
- /**
- * Beta Banner widget
- *
- * This is the Beta feature banner which needs to know about the title and
- * url of the feature to construct the content correctly. Features are
- * meant to be matched to the current LP.cache.related_features data
- * available.
- *
- * @class BetaBanner
- * @extends Banner
- *
- */
- ns.BetaBanner = Y.Base.create('banner', ns.Banner, [], {
-
- }, {
- ATTRS: {
- /**
- * @attribute badge_text
- * @default "BETA!"
- * @type {String}
- */
- badge_text: {
- value: 'BETA!'
- },
-
- /**
- * The content for the beta banner is constructed from hard coded
- * content and the list of enabled beta features currently
- * relevant to the page.
- *
- * @attribute content
- * @default {generated}
- * @type {String}
- */
- content: {
- getter: function () {
- var content = "Some parts of this page are in beta: ";
- var key;
- // We need to process the features to build the features
- // that apply.
- var features = this.get('features');
- for (key in features) {
- if (features.hasOwnProperty(key)) {
- var obj = features[key];
- if (obj.is_beta) {
- content = content + [
- '<span class="beta-feature">',
- obj.title,
- ' <a class="info-link" href="',
- obj.url + '">(read more)</a>',
- '</span>'
- ].join('');
- }
- }
- }
- return content;
- }
- },
-
- /**
- * features is a nested object of the beta features going. See
- * LP.cache.related_features for the list of features. We only
- * want those related features that are in beta.
- * Ex: {
- * disclosure.private_projects.enabled: {
- * is_beta: true,
- * title: "",
- * url: "http://blog.ld.net/general/private-projects-beta",
- * value: "true"
- * }
- * }
- * @attribute features
- * @default {}
- * @type {Object}
- */
- features: {},
-
- /**
- * Manually force the banner type so users don't need to set it.
- * This is a beta banner class.
- *
- * @attribute banner_type
- * @default BETA
- * @type {String}
- */
- banner_type: {
- value: ns.BETA
- }
-
- }
- });
-
- /**
- * Private Banner widget
- *
- * This is the Private feature banner which is pretty basic.
- *
- * Note that this doesn't automatically follow the information type code.
- * Nor does it listen to the choice widgets and try to update. It's purely
- * meant to function as told to do so. Most of the work around making sure
- * the banner shows and works properly is in the View code in global.js.
- *
- * @class PrivateBanner
- * @extends Banner
- *
- */
- ns.PrivateBanner = Y.Base.create('banner', ns.Banner, [], {
-
- }, {
- ATTRS: {
- badge_text: {
- value: ''
- },
-
- content: {
- value: 'The information on this page is private.'
- },
-
- /**
- * Manually force the banner type so users don't need to set it.
- * This is a beta banner class.
- *
- * @attribute banner_type
- * @default BETA
- * @type {String}
- */
- banner_type: {
- value: ns.PRIVATE
- }
- }
- });
-
-}, '0.1', {
- requires: ['base', 'node', 'anim', 'widget', 'lp.mustache', 'yui-log']
-});
=== added directory 'lib/lp/app/javascript/ui/tests'
=== removed directory 'lib/lp/app/javascript/ui/tests'
=== added file 'lib/lp/app/javascript/ui/tests/test_banner.html'
--- lib/lp/app/javascript/ui/tests/test_banner.html 1970-01-01 00:00:00 +0000
+++ lib/lp/app/javascript/ui/tests/test_banner.html 2012-11-12 13:05:28 +0000
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!--
+Copyright 2012 Canonical Ltd. This software is licensed under the
+GNU Affero General Public License version 3 (see the file LICENSE).
+-->
+
+<html>
+ <head>
+ <title>lp.ui.banner Tests</title>
+
+ <!-- YUI and test setup -->
+ <script type="text/javascript"
+ src="../../../../../../build/js/yui/yui/yui.js">
+ </script>
+ <link rel="stylesheet"
+ href="../../../../../../build/js/yui/console/assets/console-core.css" />
+ <link rel="stylesheet"
+ href="../../../../../../build/js/yui/test-console/assets/skins/sam/test-console.css" />
+ <link rel="stylesheet"
+ href="../../../../../../build/js/yui/test/assets/skins/sam/test.css" />
+
+ <script type="text/javascript"
+ src="../../../../../../build/js/lp/app/testing/testrunner.js"></script>
+ <script type="text/javascript"
+ src="../../../../../build/js/lp/app/testing/helpers.js"></script>
+
+ <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" />
+
+ <!-- Dependencies -->
+ <script type="text/javascript"
+ src="../../../../../../build/js/lp/app/mustache.js"></script>
+
+ <!-- The module under test. -->
+ <script type="text/javascript" src="../banner.js"></script>
+
+ <!-- Placeholder for any css asset for this module. -->
+ <link rel="stylesheet" href="../assets/skins/sam/banner.css" />
+
+ <!-- The test suite -->
+ <script type="text/javascript" src="test_banner.js"></script>
+
+ </head>
+ <body class="yui3-skin-sam">
+ <ul id="suites">
+ <li>lp.ui.banner.test</li>
+ </ul>
+ <div id="fixture"></div>
+ </body>
+</html>
=== removed file 'lib/lp/app/javascript/ui/tests/test_banner.html'
--- lib/lp/app/javascript/ui/tests/test_banner.html 2012-11-09 18:46:31 +0000
+++ lib/lp/app/javascript/ui/tests/test_banner.html 1970-01-01 00:00:00 +0000
@@ -1,49 +0,0 @@
-<!DOCTYPE html>
-<!--
-Copyright 2012 Canonical Ltd. This software is licensed under the
-GNU Affero General Public License version 3 (see the file LICENSE).
--->
-
-<html>
- <head>
- <title>lp.ui.banner Tests</title>
-
- <!-- YUI and test setup -->
- <script type="text/javascript"
- src="../../../../../../build/js/yui/yui/yui.js">
- </script>
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/console/assets/console-core.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test-console/assets/skins/sam/test-console.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test/assets/skins/sam/test.css" />
-
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/testing/testrunner.js"></script>
- <script type="text/javascript"
- src="../../../../../build/js/lp/app/testing/helpers.js"></script>
-
- <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" />
-
- <!-- Dependencies -->
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/mustache.js"></script>
-
- <!-- The module under test. -->
- <script type="text/javascript" src="../banner.js"></script>
-
- <!-- Placeholder for any css asset for this module. -->
- <link rel="stylesheet" href="../assets/skins/sam/banner.css" />
-
- <!-- The test suite -->
- <script type="text/javascript" src="test_banner.js"></script>
-
- </head>
- <body class="yui3-skin-sam">
- <ul id="suites">
- <li>lp.ui.banner.test</li>
- </ul>
- <div id="fixture"></div>
- </body>
-</html>
=== added file 'lib/lp/app/javascript/ui/tests/test_banner.js'
--- lib/lp/app/javascript/ui/tests/test_banner.js 1970-01-01 00:00:00 +0000
+++ lib/lp/app/javascript/ui/tests/test_banner.js 2012-11-12 13:05:28 +0000
@@ -0,0 +1,289 @@
+/* Copyright (c) 2012 Canonical Ltd. All rights reserved. */
+
+YUI.add('lp.ui.banner.test', function (Y) {
+
+ var tests = Y.namespace('lp.ui.banner.test');
+ tests.suite = new Y.Test.Suite('ui.banner Tests');
+
+ var ns = Y.lp.ui.banner;
+
+ tests.suite.add(new Y.Test.Case({
+ name: 'ui.banner_tests',
+
+ setUp: function () {
+ this.container = Y.one('#fixture');
+ },
+
+ tearDown: function () {
+ this.container.empty();
+ },
+
+ test_library_exists: function () {
+ Y.Assert.isObject(Y.lp.ui.banner,
+ "Could not locate the lp.ui.banner module");
+ },
+
+ test_render: function () {
+ var b = new ns.Banner();
+ b.render(this.container);
+
+ var banners = Y.all('.banner');
+ Y.Assert.areEqual(
+ 1,
+ banners._nodes.length,
+ 'We have one banner node');
+
+ // The banner should make sure it's in the container as well.
+ var contained_banners = Y.all('#fixture .banner');
+ Y.Assert.areEqual(
+ 1,
+ contained_banners._nodes.length,
+ 'Banner node is placed.');
+ },
+
+ test_render_content: function () {
+ var msg = 'This is a banner message. Fear me.',
+ b = new ns.Banner({
+ content: msg
+ });
+
+ b.render(this.container);
+
+ var banner = Y.one('.banner');
+ Y.Assert.areEqual(
+ msg,
+ banner.one('.banner-content').get('text')
+ );
+ },
+
+ test_render_private_type: function () {
+ var msg = 'Private!',
+ b = new ns.Banner({
+ content: msg,
+ banner_type: ns.PRIVATE
+ });
+
+ b.render(this.container);
+
+ var banner = Y.one('.banner');
+ Y.Assert.areEqual(
+ msg,
+ banner.one('.banner-content').get('text'),
+ 'The banner should have the private message.'
+ );
+
+ var badge = banner.one('.badge');
+
+ Y.Assert.isTrue(
+ badge.hasClass('private'),
+ 'The badge should have a private class on it.');
+
+ },
+
+ test_render_beta_type: function () {
+ var msg = 'BETA!',
+ b = new ns.Banner({
+ content: msg,
+ banner_type: ns.BETA
+ });
+
+ b.render(this.container);
+
+ var banner = Y.one('.banner');
+ Y.Assert.areEqual(
+ msg,
+ banner.one('.banner-content').get('text'),
+ 'The banner should have the beta message.'
+ );
+
+ var badge = banner.one('.badge');
+
+ Y.Assert.isTrue(
+ badge.hasClass('beta'),
+ 'The badge should have a beta class on it.');
+ },
+
+ test_render_badge_text: function () {
+ // We can set the badge to contain text.
+ var badge = 'BETA!',
+ b = new ns.Banner({
+ badge_text: badge,
+ banner_type: ns.BETA
+ });
+
+ b.render(this.container);
+ var banner = Y.one('.banner');
+ Y.Assert.areEqual(
+ badge,
+ banner.one('.badge').get('text'),
+ 'The badge should have the beta message.'
+ );
+ },
+
+ test_banner_text_update: function () {
+ // The banner should update the rendered text when the content
+ // ATTR is changed.
+ var msg = 'This is a banner message. Fear me.',
+ b = new ns.Banner({
+ content: msg
+ });
+
+ b.render(this.container);
+
+ var banner = Y.one('.banner');
+ Y.Assert.areEqual(
+ msg,
+ banner.one('.banner-content').get('text')
+ );
+
+ // Now change the content on the widget and check again.
+ var new_msg = 'Updated me!';
+ b.set('content', new_msg);
+ banner = Y.one('.banner');
+ Y.Assert.areEqual(
+ new_msg,
+ banner.one('.banner-content').get('text')
+ );
+ }
+ }));
+
+
+ tests.suite.add(new Y.Test.Case({
+ name: 'ui.beta_banner_tests',
+
+ setUp: function () {
+ this.container = Y.one('#fixture');
+ },
+
+ tearDown: function () {
+ this.container.empty();
+ },
+
+ test_base_beta_banner: function () {
+ // The beta banner is auto set to the right type, has the right
+ // badge text.
+ var badge = 'BETA!',
+ msg = 'are in beta:',
+ b = new ns.BetaBanner({
+ });
+
+ b.render(this.container);
+ var banner = Y.one('.banner');
+ Y.Assert.areEqual(
+ badge,
+ banner.one('.badge').get('text'),
+ 'The badge should have the beta message.'
+ );
+
+ Y.Assert.areEqual(
+ ns.BETA,
+ b.get('banner_type'),
+ 'The banner should be the right type.'
+ );
+
+ Y.Assert.areNotEqual(
+ -1,
+ banner.one('.banner-content').get('text').indexOf(msg),
+ 'The badge should have beta content.'
+ );
+ },
+
+ test_beta_features: function () {
+ // The features fed to the banner effect display of the messages.
+ var features = {
+ private_projects: {
+ is_beta: true,
+ title: "Private Projects",
+ url: "http://blog.ld.net/general/private-projects-beta",
+ value: "true"
+ },
+ test_projects: {
+ is_beta: true,
+ title: "Test Projects",
+ url: "http://blog.ld.net/general/private-projects-beta",
+ value: "true"
+ },
+ no_beta: {
+ is_beta: false,
+ title: "Better not see me",
+ url: "http://blog.ld.net/general/private-projects-beta",
+ value: "true"
+ },
+ };
+
+ var b = new ns.BetaBanner({
+ features: features
+ });
+
+ b.render(this.container);
+
+ var banner = Y.one('.banner'),
+ banner_content = banner.one('.banner-content').get('text');
+
+ Y.Assert.areNotEqual(
+ -1,
+ banner_content.indexOf(features.private_projects.title),
+ 'The private projects feature should be displayed.'
+ );
+
+ Y.Assert.areNotEqual(
+ -1,
+ banner_content.indexOf(features.test_projects.title),
+ 'Also test projects since we support multiple features.'
+ );
+
+ Y.Assert.areEqual(
+ -1,
+ banner_content.indexOf(features.no_beta.title),
+ 'But not no beta since we only support beta features.'
+ );
+ },
+
+
+ }));
+
+
+ tests.suite.add(new Y.Test.Case({
+ name: 'ui.private_banner_tests',
+
+ setUp: function () {
+ this.container = Y.one('#fixture');
+ },
+
+ tearDown: function () {
+ this.container.empty();
+ },
+
+ test_base_private_banner: function () {
+ // The private banner is auto set to the right type, has the right
+ // badge text.
+ var badge = '',
+ msg = 'page is private',
+ b = new ns.PrivateBanner({
+ });
+
+ b.render(this.container);
+ var banner = Y.one('.banner');
+ Y.Assert.areEqual(
+ badge,
+ banner.one('.badge').get('text'),
+ 'The badge should be empty'
+ );
+
+ Y.Assert.areEqual(
+ ns.PRIVATE,
+ b.get('banner_type'),
+ 'The banner should be the right type.'
+ );
+
+ Y.Assert.areNotEqual(
+ -1,
+ banner.one('.banner-content').get('text').indexOf(msg),
+ 'The badge should have a private warning.'
+ );
+ }
+ }));
+
+}, '0.1', {
+ requires: ['test', 'lp.testing.helpers', 'lp.ui.banner']
+});
=== removed file 'lib/lp/app/javascript/ui/tests/test_banner.js'
--- lib/lp/app/javascript/ui/tests/test_banner.js 2012-11-09 18:55:02 +0000
+++ lib/lp/app/javascript/ui/tests/test_banner.js 1970-01-01 00:00:00 +0000
@@ -1,287 +0,0 @@
-/* Copyright (c) 2012 Canonical Ltd. All rights reserved. */
-
-YUI.add('lp.ui.banner.test', function (Y) {
-
- var tests = Y.namespace('lp.ui.banner.test');
- tests.suite = new Y.Test.Suite('ui.banner Tests');
-
- var ns = Y.lp.ui.banner;
-
- tests.suite.add(new Y.Test.Case({
- name: 'ui.banner_tests',
-
- setUp: function () {
- this.container = Y.one('#fixture');
- },
-
- tearDown: function () {
- this.container.empty();
- },
-
- test_library_exists: function () {
- Y.Assert.isObject(Y.lp.ui.banner,
- "Could not locate the lp.ui.banner module");
- },
-
- test_render: function () {
- var b = new ns.Banner();
- b.render(this.container);
-
- var banners = Y.all('.banner');
- Y.Assert.areEqual(
- 1,
- banners._nodes.length,
- 'We have one banner node');
-
- // The banner should make sure it's in the container as well.
- var contained_banners = Y.all('#fixture .banner');
- Y.Assert.areEqual(
- 1,
- contained_banners._nodes.length,
- 'Banner node is placed.');
- },
-
- test_render_content: function () {
- var msg = 'This is a banner message. Fear me.',
- b = new ns.Banner({
- content: msg
- });
-
- b.render(this.container);
-
- var banner = Y.one('.banner');
- Y.Assert.areEqual(
- msg,
- banner.one('.banner-content').get('text')
- );
- },
-
- test_render_private_type: function () {
- var msg = 'Private!',
- b = new ns.Banner({
- content: msg,
- banner_type: ns.PRIVATE
- });
-
- b.render(this.container);
-
- var banner = Y.one('.banner');
- Y.Assert.areEqual(
- msg,
- banner.one('.banner-content').get('text'),
- 'The banner should have the private message.'
- );
-
- var badge = banner.one('.badge');
-
- Y.Assert.isTrue(
- badge.hasClass('private'),
- 'The badge should have a private class on it.');
-
- },
-
- test_render_beta_type: function () {
- var msg = 'BETA!',
- b = new ns.Banner({
- content: msg,
- banner_type: ns.BETA
- });
-
- b.render(this.container);
-
- var banner = Y.one('.banner');
- Y.Assert.areEqual(
- msg,
- banner.one('.banner-content').get('text'),
- 'The banner should have the beta message.'
- );
-
- var badge = banner.one('.badge');
-
- Y.Assert.isTrue(
- badge.hasClass('beta'),
- 'The badge should have a beta class on it.');
- },
-
- test_render_badge_text: function () {
- // We can set the badge to contain text.
- var badge = 'BETA!',
- b = new ns.Banner({
- badge_text: badge,
- banner_type: ns.BETA
- });
-
- b.render(this.container);
- var banner = Y.one('.banner');
- Y.Assert.areEqual(
- badge,
- banner.one('.badge').get('text'),
- 'The badge should have the beta message.'
- );
- },
-
- test_banner_text_update: function () {
- // The banner should update the rendered text when the content
- // ATTR is changed.
- var msg = 'This is a banner message. Fear me.',
- b = new ns.Banner({
- content: msg
- });
-
- b.render(this.container);
-
- var banner = Y.one('.banner');
- Y.Assert.areEqual(
- msg,
- banner.one('.banner-content').get('text')
- );
-
- // Now change the content on the widget and check again.
- var new_msg = 'Updated me!';
- b.set('content', new_msg);
- banner = Y.one('.banner');
- Y.Assert.areEqual(
- new_msg,
- banner.one('.banner-content').get('text')
- );
- }
- }));
-
-
- tests.suite.add(new Y.Test.Case({
- name: 'ui.beta_banner_tests',
-
- setUp: function () {
- this.container = Y.one('#fixture');
- },
-
- tearDown: function () {
- this.container.empty();
- },
-
- test_base_beta_banner: function () {
- // The beta banner is auto set to the right type, has the right
- // badge text.
- var badge = 'BETA!',
- msg = 'are in beta:',
- b = new ns.BetaBanner({
- });
-
- b.render(this.container);
- var banner = Y.one('.banner');
- Y.Assert.areEqual(
- badge,
- banner.one('.badge').get('text'),
- 'The badge should have the beta message.'
- );
-
- Y.Assert.areEqual(
- ns.BETA,
- b.get('banner_type'),
- 'The banner should be the right type.'
- );
-
- Y.Assert.areNotEqual(
- -1,
- banner.one('.banner-content').get('text').indexOf(msg),
- 'The badge should have beta content.'
- );
- },
-
- test_beta_features: function () {
- // The features fed to the banner effect display of the messages.
- var features = {
- private_projects: {
- is_beta: true,
- title: "Private Projects",
- url: "http://blog.ld.net/general/private-projects-beta",
- value: "true"
- },
- test_projects: {
- is_beta: true,
- title: "Test Projects",
- url: "http://blog.ld.net/general/private-projects-beta",
- value: "true"
- },
- no_beta: {
- is_beta: false,
- title: "Better not see me",
- url: "http://blog.ld.net/general/private-projects-beta",
- value: "true"
- }
- };
-
- var b = new ns.BetaBanner({
- features: features
- });
-
- b.render(this.container);
-
- var banner = Y.one('.banner'),
- banner_content = banner.one('.banner-content').get('text');
-
- Y.Assert.areNotEqual(
- -1,
- banner_content.indexOf(features.private_projects.title),
- 'The private projects feature should be displayed.'
- );
-
- Y.Assert.areNotEqual(
- -1,
- banner_content.indexOf(features.test_projects.title),
- 'Also test projects since we support multiple features.'
- );
-
- Y.Assert.areEqual(
- -1,
- banner_content.indexOf(features.no_beta.title),
- 'But not no beta since we only support beta features.'
- );
- }
- }));
-
-
- tests.suite.add(new Y.Test.Case({
- name: 'ui.private_banner_tests',
-
- setUp: function () {
- this.container = Y.one('#fixture');
- },
-
- tearDown: function () {
- this.container.empty();
- },
-
- test_base_private_banner: function () {
- // The private banner is auto set to the right type, has the right
- // badge text.
- var badge = '',
- msg = 'page is private',
- b = new ns.PrivateBanner({
- });
-
- b.render(this.container);
- var banner = Y.one('.banner');
- Y.Assert.areEqual(
- badge,
- banner.one('.badge').get('text'),
- 'The badge should be empty'
- );
-
- Y.Assert.areEqual(
- ns.PRIVATE,
- b.get('banner_type'),
- 'The banner should be the right type.'
- );
-
- Y.Assert.areNotEqual(
- -1,
- banner.one('.banner-content').get('text').indexOf(msg),
- 'The badge should have a private warning.'
- );
- }
- }));
-
-}, '0.1', {
- requires: ['test', 'lp.testing.helpers', 'lp.ui.banner']
-});
=== added directory 'lib/lp/app/javascript/views'
=== removed directory 'lib/lp/app/javascript/views'
=== added file 'lib/lp/app/javascript/views/global.js'
--- lib/lp/app/javascript/views/global.js 1970-01-01 00:00:00 +0000
+++ lib/lp/app/javascript/views/global.js 2012-11-12 13:05:28 +0000
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2012 Canonical Ltd. This software is licensed under the
+ * GNU Affero General Public License version 3 (see the file LICENSE).
+ *
+ * Global View handler for Launchpad
+ *
+ * @module lp.views.Global
+ * @namespace lp.views
+ * @module global
+ */
+YUI.add('lp.views.global', function (Y) {
+
+ var ns = Y.namespace('lp.views'),
+ ui = Y.namespace('lp.ui'),
+ info_type = Y.namespace('lp.app.information_type');
+
+ /**
+ * Provides a Y.View that controls all of the things that need handling on
+ * every single request. All code currently in the base-layout-macros
+ * should eventually moved into here to be loaded via the render() method.
+ * Events bound as required, etc.
+ *
+ * @class Global
+ * @extends Y.View
+ */
+ ns.Global = Y.Base.create('lp-views-global', Y.View, [], {
+ _events: [],
+
+ /**
+ * Watch for page level events in all pages.
+ *
+ * @method _bind_events
+ */
+ _bind_events: function () {
+ var that = this;
+
+ // Watch for any changes in information type.
+ this._events.push(Y.on(info_type.EV_ISPUBLIC, function (ev) {
+ // Remove the banner if there is one.
+ if (that._private_banner) {
+ that._private_banner.hide();
+ that._private_banner.destroy(true);
+ that._private_banner = null;
+ // XXX: Bug #1076074
+ var body = Y.one('body');
+ body.addClass('public');
+ }
+ }));
+
+ // If the information type is changed to private, and we don't
+ // currently have a privacy banner, then create a new one and set
+ // it up.
+ this._events.push(Y.on(info_type.EV_ISPRIVATE, function (ev) {
+ // Create a Private banner if there is not currently one.
+ if (!that._private_banner) {
+ that._private_banner = new ui.banner.PrivateBanner({
+ content: ev.text
+ });
+
+ // There is no current container for the banner since
+ // we're creating it on the fly.
+ var container = Y.Node.create('<div>');
+
+ // XXX: Bug #1076074
+ var body = Y.one('body');
+ body.removeClass('public');
+ that._private_banner.render(container);
+ // Only append the content to the DOM after the rest is
+ // one to avoid any repaints on the browser end.
+ body.prepend(container);
+ that._private_banner.show();
+ } else {
+ // The banner is there but we need to update text.
+ that._private_banner.set('content', ev.text);
+ }
+ }));
+ },
+
+ /**
+ * Clean up the view and its event bindings when destroyed.
+ *
+ * @method _destroy
+ * @param {Event} ev
+ * @private
+ */
+ _destroy: function (ev) {
+ var index;
+ for (index in this._events) {
+ event = this._events[index];
+ event.detach();
+ }
+ },
+
+ _init_banners: function () {
+ var that = this;
+
+ // On page load the banner container already exists. This is so
+ // that the height of the page is already determined.
+ var is_beta = Y.one('.beta_banner_container');
+ if (is_beta) {
+ that._beta_banner = new ui.banner.BetaBanner({
+ features: LP.cache.related_features
+ });
+ that._beta_banner.render(is_beta);
+ // We delay the show until the page is ready so we get our
+ // pretty css3 animation that distracts the user a bit.
+ Y.after('load', function (ev) {
+ that._beta_banner.show();
+ });
+ }
+
+ // On page load the banner container already exists. This is so
+ // that the height of the page is already determined.
+ var is_private = Y.one('.private_banner_container');
+ if (is_private) {
+ that._private_banner = new ui.banner.PrivateBanner();
+ that._private_banner.render(is_private);
+ // We delay the show until the page is ready so we get our
+ // pretty css3 animation that distracts the user a bit.
+ Y.on('load', function (ev) {
+ that._private_banner.show();
+ });
+ }
+ },
+
+ initialize: function (cfg) {},
+
+ render: function () {
+ this._bind_events();
+ this.on('destroy', this._destroy, this);
+ this._init_banners();
+ }
+
+ }, {
+ ATTRS: {
+
+ }
+ });
+
+}, '0.1', {
+ requires: ['base', 'view', 'lp.ui.banner', 'lp.app.information_type']
+});
=== removed file 'lib/lp/app/javascript/views/global.js'
--- lib/lp/app/javascript/views/global.js 2012-11-09 18:46:31 +0000
+++ lib/lp/app/javascript/views/global.js 1970-01-01 00:00:00 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd. This software is licensed under the
- * GNU Affero General Public License version 3 (see the file LICENSE).
- *
- * Global View handler for Launchpad
- *
- * @module lp.views.Global
- * @namespace lp.views
- * @module global
- */
-YUI.add('lp.views.global', function (Y) {
-
- var ns = Y.namespace('lp.views'),
- ui = Y.namespace('lp.ui'),
- info_type = Y.namespace('lp.app.information_type');
-
- /**
- * Provides a Y.View that controls all of the things that need handling on
- * every single request. All code currently in the base-layout-macros
- * should eventually moved into here to be loaded via the render() method.
- * Events bound as required, etc.
- *
- * @class Global
- * @extends Y.View
- */
- ns.Global = Y.Base.create('lp-views-global', Y.View, [], {
- _events: [],
-
- /**
- * Watch for page level events in all pages.
- *
- * @method _bind_events
- */
- _bind_events: function () {
- var that = this;
-
- // Watch for any changes in information type.
- this._events.push(Y.on(info_type.EV_ISPUBLIC, function (ev) {
- // Remove the banner if there is one.
- if (that._private_banner) {
- that._private_banner.hide();
- that._private_banner.destroy(true);
- that._private_banner = null;
- // XXX: Bug #1076074
- var body = Y.one('body');
- body.addClass('public');
- }
- }));
-
- // If the information type is changed to private, and we don't
- // currently have a privacy banner, then create a new one and set
- // it up.
- this._events.push(Y.on(info_type.EV_ISPRIVATE, function (ev) {
- // Create a Private banner if there is not currently one.
- if (!that._private_banner) {
- that._private_banner = new ui.banner.PrivateBanner({
- content: ev.text
- });
-
- // There is no current container for the banner since
- // we're creating it on the fly.
- var container = Y.Node.create('<div>');
-
- // XXX: Bug #1076074
- var body = Y.one('body');
- body.removeClass('public');
- that._private_banner.render(container);
- // Only append the content to the DOM after the rest is
- // one to avoid any repaints on the browser end.
- body.prepend(container);
- that._private_banner.show();
- } else {
- // The banner is there but we need to update text.
- that._private_banner.set('content', ev.text);
- }
- }));
- },
-
- /**
- * Clean up the view and its event bindings when destroyed.
- *
- * @method _destroy
- * @param {Event} ev
- * @private
- */
- _destroy: function (ev) {
- var index;
- for (index in this._events) {
- event = this._events[index];
- event.detach();
- }
- },
-
- _init_banners: function () {
- var that = this;
-
- // On page load the banner container already exists. This is so
- // that the height of the page is already determined.
- var is_beta = Y.one('.beta_banner_container');
- if (is_beta) {
- that._beta_banner = new ui.banner.BetaBanner({
- features: LP.cache.related_features
- });
- that._beta_banner.render(is_beta);
- // We delay the show until the page is ready so we get our
- // pretty css3 animation that distracts the user a bit.
- Y.after('load', function (ev) {
- that._beta_banner.show();
- });
- }
-
- // On page load the banner container already exists. This is so
- // that the height of the page is already determined.
- var is_private = Y.one('.private_banner_container');
- if (is_private) {
- that._private_banner = new ui.banner.PrivateBanner();
- that._private_banner.render(is_private);
- // We delay the show until the page is ready so we get our
- // pretty css3 animation that distracts the user a bit.
- Y.on('load', function (ev) {
- that._private_banner.show();
- });
- }
- },
-
- initialize: function (cfg) {},
-
- render: function () {
- this._bind_events();
- this.on('destroy', this._destroy, this);
- this._init_banners();
- }
-
- }, {
- ATTRS: {
-
- }
- });
-
-}, '0.1', {
- requires: ['base', 'view', 'lp.ui.banner', 'lp.app.information_type']
-});
=== added directory 'lib/lp/app/javascript/views/tests'
=== removed directory 'lib/lp/app/javascript/views/tests'
=== added file 'lib/lp/app/javascript/views/tests/test_global.html'
--- lib/lp/app/javascript/views/tests/test_global.html 1970-01-01 00:00:00 +0000
+++ lib/lp/app/javascript/views/tests/test_global.html 2012-11-12 13:05:28 +0000
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+
+<!--
+Copyright 2012 Canonical Ltd. This software is licensed under the
+GNU Affero General Public License version 3 (see the file LICENSE).
+-->
+
+<html>
+ <head>
+ <title>Product New Tests</title>
+
+ <!-- YUI and test setup -->
+ <script type="text/javascript"
+ src="../../../../../../build/js/yui/yui/yui.js">
+ </script>
+ <link rel="stylesheet"
+ href="../../../../../../build/js/yui/console/assets/console-core.css" />
+ <link rel="stylesheet"
+ href="../../../../../../build/js/yui/test-console/assets/skins/sam/test-console.css" />
+ <link rel="stylesheet"
+ href="../../../../../../build/js/yui/test/assets/skins/sam/test.css" />
+
+ <script type="text/javascript"
+ src="../../../../../../build/js/lp/app/testing/testrunner.js"></script>
+
+ <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" />
+
+ <!-- Dependencies -->
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/client.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/choice.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/ellipsis.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/expander.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/errors.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/information_type.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/lp.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/mustache.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/anim/anim.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/extras/extras.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/choiceedit/choiceedit.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/effects/effects.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/formoverlay/formoverlay.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/formwidgets/resizing_textarea.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/inlineedit/editor.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/testing/helpers.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/overlay/overlay.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/ui/ui.js"></script>
+ <script type="text/javascript" src="../../../../../../build/js/lp/app/ui/banner.js"></script>
+
+ <!-- The module under test. -->
+ <script type="text/javascript" src="../global.js"></script>
+
+ <!-- The test suite -->
+ <script type="text/javascript" src="test_global.js"></script>
+
+ </head>
+ <body class="yui3-skin-sam">
+ <ul id="suites">
+ <li>lp.views.global.test</li>
+ </ul>
+ <div id="fixture"></div>
+ </body>
+</html>
=== removed file 'lib/lp/app/javascript/views/tests/test_global.html'
--- lib/lp/app/javascript/views/tests/test_global.html 2012-11-09 18:46:31 +0000
+++ lib/lp/app/javascript/views/tests/test_global.html 1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-<!DOCTYPE html>
-
-<!--
-Copyright 2012 Canonical Ltd. This software is licensed under the
-GNU Affero General Public License version 3 (see the file LICENSE).
--->
-
-<html>
- <head>
- <title>Product New Tests</title>
-
- <!-- YUI and test setup -->
- <script type="text/javascript"
- src="../../../../../../build/js/yui/yui/yui.js">
- </script>
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/console/assets/console-core.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test-console/assets/skins/sam/test-console.css" />
- <link rel="stylesheet"
- href="../../../../../../build/js/yui/test/assets/skins/sam/test.css" />
-
- <script type="text/javascript"
- src="../../../../../../build/js/lp/app/testing/testrunner.js"></script>
-
- <link rel="stylesheet" href="../../../../app/javascript/testing/test.css" />
-
- <!-- Dependencies -->
- <script type="text/javascript" src="../../../../../../build/js/lp/app/client.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/choice.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/ellipsis.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/expander.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/errors.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/information_type.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/lp.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/mustache.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/anim/anim.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/extras/extras.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/choiceedit/choiceedit.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/effects/effects.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/formoverlay/formoverlay.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/formwidgets/resizing_textarea.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/inlineedit/editor.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/testing/helpers.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/overlay/overlay.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/ui/ui.js"></script>
- <script type="text/javascript" src="../../../../../../build/js/lp/app/ui/banner.js"></script>
-
- <!-- The module under test. -->
- <script type="text/javascript" src="../global.js"></script>
-
- <!-- The test suite -->
- <script type="text/javascript" src="test_global.js"></script>
-
- </head>
- <body class="yui3-skin-sam">
- <ul id="suites">
- <li>lp.views.global.test</li>
- </ul>
- <div id="fixture"></div>
- </body>
-</html>
=== added file 'lib/lp/app/javascript/views/tests/test_global.js'
--- lib/lp/app/javascript/views/tests/test_global.js 1970-01-01 00:00:00 +0000
+++ lib/lp/app/javascript/views/tests/test_global.js 2012-11-12 13:05:28 +0000
@@ -0,0 +1,164 @@
+/* Copyright (c) 2012 Canonical Ltd. All rights reserved. */
+
+YUI.add('lp.views.global.test', function (Y) {
+ var tests = Y.namespace('lp.views.global.test');
+ var info_type = Y.namespace('lp.app.information_type');
+ var ns = Y.lp.views;
+
+ tests.suite = new Y.Test.Suite('lp.views.global test');
+ tests.suite.add(new Y.Test.Case({
+ name: 'lp.views.global',
+
+ setUp: function () {
+ this.container = Y.one('#fixture');
+ window.LP = {
+ cache: {
+ related_features: {
+ private_projects: {
+ is_beta: true,
+ title: "Private Projects",
+ url: "http://blog.ld.net/general/private-projects-beta",
+ value: "true"
+ }
+ },
+ information_type_data: {
+ PUBLIC: {
+ value: 'PUBLIC', name: 'Public',
+ is_private: false, order: 1,
+ description: 'Public Description'
+ },
+ EMBARGOED: {
+ value: 'EMBARGOED', name: 'Embargoed',
+ is_private: true, order: 2,
+ description: 'Something embargoed'
+ },
+ PROPRIETARY: {
+ value: 'PROPRIETARY', name: 'Proprietary',
+ is_private: true, order: 3,
+ description: 'Private Description'
+ }
+ }
+ }
+ };
+ },
+
+ tearDown: function () {
+ this.container.empty();
+ },
+
+ test_library_exists: function () {
+ Y.Assert.isObject(ns.Global,
+ "Could not locate the lp.views.global module");
+ },
+
+ test_basic_render: function () {
+ // Nothing is currently rendered out by default.
+ var view = new ns.Global();
+ view.render();
+
+ Y.Assert.areEqual(
+ '',
+ this.container.get('innerHTML'),
+ 'The container is still empty.');
+ view.destroy();
+ },
+
+ test_beta_banner: function () {
+ // If we've prepped on load a beta banner will auto appear.
+ var banner_container = Y.Node.create('<div/>');
+ banner_container.addClass('beta_banner_container');
+ this.container.append(banner_container);
+ var view = new ns.Global();
+ view.render();
+
+ // We have to wait until after page load event fires to test
+ // things out.
+ var banner_node = Y.one('.banner');
+ Y.Assert.isObject(
+ banner_node,
+ 'The container has a new banner node in there.');
+
+ view.destroy();
+ },
+
+ test_privacy: function () {
+ var beta_container = Y.Node.create('<div/>');
+ var private_container = Y.Node.create('<div/>');
+
+ beta_container.addClass('beta_banner_container');
+ private_container.addClass('private_banner_container');
+
+ this.container.append(beta_container);
+ this.container.append(private_container);
+ var view = new ns.Global();
+ view.render();
+
+ // We have to wait until after page load event fires to test
+ // things out.
+ var banner_nodes = Y.all('.banner');
+ Y.Assert.areEqual(
+ 2,
+ banner_nodes._nodes.length,
+ 'We should have two banners rendered.');
+
+ view.destroy();
+ },
+
+ test_privacy_banner_from_event: function () {
+ // We can also get a privacy banner via a fired event.
+ // This is hard coded to the <body> tag so we have to do some
+ // manual clean up here.
+ var view = new ns.Global();
+ view.render();
+
+ var msg = 'Testing Global';
+ Y.fire(info_type.EV_ISPRIVATE, {
+ text: msg
+ });
+
+ var banner = Y.one('.banner');
+ var banner_text = banner.one('.banner-content').get('text');
+ Y.Assert.areNotEqual(
+ -1,
+ banner_text.indexOf(msg),
+ 'The event text is turned into the banner content');
+
+ // Manually clean up.
+ Y.one('.yui3-banner').remove(true);
+ view.destroy();
+ },
+
+ test_banner_updates_content: function () {
+ // If we change our privacy information type the banner needs to
+ // update the content to the new text value from the event.
+ var view = new ns.Global();
+ view.render();
+
+ var msg = 'Testing Global';
+ Y.fire(info_type.EV_ISPRIVATE, {
+ text: msg
+ });
+
+ var updated_msg = 'Updated content'
+ Y.fire(info_type.EV_ISPRIVATE, {
+ text: updated_msg
+ });
+
+ var banner = Y.one('.banner');
+ var banner_text = banner.one('.banner-content').get('text');
+ Y.Assert.areNotEqual(
+ -1,
+ banner_text.indexOf(updated_msg),
+ 'The banner updated content to the second event message.');
+
+ // Manually clean up.
+ Y.one('.yui3-banner').remove(true);
+ view.destroy();
+
+ }
+ }));
+
+}, '0.1', {
+ requires: ['test', 'event-simulate', 'node-event-simulate',
+ 'lp.app.information_type', 'lp.views.global']
+});
=== removed file 'lib/lp/app/javascript/views/tests/test_global.js'
--- lib/lp/app/javascript/views/tests/test_global.js 2012-11-09 18:55:02 +0000
+++ lib/lp/app/javascript/views/tests/test_global.js 1970-01-01 00:00:00 +0000
@@ -1,164 +0,0 @@
-/* Copyright (c) 2012 Canonical Ltd. All rights reserved. */
-
-YUI.add('lp.views.global.test', function (Y) {
- var tests = Y.namespace('lp.views.global.test');
- var info_type = Y.namespace('lp.app.information_type');
- var ns = Y.lp.views;
-
- tests.suite = new Y.Test.Suite('lp.views.global test');
- tests.suite.add(new Y.Test.Case({
- name: 'lp.views.global',
-
- setUp: function () {
- this.container = Y.one('#fixture');
- window.LP = {
- cache: {
- related_features: {
- private_projects: {
- is_beta: true,
- title: "Private Projects",
- url: "http://blog.ld.net/general/beta",
- value: "true"
- }
- },
- information_type_data: {
- PUBLIC: {
- value: 'PUBLIC', name: 'Public',
- is_private: false, order: 1,
- description: 'Public Description'
- },
- EMBARGOED: {
- value: 'EMBARGOED', name: 'Embargoed',
- is_private: true, order: 2,
- description: 'Something embargoed'
- },
- PROPRIETARY: {
- value: 'PROPRIETARY', name: 'Proprietary',
- is_private: true, order: 3,
- description: 'Private Description'
- }
- }
- }
- };
- },
-
- tearDown: function () {
- this.container.empty();
- },
-
- test_library_exists: function () {
- Y.Assert.isObject(ns.Global,
- "Could not locate the lp.views.global module");
- },
-
- test_basic_render: function () {
- // Nothing is currently rendered out by default.
- var view = new ns.Global();
- view.render();
-
- Y.Assert.areEqual(
- '',
- this.container.get('innerHTML'),
- 'The container is still empty.');
- view.destroy();
- },
-
- test_beta_banner: function () {
- // If we've prepped on load a beta banner will auto appear.
- var banner_container = Y.Node.create('<div/>');
- banner_container.addClass('beta_banner_container');
- this.container.append(banner_container);
- var view = new ns.Global();
- view.render();
-
- // We have to wait until after page load event fires to test
- // things out.
- var banner_node = Y.one('.banner');
- Y.Assert.isObject(
- banner_node,
- 'The container has a new banner node in there.');
-
- view.destroy();
- },
-
- test_privacy: function () {
- var beta_container = Y.Node.create('<div/>');
- var private_container = Y.Node.create('<div/>');
-
- beta_container.addClass('beta_banner_container');
- private_container.addClass('private_banner_container');
-
- this.container.append(beta_container);
- this.container.append(private_container);
- var view = new ns.Global();
- view.render();
-
- // We have to wait until after page load event fires to test
- // things out.
- var banner_nodes = Y.all('.banner');
- Y.Assert.areEqual(
- 2,
- banner_nodes._nodes.length,
- 'We should have two banners rendered.');
-
- view.destroy();
- },
-
- test_privacy_banner_from_event: function () {
- // We can also get a privacy banner via a fired event.
- // This is hard coded to the <body> tag so we have to do some
- // manual clean up here.
- var view = new ns.Global();
- view.render();
-
- var msg = 'Testing Global';
- Y.fire(info_type.EV_ISPRIVATE, {
- text: msg
- });
-
- var banner = Y.one('.banner');
- var banner_text = banner.one('.banner-content').get('text');
- Y.Assert.areNotEqual(
- -1,
- banner_text.indexOf(msg),
- 'The event text is turned into the banner content');
-
- // Manually clean up.
- Y.one('.yui3-banner').remove(true);
- view.destroy();
- },
-
- test_banner_updates_content: function () {
- // If we change our privacy information type the banner needs to
- // update the content to the new text value from the event.
- var view = new ns.Global();
- view.render();
-
- var msg = 'Testing Global';
- Y.fire(info_type.EV_ISPRIVATE, {
- text: msg
- });
-
- var updated_msg = 'Updated content';
- Y.fire(info_type.EV_ISPRIVATE, {
- text: updated_msg
- });
-
- var banner = Y.one('.banner');
- var banner_text = banner.one('.banner-content').get('text');
- Y.Assert.areNotEqual(
- -1,
- banner_text.indexOf(updated_msg),
- 'The banner updated content to the second event message.');
-
- // Manually clean up.
- Y.one('.yui3-banner').remove(true);
- view.destroy();
-
- }
- }));
-
-}, '0.1', {
- requires: ['test', 'event-simulate', 'node-event-simulate',
- 'lp.app.information_type', 'lp.views.global']
-});
=== modified file 'lib/lp/app/templates/base-layout-macros.pt'
--- lib/lp/app/templates/base-layout-macros.pt 2012-08-13 17:49:31 +0000
+++ lib/lp/app/templates/base-layout-macros.pt 2012-11-12 13:05:28 +0000
@@ -163,19 +163,17 @@
<script id="base-layout-load-scripts" type="text/javascript">
//<![CDATA[
LPJS.use('base', 'node', 'console', 'event',
- 'oop', 'lp', 'lp.app.banner.privacy',
- 'lp.app.banner.beta', 'lp.app.foldables','lp.app.sorttable',
+ 'oop', 'lp', 'lp.app.foldables','lp.app.sorttable',
'lp.app.inlinehelp', 'lp.app.links', 'lp.app.longpoll',
'lp.bugs.bugtask_index', 'lp.bugs.subscribers',
'lp.app.ellipsis', 'lp.code.branchmergeproposal.diff',
+ 'lp.views.global',
function(Y) {
Y.on("domready", function () {
- if (Y.one(document.body).hasClass('private')) {
- banner = Y.lp.app.banner.privacy.getPrivacyBanner();
- banner.show();
- }
- Y.lp.app.banner.beta.show_beta_if_needed();
+ var global_view = new Y.lp.views.Global();
+ global_view.render();
+
Y.lp.app.sorttable.SortTable.init();
Y.lp.app.inlinehelp.init_help();
Y.lp.activate_collapsibles();
=== modified file 'lib/lp/app/templates/base-layout.pt'
--- lib/lp/app/templates/base-layout.pt 2012-05-18 22:04:13 +0000
+++ lib/lp/app/templates/base-layout.pt 2012-11-12 13:05:28 +0000
@@ -64,6 +64,12 @@
${view/macro:pagetype}
${view/fmt:global-css}
yui3-skin-sam">
+ <tal:beta-banner condition="view/beta_features">
+ <div class="beta_banner_container"></div>
+ </tal:beta-banner>
+ <tal:private-banner condition="view/private">
+ <div class="private_banner_container"></div>
+ </tal:private-banner>
<script type="text/javascript"
tal:condition="python: is_lpnet">
var _gaq = _gaq || [];
@@ -97,10 +103,8 @@
<div class="yui-t4"
tal:omit-tag="not: view/macro:pagehas/portlets">
<div id="maincontent" class="yui-main">
- <metal:privacy-banner
- use-macro="view/@@+banner-macros/beta-banner"/>
- <metal:privacy-banner
- use-macro="view/@@+banner-macros/privacy-banner"/>
+ <!-- <metal:privacy-banner -->
+ <!-- use-macro="view/@@+banner-macros/privacy-banner"/> -->
<div class="yui-b"
tal:attributes="
lang view/lang|default_language|default;
=== modified file 'lib/lp/blueprints/javascript/addspec.js'
--- lib/lp/blueprints/javascript/addspec.js 2012-10-15 16:01:38 +0000
+++ lib/lp/blueprints/javascript/addspec.js 2012-11-12 13:05:28 +0000
@@ -10,11 +10,24 @@
var namespace = Y.namespace('lp.blueprints.addspec');
var to_choice = Y.lp.app.information_type.cache_to_choicesource;
+var info_type = Y.lp.app.information_type;
namespace.set_up = function () {
var choice_data = to_choice(LP.cache.information_type_data);
- Y.lp.app.choice.addPopupChoiceForRadioButtons('information_type',
- choice_data);
+ var widget = Y.lp.app.choice.addPopupChoiceForRadioButtons(
+ 'information_type',
+ choice_data);
+
+ // We are not doing ajax saves of the information type so we need to
+ // disable the flash on save for the widget.
+ widget.set('flashEnabled', false);
+
+ // Make sure we catch changes to the information type.
+ widget.on('save', function (ev) {
+ Y.fire(info_type.EV_CHANGE, {
+ value: ev.target.get('value')
+ });
+ });
};
}, "0.1", {"requires": ['lp.app.information_type', 'lp.app.choice']});
=== modified file 'lib/lp/bugs/javascript/bugtask_index.js'
--- lib/lp/bugs/javascript/bugtask_index.js 2012-10-11 04:57:59 +0000
+++ lib/lp/bugs/javascript/bugtask_index.js 2012-11-12 13:05:28 +0000
@@ -1131,6 +1131,5 @@
"lp.app.information_type",
"lp.app.widgets.expander", "lp.client", "escape",
"lp.client.plugins", "lp.app.errors",
- "lp.app.banner.privacy",
"lp.app.confirmationoverlay",
"lp.bugs.duplicates"]});
=== modified file 'lib/lp/bugs/javascript/filebug.js'
--- lib/lp/bugs/javascript/filebug.js 2012-09-25 19:15:04 +0000
+++ lib/lp/bugs/javascript/filebug.js 2012-11-12 13:05:28 +0000
@@ -9,6 +9,7 @@
YUI.add('lp.bugs.filebug', function(Y) {
var namespace = Y.namespace('lp.bugs.filebug');
+var info_type = Y.lp.app.information_type;
// For tests.
var skip_animation;
@@ -28,13 +29,40 @@
if (Y.Lang.isValue(search_button )) {
search_button.set('value', 'Check again');
}
+ setup_plain_inputs();
set_default_privacy_banner();
- setup_information_type();
setup_security_related();
setupChoiceWidgets();
}
};
+
+/**
+ * If there are not choice widgets, but radio buttons, then we should watch
+ * those radio buttons for change to make sure we fire the information type
+ * change events.
+ */
+var setup_plain_inputs = function () {
+ var itypes_table = Y.one('.radio-button-widget');
+
+ if (itypes_table) {
+ itypes_table.delegate('change', function(ev) {
+ Y.fire(info_type.EV_CHANGE, {
+ value: this.get('value')
+ });
+ }, "input[name='field.information_type']");
+ }
+};
+
+/**
+ * Due to the privacy setting of the project/bugs we might only allow a
+ * non-public information type. In this case we need to go ahead and let the
+ * user know it's going to be private.
+ *
+ * This is used by the security checks. If the issue is unmade/not security
+ * related then we need to check the normal default behavior to make sure we
+ * show the correct banner.
+ */
var set_default_privacy_banner = function() {
var itypes_table = Y.one('.radio-button-widget');
var val = null;
@@ -48,47 +76,12 @@
if (LP.cache.bug_private_by_default) {
var filebug_privacy_text = "This report will be private. " +
"You can disclose it later.";
- update_privacy_banner(true, filebug_privacy_text);
- } else {
- update_banner_from_information_type(val);
- }
-};
-
-var update_privacy_banner = function(show, banner_text) {
- var banner = Y.lp.app.banner.privacy.getPrivacyBanner(
- banner_text, skip_animation);
- if (show) {
- banner.show();
- } else {
- banner.hide();
- }
-};
-
-var get_new_banner_text = function(value) {
- var cache = LP.cache.information_type_data;
- var text_template = "This report contains {info_type} information." +
- " You can change the information type later.";
- return Y.Lang.substitute(text_template, {
- 'info_type': cache[value].name
- });
-};
-
-var update_banner_from_information_type = function(value) {
- var banner_text = get_new_banner_text(value);
- var is_private = LP.cache.information_type_data[value].is_private;
- update_privacy_banner(is_private, banner_text);
-};
-
-var setup_information_type = function() {
- var itypes_table = Y.one('.radio-button-widget');
- if (!Y.Lang.isValue(itypes_table)) {
- return;
- }
-
-
- itypes_table.delegate('change', function() {
- update_banner_from_information_type(this.get('value'));
- }, "input[name='field.information_type']");
+
+ Y.fire(info_type.EV_ISPRIVATE, {
+ text: filebug_privacy_text,
+ value: val
+ });
+ }
};
@@ -100,8 +93,25 @@
var information_helpers = Y.lp.app.information_type;
var choices = information_helpers.cache_to_choicesource(cache);
- Y.lp.app.choice.addPopupChoiceForRadioButtons(
+ var information_type = Y.lp.app.choice.addPopupChoiceForRadioButtons(
'information_type', choices, true);
+
+ // When dealing with legacy inputs the information type could have not
+ // been created and we get back a null value.
+ if (information_type) {
+ // We are not doing ajax saves of the information type so we need to
+ // disable the flash on save for the widget.
+ information_type.set('flashEnabled', false);
+
+ // When the information type widget changes we need to let the information
+ // type module know so it can process the change and update things
+ // like banners displayed.
+ information_type.on('save', function (ev) {
+ Y.fire(info_type.EV_CHANGE, {
+ value: ev.target.get('value')
+ });
+ });
+ }
};
var setup_security_related = function() {
@@ -116,8 +126,19 @@
security_related.on('change', function() {
var checked = security_related.get('checked');
if (checked) {
- update_privacy_banner(true, notification_text);
+ // XXX: This should use the correct information type based on the
+ // project default. We use PRIVATESECURITY because it'll get the
+ // right banner shown.
+ Y.fire(info_type.EV_ISPRIVATE, {
+ text: notification_text,
+ value: 'PRIVATESECURITY'
+ });
} else {
+ Y.fire(info_type.EV_ISPUBLIC, {
+ value: 'PUBLIC'
+ });
+ // Check with the default settings if we should add the privacy
+ // banner back because it's the default of the current project.
set_default_privacy_banner();
}
});
@@ -127,5 +148,5 @@
}, "0.1", {"requires": [
"base", "node", "event", "node-event-delegate", "lp.ui.choiceedit",
- "lp.app.banner.privacy", "lp.app.choice", "lp.app.information_type",
+ "lp.ui.banner", "lp.app.choice", "lp.app.information_type",
"lp.bugs.filebug_dupefinder"]});
=== modified file 'lib/lp/bugs/javascript/tests/test_filebug.js'
--- lib/lp/bugs/javascript/tests/test_filebug.js 2012-10-26 10:00:20 +0000
+++ lib/lp/bugs/javascript/tests/test_filebug.js 2012-11-12 13:05:28 +0000
@@ -3,6 +3,8 @@
YUI.add('lp.bugs.filebug.test', function (Y) {
var tests = Y.namespace('lp.bugs.filebug.test');
+ var info_type = Y.lp.app.information_type;
+
tests.suite = new Y.Test.Suite(
'lp.bugs.filebug Tests');
@@ -73,96 +75,136 @@
// Filing a public bug does not show the privacy banner.
test_setup_filebug_public: function () {
+ // Watch out for the event that showing a privacy banner would
+ // fire.
+ var fired = false;
+ var ev = Y.on(info_type.EV_ISPRIVATE, function (ev) {
+ fired = true;
+ });
this.setupForm(true);
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNotNull(banner_hidden);
+ Y.Assert.isFalse(fired);
+ ev.detach();
},
// Filing a bug for a project with private bugs shows the privacy
// banner.
test_setup_filebug_private: function () {
+ var fired = false;
+ var ev = Y.on(info_type.EV_ISPRIVATE, function (ev) {
+ fired = true;
+ Y.Assert.areEqual(
+ 'This report will be private. ' +
+ 'You can disclose it later.', ev.text);
+ });
+
window.LP.cache.bug_private_by_default = true;
this.setupForm(true);
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
- var banner_text = Y.one('.banner-text').get('text');
- Y.Assert.areEqual(
- 'This report will be private. ' +
- 'You can disclose it later.', banner_text);
+ Y.Assert.isTrue(fired);
+ ev.detach();
},
// Selecting a private info type using the legacy radio buttons
// turns on the privacy banner.
test_legacy_select_private_info_type: function () {
+ var fired = false;
+ var ev = Y.on(info_type.EV_ISPRIVATE, function (ev) {
+ fired = true;
+ Y.Assert.areEqual(
+ 'This report will be private because it is a security ' +
+ 'vulnerability. You can disclose it later.', ev.text);
+ });
+
this.setupForm(true);
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNotNull(banner_hidden);
+ Y.Assert.isFalse(fired);
+
Y.one('[id="field.information_type.2"]').simulate('click');
- banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
- var banner_text = Y.one('.banner-text').get('text');
- Y.Assert.areEqual(
- 'This report contains Private Security information. ' +
- 'You can change the information type later.', banner_text);
+ // And the event should be fired and caught.
+ Y.Assert.isTrue(fired);
+ ev.detach();
},
// Selecting a public info type using the legacy radio buttons
// turns off the privacy banner.
test_legacy_select_public_info_type: function () {
+ var fired = false;
+ var ev = Y.on(info_type.EV_ISPUBLIC, function (ev) {
+ fired = true;
+ });
+
window.LP.cache.bug_private_by_default = true;
this.setupForm(true);
+
+ // This will fire ISPRIVATE and a banner shows.
Y.one('[id="field.information_type.2"]').simulate('click');
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
+
+ // The second one will fire ISPUBLIC and the banner disappears.
Y.one('[id="field.information_type.0"]').simulate('click');
- banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNotNull(banner_hidden);
+ Y.Assert.isTrue(fired);
},
// When non bug supervisors select a security related bug the privacy
// banner is turned on.
test_select_security_related: function () {
+ var fired = false;
+ var ev = Y.on(info_type.EV_ISPRIVATE, function (ev) {
+ fired = true;
+ Y.Assert.areEqual(
+ 'This report will be private because it is a security ' +
+ 'vulnerability. You can disclose it later.', ev.text);
+ });
+
this.setupForm(false);
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNotNull(banner_hidden);
+ Y.Assert.isFalse(fired);
+
Y.one('[id="field.security_related"]').simulate('click');
- banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
- var banner_text = Y.one('.banner-text').get('text');
- Y.Assert.areEqual(
- 'This report will be private because it is a ' +
- 'security vulnerability. You can disclose it later.',
- banner_text);
+ // And the event should be fired and caught.
+ Y.Assert.isTrue(fired);
+ ev.detach();
},
// When non bug supervisors unselect a security related bug the privacy
// banner is turned off.
test_unselect_security_related: function () {
+ var fired = false;
+ var ev = Y.on(info_type.EV_ISPUBLIC, function (ev) {
+ fired = true;
+ });
+
this.setupForm(false);
- Y.one('[id="field.security_related"]').simulate('click');
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
- Y.one('[id="field.security_related"]').simulate('click');
- banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNotNull(banner_hidden);
+
+ Y.one('[id="field.security_related"]').simulate('click');
+ Y.Assert.isFalse(fired);
+
+ Y.one('[id="field.security_related"]').simulate('click');
+ Y.Assert.isTrue(fired);
},
// When non bug supervisors unselect a security related bug the privacy
// banner remains on for private_by_default bugs.
test_unselect_security_related_default_private: function () {
window.LP.cache.bug_private_by_default = true;
+ var public = 0;
+ var private = 0;
+ var ev = Y.on(info_type.EV_ISPUBLIC, function (ev) {
+ public = public + 1;
+ });
+
+ var ev = Y.on(info_type.EV_ISPRIVATE, function (ev) {
+ private = private + 1;
+ });
+
+
this.setupForm(false);
- Y.one('[id="field.security_related"]').simulate('click');
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
- Y.one('[id="field.security_related"]').simulate('click');
- banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
- var banner_text = Y.one('.banner-text').get('text');
+ Y.Assert.areEqual(1, private, 'Private is the default state.');
+
+ Y.one('[id="field.security_related"]').simulate('click');
+ Y.Assert.areEqual(2, private, 'The first click fires ISPRIVATE');
+
+ Y.one('[id="field.security_related"]').simulate('click');
+ Y.Assert.areEqual(1, public, 'The second click fires ISPUBLIC');
Y.Assert.areEqual(
- 'This report will be private. ' +
- 'You can disclose it later.',
- banner_text);
+ 3, private,
+ "It also fires an ISPRIVATE since that's the default state.");
},
// The dupe finder functionality is setup.
@@ -280,44 +322,59 @@
// Selecting a private info type using the popup choice widget
// turns on the privacy banner.
test_select_private_info_type: function () {
+ var fired = false;
+ var ev = Y.on(info_type.EV_ISPRIVATE, function (ev) {
+ fired = true;
+ Y.Assert.areEqual(
+ 'This report contains Private information. ' +
+ 'You can change the information type later.', ev.text);
+ });
+
this.setupForm(true);
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNotNull(banner_hidden);
+ Y.Assert.isFalse(fired);
+
var information_type_popup = Y.one('.information_type-content a');
information_type_popup.simulate('click');
var information_type_choice = Y.one(
'.yui3-ichoicelist-content a[href="#USERDATA"]');
information_type_choice.simulate('click');
- banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
- var banner_text = Y.one('.banner-text').get('text');
- Y.Assert.areEqual(
- 'This report contains Private information. ' +
- 'You can change the information type later.', banner_text);
+
+ // And the event should be fired and caught.
+ Y.Assert.isTrue(fired);
+ ev.detach();
},
// Selecting a public info type using the popup choice widget
// turns off the privacy banner.
test_select_public_info_type: function () {
+ var fired = false;
+ var ev = Y.on(info_type.EV_ISPUBLIC, function (ev) {
+ fired = true;
+ });
+
window.LP.cache.bug_private_by_default = true;
this.setupForm(true);
+
+ // This will fire ISPRIVATE and a banner shows.
var information_type_popup = Y.one('.information_type-content a');
information_type_popup.simulate('click');
var information_type_choice = Y.one(
'.yui3-ichoicelist-content a[href="#USERDATA"]');
information_type_choice.simulate('click');
- var banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNull(banner_hidden);
+
+ // The second one will fire ISPUBLIC and the banner disappears.
information_type_popup.simulate('click');
information_type_choice = Y.one(
'.yui3-ichoicelist-content a[href="#PUBLIC"]');
information_type_choice.simulate('click');
- banner_hidden = Y.one('.yui3-privacybanner-hidden');
- Y.Assert.isNotNull(banner_hidden);
+
+ Y.Assert.isTrue(fired);
}
}));
-}, '0.1', {'requires': ['test', 'test-console', 'event', 'node-event-simulate',
- 'lp.app.banner.privacy', 'lp.app.choice',
- 'lp.bugs.filebug_dupefinder', 'lp.bugs.filebug'
- ]});
+}, '0.1', {
+ requires: [
+ 'test', 'test-console', 'event', 'node-event-simulate',
+ 'lp.app.banner.privacy', 'lp.app.choice', 'lp.app.information_type',
+ 'lp.bugs.filebug_dupefinder', 'lp.bugs.filebug' ]
+});
=== modified file 'lib/lp/code/javascript/branch.information_type_choice.js'
--- lib/lp/code/javascript/branch.information_type_choice.js 2012-09-21 15:39:22 +0000
+++ lib/lp/code/javascript/branch.information_type_choice.js 2012-11-12 13:05:28 +0000
@@ -105,7 +105,9 @@
LP.cache.context.information_type =
information_type.get_cache_data_from_key(
value, 'value', 'name');
- information_type.update_privacy_banner(value);
+ Y.fire(information_type.EV_CHANGE, {
+ value: value
+ });
if (this.get('use_animation')) {
this.information_type_edit._showSucceeded();
}
@@ -119,7 +121,8 @@
}
});
-}, "0.1", {"requires": ["base", "oop", "node", "event", "io-base",
- "lp.ui.choiceedit", "lp.app.banner.privacy",
- "lp.app.errors", "lp.app.choice",
- "lp.app.information_type"]});
+}, "0.1", {
+ requires: [
+ "base", "oop", "node", "event", "io-base", "lp.ui.choiceedit",
+ "lp.app.errors", "lp.app.choice", "lp.app.information_type"]
+});
=== modified file 'lib/lp/code/javascript/tests/test_information_type_choice.js'
--- lib/lp/code/javascript/tests/test_information_type_choice.js 2012-10-26 10:00:20 +0000
+++ lib/lp/code/javascript/tests/test_information_type_choice.js 2012-11-12 13:05:28 +0000
@@ -4,6 +4,8 @@
var tests = Y.namespace('lp.code.branch.information_type_choice.test');
var ns = Y.lp.code.branch.information_type_choice;
+ var info_type = Y.lp.app.information_type;
+
tests.suite = new Y.Test.Suite(
'lp.code.branch.information_type_choice Tests');
@@ -62,22 +64,6 @@
this.widget.render();
},
- _shim_privacy_banner: function () {
- var old_func = Y.lp.app.banner.privacy.getPrivacyBanner;
- Y.lp.app.banner.privacy.getPrivacyBanner = function () {
- return {
- show: function () { Y.fire('test:banner:show'); },
- hide: function () { Y.fire('test:banner:hide'); },
- updateText: function () { Y.fire('test:banner:update'); }
- };
- };
- return old_func;
- },
-
- _unshim_privacy_banner: function (old_func) {
- Y.lp.app.banner.privacy.getPrivacyBanner = old_func;
- },
-
test_library_exists: function () {
Y.Assert.isObject(Y.lp.code.branch.information_type_choice,
"Cannot locate the " +
@@ -118,44 +104,31 @@
// Setting a private type shows the privacy banner.
test_information_type_save_success_private: function() {
+ var fired = false;
+ Y.on(info_type.EV_ISPRIVATE, function (ev) {
+ fired = true;
+ });
+
this.makeWidget();
- var old_func = this._shim_privacy_banner();
- var hide_flag = false;
- var update_flag = false;
- Y.on('test:banner:show', function() {
- hide_flag = true;
- });
- Y.on('test:banner:update', function() {
- update_flag = true;
- });
this.widget._information_type_save_success('PROPRIETARY');
- var body = Y.one('body');
- Y.Assert.isTrue(body.hasClass('private'));
- Y.Assert.isTrue(hide_flag);
- Y.Assert.isTrue(update_flag);
+ Y.Assert.isTrue(fired);
Y.Assert.areEqual(
'Proprietary', LP.cache.context.information_type);
- this._unshim_privacy_banner(old_func);
},
// Setting a private type hides the privacy banner.
test_information_type_save_success_public: function() {
+ var fired = false;
+ Y.on(info_type.EV_ISPUBLIC, function (ev) {
+ fired = true;
+ });
+
this.makeWidget();
- var old_func = this._shim_privacy_banner();
- var flag = false;
- Y.on('test:banner:hide', function() {
- flag = true;
- });
- var summary = Y.one('#information-type-summary');
- summary.replaceClass('public', 'private');
this.widget._information_type_save_success('PUBLIC');
- var body = Y.one('body');
- Y.Assert.isTrue(body.hasClass('public'));
- Y.Assert.isTrue(flag);
+ Y.Assert.isTrue(fired);
Y.Assert.areEqual('Public', LP.cache.context.information_type);
- this._unshim_privacy_banner(old_func);
},
// Test error handling when a save fails.
=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py 2012-10-26 15:11:20 +0000
+++ lib/lp/registry/browser/product.py 2012-11-12 13:05:28 +0000
@@ -1905,6 +1905,7 @@
class ProjectAddStepTwo(StepView, ProductLicenseMixin, ReturnToReferrerMixin):
"""Step 2 (of 2) in the +new project add wizard."""
+ related_features = [PRIVATE_PROJECTS_FLAG]
_field_names = ['displayname', 'name', 'title', 'summary', 'description',
'homepageurl', 'information_type', 'licenses',
=== modified file 'lib/lp/registry/javascript/product_views.js'
--- lib/lp/registry/javascript/product_views.js 2012-10-26 06:59:14 +0000
+++ lib/lp/registry/javascript/product_views.js 2012-11-12 13:05:28 +0000
@@ -95,6 +95,9 @@
*/
information_type_change: function (value) {
toggle_license_field(value);
+ Y.fire(info_type.EV_CHANGE, {
+ value: value
+ });
},
/**
@@ -349,6 +352,9 @@
*/
information_type_change: function (value) {
toggle_license_field(value);
+ Y.fire(info_type.EV_CHANGE, {
+ value: value
+ });
var driver_cont =
Y.one('input[name="field.driver"]').ancestor('td');
var bug_super_cont =
=== modified file 'lib/lp/services/features/flags.py'
--- lib/lp/services/features/flags.py 2012-11-08 06:06:22 +0000
+++ lib/lp/services/features/flags.py 2012-11-12 13:05:28 +0000
@@ -236,7 +236,7 @@
'boolean',
'If true, enabled access to private project registration features.',
'disabled',
- '',
+ 'Allow registering a non-public project.',
'http://blog.launchpad.net/general/private-projects-beta'),
('disclosure.private_project.traversal_override',
'boolean',