You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by he...@apache.org on 2015/07/22 17:48:28 UTC

[01/11] allura git commit: [#7685] ticket:802 Subsribe via POST in wiki sidebar

Repository: allura
Updated Branches:
  refs/heads/master e1ad48033 -> 6d0eb69a3


[#7685] ticket:802 Subsribe via POST in wiki sidebar


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/c5f8bdad
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/c5f8bdad
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/c5f8bdad

Branch: refs/heads/master
Commit: c5f8bdad548216d2579bc05261e70b3fd63abfd4
Parents: cc33817
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jun 25 14:24:05 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Wed Jul 22 15:35:25 2015 +0300

----------------------------------------------------------------------
 ForgeWiki/forgewiki/templates/wiki/page_view.html | 10 +++++++++-
 ForgeWiki/forgewiki/wiki_main.py                  |  2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c5f8bdad/ForgeWiki/forgewiki/templates/wiki/page_view.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_view.html b/ForgeWiki/forgewiki/templates/wiki/page_view.html
index 0420ecf..7289f23 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_view.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_view.html
@@ -116,5 +116,13 @@
       {% endif %}
   {% endif %}
   {{c.confirmation.display(content='')}}
-
 {% endblock %}
+
+{% block wiki_extra_js %}
+  <script type="text/javascript">
+    $('a[href$="#toggle-subscribe"]').click(function() {
+      $('#subscribe_form').submit();
+      return false;
+    })
+  </script>
+{% endblock wiki_extra_js %}

http://git-wip-us.apache.org/repos/asf/allura/blob/c5f8bdad/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 7899ffa..229b217 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -249,7 +249,7 @@ The wiki uses [Markdown](%s) syntax.
             subscribe_title = '{}{}'.format(
                 subscribe_action.capitalize(),
                 '' if subscribed else ' to wiki')
-            subscribe_url = '{}subscribe?{}=True'.format(self.url, subscribe_action)
+            subscribe_url = '{}#toggle-subscribe'.format(self.url, subscribe_action)
             links += [SitemapEntry(''),
                       SitemapEntry(subscribe_title, subscribe_url, ui_icon=g.icons['mail'])]
         if not admin_menu:


[05/11] allura git commit: [#7685] ticket:802 Fixed subscription to whole wiki

Posted by he...@apache.org.
[#7685] ticket:802 Fixed subscription to whole wiki


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/e2cd5f60
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/e2cd5f60
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/e2cd5f60

Branch: refs/heads/master
Commit: e2cd5f60a02c3780cdf66228a22380d01724b7e5
Parents: 4b76e4c
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jul 2 16:26:09 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:57 2015 -0400

----------------------------------------------------------------------
 ForgeWiki/forgewiki/templates/wiki/page_view.html | 12 +++++++++++-
 ForgeWiki/forgewiki/wiki_main.py                  |  4 +++-
 2 files changed, 14 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e2cd5f60/ForgeWiki/forgewiki/templates/wiki/page_view.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_view.html b/ForgeWiki/forgewiki/templates/wiki/page_view.html
index 7289f23..7a6135e 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_view.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_view.html
@@ -116,12 +116,22 @@
       {% endif %}
   {% endif %}
   {{c.confirmation.display(content='')}}
+  {% if not c.user.is_anonymous() %}
+    <form action="{{c.app.url}}subscribe" id="wiki_subscribe_form" style="display:none;" method="POST">
+      {{lib.csrf_token()}}
+      {% if c.subscribed %}
+        <input type="hidden" name="unsubscribe" value="1">
+      {% else %}
+        <input type="hidden" name="subscribe" value="1">
+      {% endif %}
+    </form>
+  {% endif %}
 {% endblock %}
 
 {% block wiki_extra_js %}
   <script type="text/javascript">
     $('a[href$="#toggle-subscribe"]').click(function() {
-      $('#subscribe_form').submit();
+      $('#wiki_subscribe_form').submit();
       return false;
     })
   </script>

http://git-wip-us.apache.org/repos/asf/allura/blob/e2cd5f60/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 229b217..c2bcb16 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -249,7 +249,7 @@ The wiki uses [Markdown](%s) syntax.
             subscribe_title = '{}{}'.format(
                 subscribe_action.capitalize(),
                 '' if subscribed else ' to wiki')
-            subscribe_url = '{}#toggle-subscribe'.format(self.url, subscribe_action)
+            subscribe_url = '#toggle-subscribe'.format(self.url)
             links += [SitemapEntry(''),
                       SitemapEntry(subscribe_title, subscribe_url, ui_icon=g.icons['mail'])]
         if not admin_menu:
@@ -483,6 +483,8 @@ class PageController(BaseController, FeedController):
         if self.page is not None:
             self.attachment = WikiAttachmentsController(self.page)
         c.create_page_lightbox = W.create_page_lightbox
+        if not c.user.is_anonymous():
+            c.subscribed = M.Mailbox.subscribed()
 
     def _check_security(self):
         if self.page:


[08/11] allura git commit: [#7685] ticket:819 Use ajax requests in subscription icons

Posted by he...@apache.org.
[#7685] ticket:819 Use ajax requests in subscription icons


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/a5227e2e
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/a5227e2e
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/a5227e2e

Branch: refs/heads/master
Commit: a5227e2e1f75ca831a39aa468582e41943004002
Parents: 63dbb3d
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 10 18:03:02 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:57 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py         |  7 +-
 .../lib/widgets/resources/js/subscriptions.js   | 99 ++++++++++++++++++++
 Allura/allura/lib/widgets/subscriptions.py      |  7 +-
 Allura/allura/templates/widgets/subscribe.html  | 44 ++++-----
 ForgeBlog/forgeblog/main.py                     | 11 ++-
 .../forgediscussion/controllers/forum.py        |  7 +-
 ForgeTracker/forgetracker/tracker_main.py       | 14 ++-
 ForgeWiki/forgewiki/wiki_main.py                |  7 +-
 8 files changed, 158 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/a5227e2e/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 0178723..2b9ae89 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -688,7 +688,7 @@ class TreeBrowser(BaseController, DispatchIndex):
             self._path + '/' + next,
             self), rest
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -696,7 +696,10 @@ class TreeBrowser(BaseController, DispatchIndex):
             M.Mailbox.subscribe()
         elif unsubscribe:
             M.Mailbox.unsubscribe()
-        redirect(request.referer)
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(),
+        }
 
 
 class FileBrowser(BaseController):

http://git-wip-us.apache.org/repos/asf/allura/blob/a5227e2e/Allura/allura/lib/widgets/resources/js/subscriptions.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/subscriptions.js b/Allura/allura/lib/widgets/resources/js/subscriptions.js
new file mode 100644
index 0000000..c03bbeb
--- /dev/null
+++ b/Allura/allura/lib/widgets/resources/js/subscriptions.js
@@ -0,0 +1,99 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var dom = React.createElement;
+
+/* top-level form state */
+var state = {
+  'thing': 'tool',
+  'subscribed': false,
+  'url': '',
+  'icon': {}
+};
+
+SubscriptionForm = React.createClass({
+
+  render: function() {
+    var action = this.props.subscribed ? "Unsubscribe from" : "Subscribe to";
+    var title = action + ' this ' + this.props.thing;
+    var link_opts = {
+      className: this.props.subscribed ? 'active' : '',
+      href: '#',
+      title: title,
+      onClick: this.handleClick
+    };
+    var icon_opts = {
+      'data-icon': this.props.icon.char,
+      className: 'ico ' + this.props.icon.css,
+      title: title
+    };
+    return dom('a', link_opts, dom('b', icon_opts));
+  },
+
+  handleClick: function() {
+    var url = this.props.url;
+    var csrf = $.cookie('_session_id');
+    var data = {_session_id: csrf};
+    if (this.props.subscribed) {
+      data.unsubscribe = true;
+    } else {
+      data.subscribe = true;
+    }
+    set_state({in_progress: true});
+    /*
+     * TODO:
+     * - show 'in-progress' status to user somehow
+     * - handle errors (show to the user in some kind of popup/flash?)
+     * - If user is subscribed to the whole tool and she tries to subsribe to
+     *   the artifact she will not be subscribed, so nothing will change in the
+     *   UI and it's confusing. We need to show some information message in
+     *   such case
+     */
+    $.post(url, data, function(resp) {
+      if (resp.status == 'ok') {
+        set_state({subscribed: resp.subscribed});
+      }
+    }).always(function() {
+      set_state({in_progress: false});
+    });
+    return false;
+  }
+
+});
+
+function set_state(new_state) {
+  /* Set state and re-render entire UI */
+  for (var key in new_state) {
+    state[key] = new_state[key];
+  }
+  render(state);
+}
+
+function render(state) {
+  var props = {};
+  for (var key in state) { props[key] = state[key]; }
+  React.render(
+    dom(SubscriptionForm, props),
+    document.getElementById('subscription-form')
+  );
+}
+
+$(function() {
+  set_state(document.SUBSCRIPTION_OPTIONS);
+});

http://git-wip-us.apache.org/repos/asf/allura/blob/a5227e2e/Allura/allura/lib/widgets/subscriptions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/subscriptions.py b/Allura/allura/lib/widgets/subscriptions.py
index dec1274..c8d3dcd 100644
--- a/Allura/allura/lib/widgets/subscriptions.py
+++ b/Allura/allura/lib/widgets/subscriptions.py
@@ -75,7 +75,7 @@ class SubscribeForm(ew.SimpleForm):
     defaults = dict(
         ew.SimpleForm.defaults,
         thing='tool',
-        style='text',
+        style='icon',
         tool_subscribed=False,
         value=None)
 
@@ -86,3 +86,8 @@ class SubscribeForm(ew.SimpleForm):
 
     def from_python(self, value, state):
         return value
+
+    def resources(self):
+        for r in super(SubscribeForm, self).resources():
+            yield r
+        yield ew.JSLink('js/subscriptions.js')

http://git-wip-us.apache.org/repos/asf/allura/blob/a5227e2e/Allura/allura/templates/widgets/subscribe.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/subscribe.html b/Allura/allura/templates/widgets/subscribe.html
index 5154eb7..1361a9c 100644
--- a/Allura/allura/templates/widgets/subscribe.html
+++ b/Allura/allura/templates/widgets/subscribe.html
@@ -17,28 +17,24 @@
        under the License.
 -#}
 {% import 'allura:templates/jinja_master/lib.html' as lib with context %}
-{% if value %}
-  {% if style == 'icon' %}
-    <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
-      {{lib.csrf_token()}}
-      <input type="hidden" name="unsubscribe" value="1">
-      <a href="#" class="artifact_unsubscribe active" title="Unsubscribe from this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Unsubscribe from this {{thing}}"></b></a>
-    </form>
-  {% else %}
-    You are currently subscribed to this {{thing}}.
-    <br/>
-    {{fields['unsubscribe'].display()}}
-  {% endif %}
-{% else %}
-  {% if style == 'icon' %}
-    <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
-      {{lib.csrf_token()}}
-      <input type="hidden" name="subscribe" value="1">
-      <a href="#" class="artifact_subscribe" title="Subscribe to this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Subscribe to this {{thing}}"></b></a>
-    </form>
-  {% else %}
-    You are currently not subscribed to this {{thing}}.
-    <br/>
-    {{fields['subscribe'].display()}}
-  {% endif %}
+
+{% do g.register_forge_js('js/react.min.js', location='head_js') %}
+{% for blob in g.resource_manager.emit('head_js') %}
+{% if 'react.min.js' in blob %}
+  {{ blob }}
 {% endif %}
+{% endfor %}
+
+<div id="subscription-form" style="display: inline;">{# see subscription.js #}</div>
+
+<script>
+  document.SUBSCRIPTION_OPTIONS = {
+    "thing": "{{thing}}",
+    "subscribed": {{"true" if value else "false"}},
+    "url": "{{action}}",
+    "icon": {
+      "char": "{{g.icons['mail'].char}}",
+      "css": "{{g.icons['mail'].css}}"
+    }
+  };
+</script>

http://git-wip-us.apache.org/repos/asf/allura/blob/a5227e2e/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 9007f87..adfc172 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -322,8 +322,10 @@ class PostController(BaseController, FeedController):
         version = kw.pop('version', None)
         post = self._get_version(version)
         base_post = self.post
+        subscribed = M.Mailbox.subscribed(artifact=self.post)
         return dict(post=post, base_post=base_post,
-                    page=page, limit=limit, count=post_count)
+                    page=page, limit=limit, count=post_count,
+                    subscribed=subscribed)
 
     @expose('jinja:forgeblog:templates/blog/edit_post.html')
     @without_trailing_slash
@@ -375,7 +377,7 @@ class PostController(BaseController, FeedController):
         self.post.commit()
         redirect('.')
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -383,7 +385,10 @@ class PostController(BaseController, FeedController):
             self.post.subscribe(type='direct')
         elif unsubscribe:
             self.post.unsubscribe()
-        redirect(h.really_unicode(request.referer).encode('utf-8'))
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(artifact=self.post),
+        }
 
     def get_feed(self, project, app, user):
         """Return a :class:`allura.controllers.feed.FeedArgs` object describing

http://git-wip-us.apache.org/repos/asf/allura/blob/a5227e2e/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index 94fe6d9..b915823 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -122,7 +122,7 @@ class ForumController(DiscussionController):
     def deleted(self):
         return dict()
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe_to_forum(self, subscribe=None, unsubscribe=None, shortname=None, **kw):
@@ -130,7 +130,10 @@ class ForumController(DiscussionController):
             self.discussion.subscribe(type='direct')
         elif unsubscribe:
             self.discussion.unsubscribe()
-        redirect(h.really_unicode(request.referer).encode('utf-8'))
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(artifact=self.discussion),
+        }
 
 
 class ForumThreadController(ThreadController):

http://git-wip-us.apache.org/repos/asf/allura/blob/a5227e2e/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index c3a83e6..0049957 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1090,7 +1090,7 @@ class RootController(BaseController, FeedController):
             dates=dates,
         )
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
@@ -1098,7 +1098,10 @@ class RootController(BaseController, FeedController):
             M.Mailbox.subscribe(type='direct')
         elif unsubscribe:
             M.Mailbox.unsubscribe()
-        redirect(request.referer)
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(),
+        }
 
 
 class BinController(BaseController):
@@ -1520,7 +1523,7 @@ class TicketController(BaseController, FeedController):
         c.app.globals.invalidate_bin_counts()
         redirect('.')
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
@@ -1528,7 +1531,10 @@ class TicketController(BaseController, FeedController):
             self.ticket.subscribe(type='direct')
         elif unsubscribe:
             self.ticket.unsubscribe()
-        redirect(request.referer)
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(artifact=self.ticket),
+        }
 
     @expose('json:')
     @require_post()

http://git-wip-us.apache.org/repos/asf/allura/blob/a5227e2e/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 229a348..9fca1c2 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -737,7 +737,7 @@ class PageController(BaseController, FeedController):
         self.page.add_multiple_attachments(file_info)
         redirect(request.referer)
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -747,7 +747,10 @@ class PageController(BaseController, FeedController):
             self.page.subscribe(type='direct')
         elif unsubscribe:
             self.page.unsubscribe()
-        redirect(request.referer)
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(artifact=self.page),
+        }
 
 
 class WikiAttachmentController(ac.AttachmentController):


[02/11] allura git commit: [#7685] ticket:802 Submit subscription request via POST

Posted by he...@apache.org.
[#7685] ticket:802 Submit subscription request via POST


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/cc33817a
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/cc33817a
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/cc33817a

Branch: refs/heads/master
Commit: cc33817a3e151554c2b6446f3afb7c052760129d
Parents: e1ad480
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Wed Jun 24 23:39:53 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Wed Jul 22 15:35:25 2015 +0300

----------------------------------------------------------------------
 Allura/allura/templates/widgets/subscribe.html       | 13 +++++++++++--
 ForgeBlog/forgeblog/main.py                          |  1 +
 ForgeDiscussion/forgediscussion/controllers/forum.py |  1 +
 ForgeTracker/forgetracker/tracker_main.py            |  2 ++
 ForgeWiki/forgewiki/wiki_main.py                     |  2 ++
 5 files changed, 17 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/cc33817a/Allura/allura/templates/widgets/subscribe.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/subscribe.html b/Allura/allura/templates/widgets/subscribe.html
index a88c7e4..5154eb7 100644
--- a/Allura/allura/templates/widgets/subscribe.html
+++ b/Allura/allura/templates/widgets/subscribe.html
@@ -16,9 +16,14 @@
        specific language governing permissions and limitations
        under the License.
 -#}
+{% import 'allura:templates/jinja_master/lib.html' as lib with context %}
 {% if value %}
   {% if style == 'icon' %}
-    <a href="{{action}}?unsubscribe=True" class="artifact_unsubscribe active" title="Unsubscribe from this {{thing}}"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Unsubscribe from this {{thing}}"></b></a>
+    <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
+      {{lib.csrf_token()}}
+      <input type="hidden" name="unsubscribe" value="1">
+      <a href="#" class="artifact_unsubscribe active" title="Unsubscribe from this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Unsubscribe from this {{thing}}"></b></a>
+    </form>
   {% else %}
     You are currently subscribed to this {{thing}}.
     <br/>
@@ -26,7 +31,11 @@
   {% endif %}
 {% else %}
   {% if style == 'icon' %}
-    <a href="{{action}}?subscribe=True" class="artifact_subscribe" title="Subscribe to this {{thing}}"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Subscribe to this {{thing}}"></b></a>
+    <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
+      {{lib.csrf_token()}}
+      <input type="hidden" name="subscribe" value="1">
+      <a href="#" class="artifact_subscribe" title="Subscribe to this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Subscribe to this {{thing}}"></b></a>
+    </form>
   {% else %}
     You are currently not subscribed to this {{thing}}.
     <br/>

http://git-wip-us.apache.org/repos/asf/allura/blob/cc33817a/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index edfe1f0..9007f87 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -376,6 +376,7 @@ class PostController(BaseController, FeedController):
         redirect('.')
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
         if subscribe:

http://git-wip-us.apache.org/repos/asf/allura/blob/cc33817a/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index 67dbea3..94fe6d9 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -123,6 +123,7 @@ class ForumController(DiscussionController):
         return dict()
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe_to_forum(self, subscribe=None, unsubscribe=None, shortname=None, **kw):
         if subscribe:

http://git-wip-us.apache.org/repos/asf/allura/blob/cc33817a/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 68b1a0c..c3a83e6 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1091,6 +1091,7 @@ class RootController(BaseController, FeedController):
         )
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
         if subscribe:
@@ -1520,6 +1521,7 @@ class TicketController(BaseController, FeedController):
         redirect('.')
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
         if subscribe:

http://git-wip-us.apache.org/repos/asf/allura/blob/cc33817a/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index cfaec31..7899ffa 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -464,6 +464,7 @@ class RootController(BaseController, DispatchIndex, FeedController):
         return dict(example=MARKDOWN_EXAMPLE)
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
         if subscribe:
@@ -735,6 +736,7 @@ class PageController(BaseController, FeedController):
         redirect(request.referer)
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
         if not self.page:


[04/11] allura git commit: [#7685] ticket:802 Added @with_trailing_slash to discussion thread controller

Posted by he...@apache.org.
[#7685] ticket:802 Added @with_trailing_slash to discussion thread controller


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/dada202f
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/dada202f
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/dada202f

Branch: refs/heads/master
Commit: dada202ff032b97f3d43ffc17eaa3d5f90ff1080
Parents: e2cd5f6
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jul 2 16:32:16 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:57 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/dada202f/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 28cfcb6..13fe436 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -20,6 +20,7 @@ from datetime import datetime
 import logging
 
 from tg import expose, redirect, validate, request, flash
+from tg.decorators import with_trailing_slash
 from pylons import tmpl_context as c, app_globals as g
 from webob import exc
 
@@ -182,6 +183,7 @@ class ThreadController(BaseController, FeedController):
         id = unquote(id)
         return self.PostController(self._discussion_controller, self.thread, id), remainder
 
+    @with_trailing_slash
     @expose('jinja:allura:templates/discussion/thread.html')
     def index(self, limit=None, page=0, count=0, **kw):
         c.thread = self.W.thread


[11/11] allura git commit: [#7685] ticket:825 Add UI feedback for subscribe/unsubscribe actions

Posted by he...@apache.org.
[#7685] ticket:825 Add UI feedback for subscribe/unsubscribe actions


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/6d0eb69a
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/6d0eb69a
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/6d0eb69a

Branch: refs/heads/master
Commit: 6d0eb69a33b4118f27617101bf22691f68d60d20
Parents: c89213c
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jul 22 17:10:45 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:58 2015 -0400

----------------------------------------------------------------------
 .../lib/widgets/resources/js/subscriptions.js   | 56 ++++++++++++++++----
 Allura/allura/templates/widgets/subscribe.html  |  1 +
 ForgeBlog/forgeblog/main.py                     |  2 +
 .../forgediscussion/controllers/forum.py        |  1 +
 ForgeTracker/forgetracker/tracker_main.py       |  2 +
 ForgeWiki/forgewiki/wiki_main.py                |  2 +
 6 files changed, 53 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/6d0eb69a/Allura/allura/lib/widgets/resources/js/subscriptions.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/subscriptions.js b/Allura/allura/lib/widgets/resources/js/subscriptions.js
index c03bbeb..d5a7648 100644
--- a/Allura/allura/lib/widgets/resources/js/subscriptions.js
+++ b/Allura/allura/lib/widgets/resources/js/subscriptions.js
@@ -23,21 +23,30 @@ var dom = React.createElement;
 var state = {
   'thing': 'tool',
   'subscribed': false,
+  'subscribed_to_tool': false,
   'url': '',
   'icon': {}
 };
 
 SubscriptionForm = React.createClass({
 
+  getInitialState: function() {
+    return {tooltip_timeout: null};
+  },
+
   render: function() {
     var action = this.props.subscribed ? "Unsubscribe from" : "Subscribe to";
     var title = action + ' this ' + this.props.thing;
     var link_opts = {
+      ref: 'link',
       className: this.props.subscribed ? 'active' : '',
       href: '#',
       title: title,
       onClick: this.handleClick
     };
+    if (this.props.in_progress) {
+      link_opts.style = {cursor: 'wait'};
+    }
     var icon_opts = {
       'data-icon': this.props.icon.char,
       className: 'ico ' + this.props.icon.css,
@@ -56,23 +65,48 @@ SubscriptionForm = React.createClass({
       data.subscribe = true;
     }
     set_state({in_progress: true});
-    /*
-     * TODO:
-     * - show 'in-progress' status to user somehow
-     * - handle errors (show to the user in some kind of popup/flash?)
-     * - If user is subscribed to the whole tool and she tries to subsribe to
-     *   the artifact she will not be subscribed, so nothing will change in the
-     *   UI and it's confusing. We need to show some information message in
-     *   such case
-     */
     $.post(url, data, function(resp) {
       if (resp.status == 'ok') {
-        set_state({subscribed: resp.subscribed});
+        set_state({
+          subscribed: resp.subscribed,
+          subscribed_to_tool: resp.subscribed_to_tool
+        });
+        var link = this.getLinkNode();
+        var text = null;
+        if (resp.subscribed_to_tool) {
+          text = "You can't subscribe to this ";
+          text += this.props.thing;
+          text += " because you are already subscribed to the entire tool";
+        } else {
+          var action = resp.subscribed ? 'subscribed to' : 'unsubscribed from';
+          text = 'Successfully ' + action + ' this ' + this.props.thing;
+        }
+        $(link).tooltipster('content', text).tooltipster('show');
+        if (this.state.tooltip_timeout) {
+          clearTimeout(this.state.tooltip_timeout);
+        }
+        var t = setTimeout(function() { $(link).tooltipster('hide'); }, 4000);
+        this.setState({tooltip_timeout: t});
       }
-    }).always(function() {
+    }.bind(this)).always(function() {
       set_state({in_progress: false});
     });
     return false;
+  },
+
+  getLinkNode: function() { return React.findDOMNode(this.refs.link); },
+
+  componentDidMount: function() {
+    var link = this.getLinkNode();
+    $(link).tooltipster({
+      content: '',
+      animation: 'fade',
+      delay: 200,
+      trigger: 'custom',
+      position: 'top',
+      iconCloning: false,
+      maxWidth: 300
+    });
   }
 
 });

http://git-wip-us.apache.org/repos/asf/allura/blob/6d0eb69a/Allura/allura/templates/widgets/subscribe.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/subscribe.html b/Allura/allura/templates/widgets/subscribe.html
index 1361a9c..2b61f71 100644
--- a/Allura/allura/templates/widgets/subscribe.html
+++ b/Allura/allura/templates/widgets/subscribe.html
@@ -31,6 +31,7 @@
   document.SUBSCRIPTION_OPTIONS = {
     "thing": "{{thing}}",
     "subscribed": {{"true" if value else "false"}},
+    "subscribed_to_tool": {{"true" if tool_subscribed else "false"}},
     "url": "{{action}}",
     "icon": {
       "char": "{{g.icons['mail'].char}}",

http://git-wip-us.apache.org/repos/asf/allura/blob/6d0eb69a/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index adfc172..b4f4641 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -323,6 +323,7 @@ class PostController(BaseController, FeedController):
         post = self._get_version(version)
         base_post = self.post
         subscribed = M.Mailbox.subscribed(artifact=self.post)
+        c.subscribe_form.tool_subscribed = M.Mailbox.subscribed()
         return dict(post=post, base_post=base_post,
                     page=page, limit=limit, count=post_count,
                     subscribed=subscribed)
@@ -388,6 +389,7 @@ class PostController(BaseController, FeedController):
         return {
             'status': 'ok',
             'subscribed': M.Mailbox.subscribed(artifact=self.post),
+            'subscribed_to_tool': M.Mailbox.subscribed(),
         }
 
     def get_feed(self, project, app, user):

http://git-wip-us.apache.org/repos/asf/allura/blob/6d0eb69a/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index b915823..8d0117d 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -133,6 +133,7 @@ class ForumController(DiscussionController):
         return {
             'status': 'ok',
             'subscribed': M.Mailbox.subscribed(artifact=self.discussion),
+            'subscribed_to_tool': M.Mailbox.subscribed(),
         }
 
 

http://git-wip-us.apache.org/repos/asf/allura/blob/6d0eb69a/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 0049957..ddf570d 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1359,6 +1359,7 @@ class TicketController(BaseController, FeedController):
             c.ticket_custom_field = W.ticket_custom_field
             c.vote_form = W.vote_form
             tool_subscribed = M.Mailbox.subscribed()
+            c.subscribe_form.tool_subscribed = tool_subscribed
             if tool_subscribed:
                 subscribed = False
             else:
@@ -1534,6 +1535,7 @@ class TicketController(BaseController, FeedController):
         return {
             'status': 'ok',
             'subscribed': M.Mailbox.subscribed(artifact=self.ticket),
+            'subscribed_to_tool': M.Mailbox.subscribed(),
         }
 
     @expose('json:')

http://git-wip-us.apache.org/repos/asf/allura/blob/6d0eb69a/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 9fca1c2..513b1e2 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -558,6 +558,7 @@ class PageController(BaseController, FeedController):
         next = cur + 1
         hide_left_bar = not (c.app.show_left_bar)
         subscribed_to_page = M.Mailbox.subscribed(artifact=self.page)
+        c.subscribe_form.tool_subscribed = M.Mailbox.subscribed()
         return dict(
             page=page,
             cur=cur, prev=prev, next=next,
@@ -750,6 +751,7 @@ class PageController(BaseController, FeedController):
         return {
             'status': 'ok',
             'subscribed': M.Mailbox.subscribed(artifact=self.page),
+            'subscribed_to_tool': M.Mailbox.subscribed(),
         }
 
 


[07/11] allura git commit: [#7685] ticket:802 Use post in SCM subscription test and fix format call

Posted by he...@apache.org.
[#7685] ticket:802 Use post in SCM subscription test and fix format call


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/eb5f3d6c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/eb5f3d6c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/eb5f3d6c

Branch: refs/heads/master
Commit: eb5f3d6ce3297d6ad58d1133670b67df50f76a9d
Parents: dada202
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 3 12:45:13 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:57 2015 -0400

----------------------------------------------------------------------
 .../forgegit/tests/functional/test_controllers.py   | 16 +++++++++-------
 ForgeWiki/forgewiki/wiki_main.py                    |  2 +-
 2 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/eb5f3d6c/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index b84cd5a..20bfc1b 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -353,24 +353,26 @@ class TestRootController(_TestCase):
         assert link is not None, r.html
 
         # subscribe
-        self.app.get(ci + 'tree/subscribe?subscribe=True',
-                     extra_environ={'username': str(user.username)}).follow()
+        self.app.post(str(ci + 'tree/subscribe'),
+                      {'subscribe': True},
+                      extra_environ={'username': str(user.username)}).follow()
         # user is subscribed
         assert M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        link = r.html.find('a', 'artifact_unsubscribe active')
-        assert link is not None, r.html
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'unsubscribe'})
+        assert inp is not None
 
         # unsubscribe
-        self.app.get(ci + 'tree/subscribe?unsubscribe=True',
+        self.app.post(str(ci + 'tree/subscribe'),
+                     {'unsubscribe': True},
                      extra_environ={'username': str(user.username)}).follow()
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        link = r.html.find('a', 'artifact_subscribe')
-        assert link is not None, r.html
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'subscribe'})
+        assert inp is not None
 
     def test_timezone(self):
         ci = self._get_ci()

http://git-wip-us.apache.org/repos/asf/allura/blob/eb5f3d6c/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index c2bcb16..229a348 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -249,7 +249,7 @@ The wiki uses [Markdown](%s) syntax.
             subscribe_title = '{}{}'.format(
                 subscribe_action.capitalize(),
                 '' if subscribed else ' to wiki')
-            subscribe_url = '#toggle-subscribe'.format(self.url)
+            subscribe_url = '{}#toggle-subscribe'.format(self.url)
             links += [SitemapEntry(''),
                       SitemapEntry(subscribe_title, subscribe_url, ui_icon=g.icons['mail'])]
         if not admin_menu:


[06/11] allura git commit: [#7685] ticket:802 Require POST for repository subscription

Posted by he...@apache.org.
[#7685] ticket:802 Require POST for repository subscription


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/4b76e4cd
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/4b76e4cd
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/4b76e4cd

Branch: refs/heads/master
Commit: 4b76e4cdfc60518d75e5945bb2bd16ef829c6cc2
Parents: 55c7b48
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jul 2 14:29:12 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:57 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/4b76e4cd/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index f8b0834..0178723 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -689,6 +689,7 @@ class TreeBrowser(BaseController, DispatchIndex):
             self), rest
 
     @expose()
+    @require_post()
     @validate(subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
         if subscribe:


[03/11] allura git commit: [#7685] ticket:802 Fixed tests

Posted by he...@apache.org.
[#7685] ticket:802 Fixed tests


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/55c7b485
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/55c7b485
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/55c7b485

Branch: refs/heads/master
Commit: 55c7b485a169e72cf402504122ac68c85b16c028
Parents: c5f8bda
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Sat Jun 27 22:53:54 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:56 2015 -0400

----------------------------------------------------------------------
 .../tests/functional/test_forum.py              |  2 +-
 .../forgetracker/tests/functional/test_root.py  | 22 ++++++++++----------
 .../forgewiki/tests/functional/test_rest.py     |  2 +-
 .../forgewiki/tests/functional/test_root.py     | 16 +++++++-------
 4 files changed, 21 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/55c7b485/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index 9c5397f..ae91bf0 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -576,7 +576,7 @@ class TestForum(TestController):
             if field.has_key('name') and 'subscription' not in field['name']:
                 params[field['name']] = field.has_key('value') and field['value'] or ''
         self.app.post(str(subscribe_url), params=params)
-        self.app.get('/discussion/general/subscribe_to_forum?subscribe=True')
+        self.app.post('/discussion/general/subscribe_to_forum', {'subscribe': True})
         f = thread.html.find('div', {'class': 'row reply_post_form'}).find('form')
         rep_url = f.get('action')
         params = dict()

http://git-wip-us.apache.org/repos/asf/allura/blob/55c7b485/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 871f0fd..23c77f4 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -840,7 +840,7 @@ class TestFunctionalController(TrackerTestController):
         }, upload_files=[upload]).follow()
         assert file_name in ticket_editor, ticket_editor.showbrowser()
         req = self.app.get('/bugs/1/')
-        file_link = req.html.findAll('form')[1].findAll('a')[6]
+        file_link = req.html.findAll('form')[2].findAll('a')[6]
         assert_equal(file_link.string, file_name)
         self.app.post(str(file_link['href']), {
             'delete': 'True'
@@ -882,7 +882,7 @@ class TestFunctionalController(TrackerTestController):
         ticket_editor = self.app.post('/bugs/1/update_ticket', {
             'summary': 'zzz'
         }, upload_files=[upload]).follow()
-        download = self.app.get(str(ticket_editor.html.findAll('form')[1].findAll('a')[7]['href']))
+        download = self.app.get(str(ticket_editor.html.findAll('form')[2].findAll('a')[7]['href']))
         assert_equal(download.body, file_data)
 
     def test_two_attachments(self):
@@ -1239,7 +1239,7 @@ class TestFunctionalController(TrackerTestController):
         # Test edit ticket form
         self.new_ticket(summary='Test ticket')
         response = self.app.get('/bugs/1/')
-        form = response.forms[1]
+        form = response.forms[2]
         assert_equal(
             form['ticket_form.custom_fields._priority'].value, 'normal')
         assert_equal(form['ticket_form.custom_fields._category'].value, '')
@@ -1247,9 +1247,9 @@ class TestFunctionalController(TrackerTestController):
         form['ticket_form.custom_fields._priority'] = 'urgent'
         form['ticket_form.custom_fields._category'] = 'bugs'
         error_form = form.submit()
-        assert_equal(error_form.forms[1]['ticket_form.custom_fields._priority'].value,
+        assert_equal(error_form.forms[2]['ticket_form.custom_fields._priority'].value,
                      'urgent')
-        assert_equal(error_form.forms[1]['ticket_form.custom_fields._category'].value,
+        assert_equal(error_form.forms[2]['ticket_form.custom_fields._category'].value,
                      'bugs')
 
     def test_new_ticket_validation(self):
@@ -1269,7 +1269,7 @@ class TestFunctionalController(TrackerTestController):
         # set a summary, submit, and check for success
         error_form.forms[1]['ticket_form.summary'] = summary
         success = error_form.forms[1].submit().follow().html
-        assert success.findAll('form')[1].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
+        assert success.findAll('form')[2].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
         assert success.find('input', {'name': 'ticket_form.summary'})['value'] == summary
 
     def test_edit_ticket_validation(self):
@@ -1280,7 +1280,7 @@ class TestFunctionalController(TrackerTestController):
         # check that existing form is valid
         assert response.html.find('input', {'name': 'ticket_form.summary'})['value'] == old_summary
         assert not response.html.find('div', {'class': 'error'})
-        form = response.forms[1]
+        form = response.forms[2]
         # try submitting with no summary set and check for error message
         form['ticket_form.summary'] = ""
         error_form = form.submit()
@@ -1289,11 +1289,11 @@ class TestFunctionalController(TrackerTestController):
         assert error_message.string == 'You must provide a Title'
         assert error_message.findPreviousSibling('input').get('name') == 'ticket_form.summary'
         # set a summary, submit, and check for success
-        error_form.forms[1]['ticket_form.summary'] = new_summary
-        r = error_form.forms[1].submit()
+        error_form.forms[2]['ticket_form.summary'] = new_summary
+        r = error_form.forms[2].submit()
         assert r.status_int == 302, r.showbrowser()
         success = r.follow().html
-        assert success.findAll('form')[1].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
+        assert success.findAll('form')[2].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
         assert success.find('input', {'name': 'ticket_form.summary'})['value'] == new_summary
 
     def test_home(self):
@@ -2720,7 +2720,7 @@ class TestCustomUserField(TrackerTestController):
     def test_change_user_field(self):
         kw = {'custom_fields._code_review': ''}
         r = self.new_ticket(summary='test custom fields', **kw).follow()
-        f = r.forms[1]
+        f = r.forms[2]
         # Populate ProjectUserCombo's select with option we want.
         # This is a workaround for tests,
         # in real enviroment this is populated via ajax.

http://git-wip-us.apache.org/repos/asf/allura/blob/55c7b485/ForgeWiki/forgewiki/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_rest.py b/ForgeWiki/forgewiki/tests/functional/test_rest.py
index 6a5de3b..a2b58ae 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_rest.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_rest.py
@@ -42,7 +42,7 @@ class TestWikiApi(TestRestApiBase):
 
     def test_get_page(self):
         r = self.app.get('/p/test/wiki/Home/')
-        discussion_url = r.html.findAll('form')[2]['action'][:-4]
+        discussion_url = r.html.findAll('form')[3]['action'][:-4]
         content = file(__file__).read()
         self.app.post('/wiki/Home/attach',
                       upload_files=[('file_info', 'test_root.py', content)])

http://git-wip-us.apache.org/repos/asf/allura/blob/55c7b485/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index aea9028..dafb74f 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -754,24 +754,24 @@ class TestRootController(TestController):
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get('/p/test/wiki/Home/', extra_environ={'username': str(user.username)})
-        link = r.html.find('a', {'href': '/p/test/wiki/subscribe?subscribe=True'})
-        assert link is not None
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'subscribe'})
+        assert inp is not None
         # subscribe
-        self.app.get('/p/test/wiki/subscribe?subscribe=True',
+        self.app.post('/p/test/wiki/subscribe', {'subscribe': True},
                      extra_environ={'username': str(user.username)}).follow()
         # user is subscribed
         assert M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get('/p/test/wiki/Home/', extra_environ={'username': str(user.username)})
-        link = r.html.find('a', {'href': '/p/test/wiki/subscribe?unsubscribe=True'})
-        assert link is not None
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'unsubscribe'})
+        assert inp is not None
         # unsubscribe
-        self.app.get('/p/test/wiki/subscribe?unsubscribe=True',
+        self.app.post('/p/test/wiki/subscribe', {'unsubscribe': True},
                      extra_environ={'username': str(user.username)}).follow()
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get('/p/test/wiki/Home/', extra_environ={'username': str(user.username)})
-        link = r.html.find('a', {'href': '/p/test/wiki/subscribe?subscribe=True'})
-        assert link is not None
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'subscribe'})
+        assert inp is not None
 
     def test_rate_limit_new_page(self):
         # Set rate limit to unlimit


[10/11] allura git commit: [#7685] ticket:819 Fix tests failing due to new markup

Posted by he...@apache.org.
[#7685] ticket:819 Fix tests failing due to new markup


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/c89213cb
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/c89213cb
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/c89213cb

Branch: refs/heads/master
Commit: c89213cb741a860f6e3ed95fc5bb01781228917f
Parents: a5227e2
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Jul 13 12:32:15 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:58 2015 -0400

----------------------------------------------------------------------
 AlluraTest/alluratest/controller.py             | 16 ++++++++++++
 .../tests/functional/test_controllers.py        | 26 +++++++++++---------
 .../forgetracker/tests/functional/test_root.py  | 25 ++++++++++---------
 .../forgewiki/tests/functional/test_rest.py     |  2 +-
 .../forgewiki/tests/functional/test_root.py     |  2 --
 5 files changed, 44 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c89213cb/AlluraTest/alluratest/controller.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/controller.py b/AlluraTest/alluratest/controller.py
index 4a8f983..5a61ab7 100644
--- a/AlluraTest/alluratest/controller.py
+++ b/AlluraTest/alluratest/controller.py
@@ -18,6 +18,7 @@
 """Unit and functional test suite for allura."""
 import os
 import urllib
+import json
 
 import mock
 import beaker.session
@@ -169,6 +170,21 @@ class TestController(object):
         "Extract webflash content from response."
         return urllib.unquote(response.cookies_set.get('webflash', ''))
 
+    def subscription_options(self, response):
+        """
+        Extract subscription options to be passed to React SubscriptionForm
+        component from the <script> tag
+        """
+        script = None
+        for s in response.html.findAll('script'):
+            if s.getText().strip().startswith('document.SUBSCRIPTION_OPTIONS'):
+                script = s
+                break
+        assert script is not None, 'subscription options not found'
+        _, json_dict = script.getText().split('=')
+        json_dict = json_dict.strip(' ;')
+        return json.loads(json_dict)
+
 
 class TestRestApiBase(TestController):
 

http://git-wip-us.apache.org/repos/asf/allura/blob/c89213cb/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 20bfc1b..7f6bf88 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -349,30 +349,32 @@ class TestRootController(_TestCase):
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        link = r.html.find('a', 'artifact_subscribe')
-        assert link is not None, r.html
+        opts = self.subscription_options(r)
+        assert_equal(opts['subscribed'], False)
 
         # subscribe
-        self.app.post(str(ci + 'tree/subscribe'),
-                      {'subscribe': True},
-                      extra_environ={'username': str(user.username)}).follow()
+        r = self.app.post(str(ci + 'tree/subscribe'),
+                          {'subscribe': True},
+                          extra_environ={'username': str(user.username)})
+        assert_equal(r.json, {'status': 'ok', 'subscribed': True})
         # user is subscribed
         assert M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        inp = r.html.find('input', {'type': 'hidden', 'name': 'unsubscribe'})
-        assert inp is not None
+        opts = self.subscription_options(r)
+        assert_equal(opts['subscribed'], True)
 
         # unsubscribe
-        self.app.post(str(ci + 'tree/subscribe'),
-                     {'unsubscribe': True},
-                     extra_environ={'username': str(user.username)}).follow()
+        r = self.app.post(str(ci + 'tree/subscribe'),
+                          {'unsubscribe': True},
+                          extra_environ={'username': str(user.username)})
+        assert_equal(r.json, {'status': 'ok', 'subscribed': False})
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        inp = r.html.find('input', {'type': 'hidden', 'name': 'subscribe'})
-        assert inp is not None
+        opts = self.subscription_options(r)
+        assert_equal(opts['subscribed'], False)
 
     def test_timezone(self):
         ci = self._get_ci()

http://git-wip-us.apache.org/repos/asf/allura/blob/c89213cb/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 23c77f4..de061ca 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -294,7 +294,8 @@ class TestFunctionalController(TrackerTestController):
         summary = 'test new ticket'
         ticket_view = self.new_ticket(summary=summary).follow()
         assert_true(summary in ticket_view)
-        assert 'class="artifact_subscribe' in ticket_view
+        opts = self.subscription_options(ticket_view)
+        assert_equal(opts['subscribed'], False)
 
     def test_labels(self):
         ticket_view = self.new_ticket(summary='summary', labels="test label").follow()
@@ -840,7 +841,7 @@ class TestFunctionalController(TrackerTestController):
         }, upload_files=[upload]).follow()
         assert file_name in ticket_editor, ticket_editor.showbrowser()
         req = self.app.get('/bugs/1/')
-        file_link = req.html.findAll('form')[2].findAll('a')[6]
+        file_link = req.html.findAll('form')[1].findAll('a')[6]
         assert_equal(file_link.string, file_name)
         self.app.post(str(file_link['href']), {
             'delete': 'True'
@@ -882,7 +883,7 @@ class TestFunctionalController(TrackerTestController):
         ticket_editor = self.app.post('/bugs/1/update_ticket', {
             'summary': 'zzz'
         }, upload_files=[upload]).follow()
-        download = self.app.get(str(ticket_editor.html.findAll('form')[2].findAll('a')[7]['href']))
+        download = self.app.get(str(ticket_editor.html.findAll('form')[1].findAll('a')[7]['href']))
         assert_equal(download.body, file_data)
 
     def test_two_attachments(self):
@@ -1239,7 +1240,7 @@ class TestFunctionalController(TrackerTestController):
         # Test edit ticket form
         self.new_ticket(summary='Test ticket')
         response = self.app.get('/bugs/1/')
-        form = response.forms[2]
+        form = response.forms[1]
         assert_equal(
             form['ticket_form.custom_fields._priority'].value, 'normal')
         assert_equal(form['ticket_form.custom_fields._category'].value, '')
@@ -1247,9 +1248,9 @@ class TestFunctionalController(TrackerTestController):
         form['ticket_form.custom_fields._priority'] = 'urgent'
         form['ticket_form.custom_fields._category'] = 'bugs'
         error_form = form.submit()
-        assert_equal(error_form.forms[2]['ticket_form.custom_fields._priority'].value,
+        assert_equal(error_form.forms[1]['ticket_form.custom_fields._priority'].value,
                      'urgent')
-        assert_equal(error_form.forms[2]['ticket_form.custom_fields._category'].value,
+        assert_equal(error_form.forms[1]['ticket_form.custom_fields._category'].value,
                      'bugs')
 
     def test_new_ticket_validation(self):
@@ -1269,7 +1270,7 @@ class TestFunctionalController(TrackerTestController):
         # set a summary, submit, and check for success
         error_form.forms[1]['ticket_form.summary'] = summary
         success = error_form.forms[1].submit().follow().html
-        assert success.findAll('form')[2].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
+        assert success.findAll('form')[1].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
         assert success.find('input', {'name': 'ticket_form.summary'})['value'] == summary
 
     def test_edit_ticket_validation(self):
@@ -1280,7 +1281,7 @@ class TestFunctionalController(TrackerTestController):
         # check that existing form is valid
         assert response.html.find('input', {'name': 'ticket_form.summary'})['value'] == old_summary
         assert not response.html.find('div', {'class': 'error'})
-        form = response.forms[2]
+        form = response.forms[1]
         # try submitting with no summary set and check for error message
         form['ticket_form.summary'] = ""
         error_form = form.submit()
@@ -1289,11 +1290,11 @@ class TestFunctionalController(TrackerTestController):
         assert error_message.string == 'You must provide a Title'
         assert error_message.findPreviousSibling('input').get('name') == 'ticket_form.summary'
         # set a summary, submit, and check for success
-        error_form.forms[2]['ticket_form.summary'] = new_summary
-        r = error_form.forms[2].submit()
+        error_form.forms[1]['ticket_form.summary'] = new_summary
+        r = error_form.forms[1].submit()
         assert r.status_int == 302, r.showbrowser()
         success = r.follow().html
-        assert success.findAll('form')[2].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
+        assert success.findAll('form')[1].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
         assert success.find('input', {'name': 'ticket_form.summary'})['value'] == new_summary
 
     def test_home(self):
@@ -2720,7 +2721,7 @@ class TestCustomUserField(TrackerTestController):
     def test_change_user_field(self):
         kw = {'custom_fields._code_review': ''}
         r = self.new_ticket(summary='test custom fields', **kw).follow()
-        f = r.forms[2]
+        f = r.forms[1]
         # Populate ProjectUserCombo's select with option we want.
         # This is a workaround for tests,
         # in real enviroment this is populated via ajax.

http://git-wip-us.apache.org/repos/asf/allura/blob/c89213cb/ForgeWiki/forgewiki/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_rest.py b/ForgeWiki/forgewiki/tests/functional/test_rest.py
index a2b58ae..6a5de3b 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_rest.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_rest.py
@@ -42,7 +42,7 @@ class TestWikiApi(TestRestApiBase):
 
     def test_get_page(self):
         r = self.app.get('/p/test/wiki/Home/')
-        discussion_url = r.html.findAll('form')[3]['action'][:-4]
+        discussion_url = r.html.findAll('form')[2]['action'][:-4]
         content = file(__file__).read()
         self.app.post('/wiki/Home/attach',
                       upload_files=[('file_info', 'test_root.py', content)])

http://git-wip-us.apache.org/repos/asf/allura/blob/c89213cb/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index dafb74f..3f69d89 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -258,8 +258,6 @@ class TestRootController(TestController):
                 'labels': '',
                 'viewable_by-0.id': 'all'})
         self.app.post('/wiki/tést/revert', params=dict(version='1'))
-        response = self.app.get('/wiki/tést/')
-        assert 'Subscribe' in response
         response = self.app.get('/wiki/tést/diff?v1=0&v2=0')
         assert 'tést' in response
         d = dict(title='testdiff', text="""**Optionally**, you may also want to remove all the unused accounts that have accumulated (one was created for *every* logged in SF-user who has visited your MediaWiki hosted app):


[09/11] allura git commit: [#7685] ticket:802 Add trailing slash to discussion controller

Posted by he...@apache.org.
[#7685] ticket:802 Add trailing slash to discussion controller


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/63dbb3df
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/63dbb3df
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/63dbb3df

Branch: refs/heads/master
Commit: 63dbb3dfadabf1b5dff1d5feecf426c56e963576
Parents: eb5f3d6
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 3 12:53:50 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Wed Jul 22 11:47:57 2015 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/63dbb3df/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 13fe436..b329b01 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -89,6 +89,7 @@ class DiscussionController(BaseController, FeedController):
         if not hasattr(self, 'moderate'):
             self.moderate = ModerationController(self)
 
+    @with_trailing_slash
     @expose('jinja:allura:templates/discussion/index.html')
     def index(self, threads=None, limit=None, page=0, count=0, **kw):
         c.discussion = self.W.discussion