From 539890afdfe9b0d70b1cc7e8307f6d33ebc457f4 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 21 Mar 2014 14:13:04 -0400 Subject: [PATCH] Let's not show tons of extra information about invites unless you're the person who invited them. --- .../controllers/user_invited_controller.js | 16 ++++-- .../javascripts/discourse/models/invite.js | 4 +- .../templates/user/invited.js.handlebars | 52 ++++++++++--------- app/controllers/users_controller.rb | 6 +-- app/serializers/invite_serializer.rb | 9 +++- app/serializers/invited_user_serializer.rb | 22 ++++++++ lib/guardian.rb | 2 +- spec/components/guardian_spec.rb | 8 +-- spec/controllers/users_controller_spec.rb | 20 +++---- 9 files changed, 89 insertions(+), 50 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/user_invited_controller.js b/app/assets/javascripts/discourse/controllers/user_invited_controller.js index fac3c5be298..673e3a0ae28 100644 --- a/app/assets/javascripts/discourse/controllers/user_invited_controller.js +++ b/app/assets/javascripts/discourse/controllers/user_invited_controller.js @@ -6,7 +6,13 @@ @namespace Discourse @module Discourse **/ -Discourse.UserInvitedController = Ember.ArrayController.extend({ +Discourse.UserInvitedController = Ember.ObjectController.extend({ + user: null, + + init: function() { + this._super(); + this.set('searchTerm', ''); + }, /** Observe the search term box with a debouncer and change the results. @@ -44,8 +50,8 @@ Discourse.UserInvitedController = Ember.ArrayController.extend({ @property showSearch **/ showSearch: function() { - return !(Em.isNone(this.get('searchTerm')) && this.get('model.length') === 0); - }.property('searchTerm', 'model.length'), + return !(Em.isNone(this.get('searchTerm')) && this.get('invites.length') === 0); + }.property('searchTerm', 'invites.length'), /** Were the results limited by our `maxInvites` @@ -53,8 +59,8 @@ Discourse.UserInvitedController = Ember.ArrayController.extend({ @property truncated **/ truncated: function() { - return this.get('model.length') === Discourse.SiteSettings.invites_shown; - }.property('model.length'), + return this.get('invites.length') === Discourse.SiteSettings.invites_shown; + }.property('invites.length'), actions: { diff --git a/app/assets/javascripts/discourse/models/invite.js b/app/assets/javascripts/discourse/models/invite.js index 00b5a35b6b3..7db80845c44 100644 --- a/app/assets/javascripts/discourse/models/invite.js +++ b/app/assets/javascripts/discourse/models/invite.js @@ -36,9 +36,11 @@ Discourse.Invite.reopenClass({ if (!Em.isNone(filter)) { data.filter = filter; } return Discourse.ajax("/users/" + user.get('username_lower') + "/invited.json", {data: data}).then(function (result) { - return result.map(function (i) { + result.invites = result.invites.map(function (i) { return Discourse.Invite.create(i); }); + + return Em.Object.create(result); }); } diff --git a/app/assets/javascripts/discourse/templates/user/invited.js.handlebars b/app/assets/javascripts/discourse/templates/user/invited.js.handlebars index cf3da9bdc24..96b77f17c43 100644 --- a/app/assets/javascripts/discourse/templates/user/invited.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/invited.js.handlebars @@ -12,42 +12,46 @@ {{/if}} - {{#if model}} + {{#if model.invites}} - - - - - + {{#if can_see_invite_details}} + + + + + + {{/if}} - {{#each model}} + {{#each invite in model.invites}} - {{#if user}} - - - - - - - + {{#if invite.user}} + + + {{#if can_see_invite_details}} + + + + + + {{/if}} {{else}} - + {{/if}} diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 1cbbf1f875f..b0f3dd54e98 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -68,15 +68,15 @@ class UsersController < ApplicationController def invited inviter = fetch_user_from_params - invites = if guardian.can_see_pending_invites_from?(inviter) + invites = if guardian.can_see_invite_details?(inviter) Invite.find_all_invites_from(inviter) else Invite.find_redeemed_invites_from(inviter) end invites = invites.filter_by(params[:filter]) - - render_serialized(invites.to_a, InviteSerializer) + render_json_dump invites: serialize_data(invites.to_a, InviteSerializer), + can_see_invite_details: guardian.can_see_invite_details?(inviter) end def is_local_username diff --git a/app/serializers/invite_serializer.rb b/app/serializers/invite_serializer.rb index 87a3cf7f081..4180eda4ee0 100644 --- a/app/serializers/invite_serializer.rb +++ b/app/serializers/invite_serializer.rb @@ -1,7 +1,6 @@ class InviteSerializer < ApplicationSerializer - attributes :email, :created_at, :redeemed_at, :expired - has_one :user, embed: :objects, serializer: InvitedUserSerializer + attributes :email, :created_at, :redeemed_at, :expired, :user def include_email? !object.redeemed? @@ -11,4 +10,10 @@ class InviteSerializer < ApplicationSerializer object.expired? end + def user + ser = InvitedUserSerializer.new(object.user, scope: scope, root: false) + ser.invited_by = object.invited_by + ser.as_json + end + end diff --git a/app/serializers/invited_user_serializer.rb b/app/serializers/invited_user_serializer.rb index dc996b10981..ce3fe906235 100644 --- a/app/serializers/invited_user_serializer.rb +++ b/app/serializers/invited_user_serializer.rb @@ -7,24 +7,46 @@ class InvitedUserSerializer < BasicUserSerializer :days_visited, :days_since_created + attr_accessor :invited_by + def time_read AgeWords.age_words(object.user_stat.time_read) end + def include_time_read? + scope.can_see_invite_details?(invited_by) + end + def days_visited object.user_stat.days_visited end + def include_days_visited? + scope.can_see_invite_details?(invited_by) + end + def topics_entered object.user_stat.topics_entered end + def include_topics_entered? + scope.can_see_invite_details?(invited_by) + end + def posts_read_count object.user_stat.posts_read_count end + def include_posts_read_count? + scope.can_see_invite_details?(invited_by) + end + def days_since_created ((Time.now - object.created_at) / 60 / 60 / 24).ceil end + def include_days_since_created + scope.can_see_invite_details?(invited_by) + end + end diff --git a/lib/guardian.rb b/lib/guardian.rb index e26a04bafcf..b80860a7260 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -176,7 +176,7 @@ class Guardian @user.approved? end - def can_see_pending_invites_from?(user) + def can_see_invite_details?(user) is_me?(user) end diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index 936704940a4..ec83c27bd14 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -1108,18 +1108,18 @@ describe Guardian do end end - context "can_see_pending_invites_from?" do + context "can_see_invite_details?" do it 'is false without a logged in user' do - Guardian.new(nil).can_see_pending_invites_from?(user).should be_false + Guardian.new(nil).can_see_invite_details?(user).should be_false end it 'is false without a user to look at' do - Guardian.new(user).can_see_pending_invites_from?(nil).should be_false + Guardian.new(user).can_see_invite_details?(nil).should be_false end it 'is true when looking at your own invites' do - Guardian.new(user).can_see_pending_invites_from?(user).should be_true + Guardian.new(user).can_see_invite_details?(user).should be_true end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 1833dab5f73..ab299849aa4 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -835,7 +835,7 @@ describe UsersController do xhr :get, :invited, username: inviter.username, filter: 'billybob' - invites = JSON.parse(response.body) + invites = JSON.parse(response.body)['invites'] expect(invites).to have(1).item expect(invites.first).to include('email' => 'billybob@example.com') end @@ -857,7 +857,7 @@ describe UsersController do xhr :get, :invited, username: inviter.username, filter: 'billybob' - invites = JSON.parse(response.body) + invites = JSON.parse(response.body)['invites'] expect(invites).to have(1).item expect(invites.first).to include('email' => 'billybob@example.com') end @@ -870,7 +870,7 @@ describe UsersController do xhr :get, :invited, username: inviter.username - invites = JSON.parse(response.body) + invites = JSON.parse(response.body)['invites'] expect(invites).to be_empty end end @@ -883,7 +883,7 @@ describe UsersController do xhr :get, :invited, username: inviter.username - invites = JSON.parse(response.body) + invites = JSON.parse(response.body)['invites'] expect(invites).to have(1).item expect(invites.first).to include('email' => invite.email) end @@ -898,13 +898,13 @@ describe UsersController do inviter = Fabricate(:user) invite = Fabricate(:invite, invited_by: inviter) stub_guardian(user) do |guardian| - guardian.stubs(:can_see_pending_invites_from?). + guardian.stubs(:can_see_invite_details?). with(inviter).returns(true) end xhr :get, :invited, username: inviter.username - invites = JSON.parse(response.body) + invites = JSON.parse(response.body)['invites'] expect(invites).to have(1).item expect(invites.first).to include("email" => invite.email) end @@ -917,14 +917,14 @@ describe UsersController do invitee = Fabricate(:user) Fabricate(:invite, invited_by: inviter) stub_guardian(user) do |guardian| - guardian.stubs(:can_see_pending_invites_from?). + guardian.stubs(:can_see_invite_details?). with(inviter).returns(false) end xhr :get, :invited, username: inviter.username - invites = JSON.parse(response.body) - expect(invites).to be_empty + json = JSON.parse(response.body)['invites'] + expect(json).to be_empty end end end @@ -938,7 +938,7 @@ describe UsersController do xhr :get, :invited, username: inviter.username - invites = JSON.parse(response.body) + invites = JSON.parse(response.body)['invites'] expect(invites).to have(1).item expect(invites.first).to include('email' => invite.email) end
{{i18n user.invited.user}} {{i18n user.invited.redeemed_at}}{{i18n user.last_seen}}{{i18n user.invited.topics_entered}}{{i18n user.invited.posts_read_count}}{{i18n user.invited.time_read}}{{i18n user.invited.days_visited}}{{i18n user.last_seen}}{{i18n user.invited.topics_entered}}{{i18n user.invited.posts_read_count}}{{i18n user.invited.time_read}}{{i18n user.invited.days_visited}}
- {{#link-to 'user' user}}{{avatar user imageSize="tiny"}}{{/link-to}} - {{#link-to 'user' user}}{{user.username}}{{/link-to}} - {{unboundDate redeemed_at}}{{unboundDate user.last_seen_at}}{{number user.topics_entered}}{{number user.posts_read_count}}{{{unbound user.time_read}}}{{{unbound user.days_visited}}} - / - {{{unbound user.days_since_created}}} + {{#link-to 'user' invite.user}}{{avatar invite.user imageSize="tiny"}}{{/link-to}} + {{#link-to 'user' invite.user}}{{invite.user.username}}{{/link-to}} + {{unboundDate invite.redeemed_at}}{{unboundDate invite.user.last_seen_at}}{{number invite.user.topics_entered}}{{number invite.user.posts_read_count}}{{{unbound invite.user.time_read}}}{{{unbound invite.user.days_visited}}} + / + {{{unbound invite.user.days_since_created}}}{{unbound email}}{{unbound invite.email}} - {{#if expired}} + {{#if invite.expired}} {{i18n user.invited.expired}} {{/if}} - {{#if rescinded}} + {{#if invite.rescinded}} {{i18n user.invited.rescinded}} {{else}} - + {{/if}}