From 057c56ef9bd74427d9417ea759d62e888dc8aa46 Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Wed, 16 Apr 2014 15:32:57 +0530 Subject: [PATCH 1/9] Add user-badge component. --- .../components/user_badge_component.js | 7 ++++ .../components/user-badge.js.handlebars | 4 +++ .../templates/poster_expansion.handlebars | 2 +- .../stylesheets/desktop/poster_expansion.scss | 35 +++---------------- .../stylesheets/desktop/user-badges.scss | 25 +++++++++++++ 5 files changed, 41 insertions(+), 32 deletions(-) create mode 100644 app/assets/javascripts/discourse/components/user_badge_component.js create mode 100644 app/assets/javascripts/discourse/templates/components/user-badge.js.handlebars create mode 100644 app/assets/stylesheets/desktop/user-badges.scss diff --git a/app/assets/javascripts/discourse/components/user_badge_component.js b/app/assets/javascripts/discourse/components/user_badge_component.js new file mode 100644 index 0000000000..daf3e6d305 --- /dev/null +++ b/app/assets/javascripts/discourse/components/user_badge_component.js @@ -0,0 +1,7 @@ +Discourse.UserBadgeComponent = Ember.Component.extend({ + tagName: 'span', + + badgeTypeClassName: function() { + return "badge-type-" + this.get('badge.badge_type.name').toLowerCase(); + }.property('badge.badge_type.name') +}); diff --git a/app/assets/javascripts/discourse/templates/components/user-badge.js.handlebars b/app/assets/javascripts/discourse/templates/components/user-badge.js.handlebars new file mode 100644 index 0000000000..b934b3b1fa --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/user-badge.js.handlebars @@ -0,0 +1,4 @@ + + + {{badge.name}} + diff --git a/app/assets/javascripts/discourse/templates/poster_expansion.handlebars b/app/assets/javascripts/discourse/templates/poster_expansion.handlebars index 1e9f3e99ed..874935fda5 100644 --- a/app/assets/javascripts/discourse/templates/poster_expansion.handlebars +++ b/app/assets/javascripts/discourse/templates/poster_expansion.handlebars @@ -10,7 +10,7 @@ {{#if showBadges}}
{{#each user.featured_user_badges}} - {{badge.name}} + {{user-badge badge=badge}} {{/each}} {{#if showMoreBadges}} {{i18n badges.more_badges count=moreBadgesCount}} diff --git a/app/assets/stylesheets/desktop/poster_expansion.scss b/app/assets/stylesheets/desktop/poster_expansion.scss index 8a90a8694c..d3a7a566c6 100644 --- a/app/assets/stylesheets/desktop/poster_expansion.scss +++ b/app/assets/stylesheets/desktop/poster_expansion.scss @@ -102,39 +102,12 @@ font-size: 14px; margin-bottom: -8px; } + } + .more-user-badges { + @extend .user-badge; + padding: 4px 8px; } } } -.user-badge, .more-user-badges { - font-size: 12px; - margin: 0; - line-height: 16px; - display: inline-block; - .fa { - padding-right: 5px; - font-size: 16px; - } -} - -.user-badge { - padding: 3px 8px; - border: 1px solid $secondary-border-color; -} - -.more-user-badges { - padding: 4px 8px; -} - -.badge-type-1 .fa-certificate { - color: #A67D3D; -} - -.badge-type-2 .fa-certificate { - color: silver; -} - -.badge-type-1 .fa-certificate { - color: gold; -} diff --git a/app/assets/stylesheets/desktop/user-badges.scss b/app/assets/stylesheets/desktop/user-badges.scss new file mode 100644 index 0000000000..66b4ac2024 --- /dev/null +++ b/app/assets/stylesheets/desktop/user-badges.scss @@ -0,0 +1,25 @@ +.user-badge { + padding: 3px 8px; + border: 1px solid $secondary-border-color; + font-size: 12px; + line-height: 16px; + margin: 0; + display: inline-block; + + .fa { + padding-right: 5px; + font-size: 16px; + } + + &.badge-type-gold .fa { + color: #ffd700; + } + + &.badge-type-silver .fa { + color: #c0c0c0; + } + + &.badge-type-bronze .fa { + color: #cd7f32; + } +} From e0a4959dc95cb5711f97a6bd63f94e8bf0a793b0 Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Wed, 16 Apr 2014 15:41:11 +0530 Subject: [PATCH 2/9] Sort featured badges by badge type first, followed by grant count. --- app/models/user.rb | 4 ++++ app/serializers/user_serializer.rb | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 23f3daa09d..de6db4cc33 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -492,6 +492,10 @@ class User < ActiveRecord::Base Summarize.new(bio_cooked).summary end + def featured_user_badges + user_badges.joins(:badge).order('badges.badge_type_id ASC, badges.grant_count ASC').includes(:granted_by, badge: :badge_type).limit(3) + end + def self.count_by_signup_date(sinceDaysAgo=30) where('created_at > ?', sinceDaysAgo.days.ago).group('date(created_at)').order('date(created_at)').count end diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index 1431ccd9f8..df35418f94 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -134,9 +134,4 @@ class UserSerializer < BasicUserSerializer def badge_count object.user_badges.count end - - def featured_user_badges - # The three rarest badges this user has received should be featured. - object.user_badges.joins(:badge).order('badges.grant_count ASC').includes(:granted_by, badge: :badge_type).limit(3) - end end From 4c0f85650ec90bc1bbe23d9feb2ad577d6415917 Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Wed, 16 Apr 2014 15:52:21 +0530 Subject: [PATCH 3/9] Display badge count in the user admin page. --- .../javascripts/admin/templates/user_index.js.handlebars | 2 +- app/models/user.rb | 4 ++++ app/serializers/admin_detailed_user_serializer.rb | 3 ++- app/serializers/user_serializer.rb | 3 --- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/admin/templates/user_index.js.handlebars b/app/assets/javascripts/admin/templates/user_index.js.handlebars index bdbdde7619..89ce976275 100644 --- a/app/assets/javascripts/admin/templates/user_index.js.handlebars +++ b/app/assets/javascripts/admin/templates/user_index.js.handlebars @@ -81,7 +81,7 @@
{{i18n admin.badges.title}}
- TODO featured badges + {{i18n badges.badge_count count=badge_count}}
{{#link-to 'adminUser.badges' this class="btn"}}{{i18n admin.badges.edit_badges}}{{/link-to}} diff --git a/app/models/user.rb b/app/models/user.rb index de6db4cc33..238a2a0f6c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -492,6 +492,10 @@ class User < ActiveRecord::Base Summarize.new(bio_cooked).summary end + def badge_count + user_badges.count + end + def featured_user_badges user_badges.joins(:badge).order('badges.badge_type_id ASC, badges.grant_count ASC').includes(:granted_by, badge: :badge_type).limit(3) end diff --git a/app/serializers/admin_detailed_user_serializer.rb b/app/serializers/admin_detailed_user_serializer.rb index 685c34c1c4..32ba08cff3 100644 --- a/app/serializers/admin_detailed_user_serializer.rb +++ b/app/serializers/admin_detailed_user_serializer.rb @@ -15,7 +15,8 @@ class AdminDetailedUserSerializer < AdminUserSerializer :can_delete_all_posts, :can_be_deleted, :suspend_reason, - :primary_group_id + :primary_group_id, + :badge_count has_one :approved_by, serializer: BasicUserSerializer, embed: :objects has_one :api_key, serializer: ApiKeySerializer, embed: :objects diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index df35418f94..fc597762a9 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -131,7 +131,4 @@ class UserSerializer < BasicUserSerializer CategoryUser.lookup(object, :watching).pluck(:category_id) end - def badge_count - object.user_badges.count - end end From de23caa871457f10f31eba7d3927c1136dd04963 Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Wed, 16 Apr 2014 16:04:27 +0530 Subject: [PATCH 4/9] Slightly faster badge system specs. (Shaves off ~100ms) --- spec/controllers/user_badges_controller_spec.rb | 14 +++++--------- spec/models/badge.rb | 3 --- spec/models/badge_type.rb | 2 -- spec/models/user_badge.rb | 4 ---- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/spec/controllers/user_badges_controller_spec.rb b/spec/controllers/user_badges_controller_spec.rb index 9d3fdbf1f4..311d448f41 100644 --- a/spec/controllers/user_badges_controller_spec.rb +++ b/spec/controllers/user_badges_controller_spec.rb @@ -5,9 +5,7 @@ describe UserBadgesController do let(:badge) { Fabricate(:badge) } context 'index' do - before do - @user_badge = BadgeGranter.grant(badge, user) - end + let!(:user_badge) { UserBadge.create(badge: badge, user: user, granted_by: Discourse.system_user, granted_at: Time.now) } it 'requires username to be specified' do expect { xhr :get, :index }.to raise_error @@ -62,21 +60,19 @@ describe UserBadgesController do end context 'destroy' do - before do - @user_badge = BadgeGranter.grant(badge, user) - end + let!(:user_badge) { UserBadge.create(badge: badge, user: user, granted_by: Discourse.system_user, granted_at: Time.now) } it 'checks that the user is authorized to revoke a badge' do - xhr :delete, :destroy, id: @user_badge.id + xhr :delete, :destroy, id: user_badge.id response.status.should == 403 end it 'revokes the badge' do log_in :admin StaffActionLogger.any_instance.expects(:log_badge_revoke).once - xhr :delete, :destroy, id: @user_badge.id + xhr :delete, :destroy, id: user_badge.id response.status.should == 200 - UserBadge.where(id: @user_badge.id).first.should be_nil + UserBadge.where(id: user_badge.id).first.should be_nil end end end diff --git a/spec/models/badge.rb b/spec/models/badge.rb index 8416fc854f..ab8ab50c3f 100644 --- a/spec/models/badge.rb +++ b/spec/models/badge.rb @@ -3,9 +3,6 @@ require_dependency 'badge' describe Badge do - it { should belong_to :badge_type } - it { should have_many(:user_badges).dependent(:destroy) } - context 'validations' do before(:each) { Fabricate(:badge) } diff --git a/spec/models/badge_type.rb b/spec/models/badge_type.rb index bc716b857e..9f152f0d8a 100644 --- a/spec/models/badge_type.rb +++ b/spec/models/badge_type.rb @@ -3,8 +3,6 @@ require_dependency 'badge_type' describe BadgeType do - it { should have_many :badges } - it { should validate_presence_of :name } it { should validate_uniqueness_of :name } it { should validate_presence_of :color_hexcode } diff --git a/spec/models/user_badge.rb b/spec/models/user_badge.rb index 383db76a10..7c23305117 100644 --- a/spec/models/user_badge.rb +++ b/spec/models/user_badge.rb @@ -3,10 +3,6 @@ require_dependency 'user_badge' describe UserBadge do - it { should belong_to :badge } - it { should belong_to :user } - it { should belong_to :granted_by } - context 'validations' do before(:each) { BadgeGranter.grant(Fabricate(:badge), Fabricate(:user)) } From acfcf0b64e1fa77b665903ea3f3e9570fc0f7c07 Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Wed, 16 Apr 2014 18:42:06 +0530 Subject: [PATCH 5/9] Add /badges route that lists all defined badges. --- .../javascripts/discourse/models/badge.js | 2 +- .../discourse/routes/application_routes.js | 2 ++ .../discourse/routes/badges_route.js | 13 +++++++ .../discourse/templates/badges.js.handlebars | 13 +++++++ .../stylesheets/desktop/user-badges.scss | 34 +++++++++++++++++-- app/controllers/admin/badges_controller.rb | 5 --- app/controllers/badges_controller.rb | 6 ++++ app/serializers/badge_serializer.rb | 2 +- config/locales/client.en.yml | 4 +++ config/routes.rb | 1 + .../admin/badges_controller_spec.rb | 12 ------- spec/controllers/badges_controller_spec.rb | 15 ++++++++ 12 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 app/assets/javascripts/discourse/routes/badges_route.js create mode 100644 app/assets/javascripts/discourse/templates/badges.js.handlebars create mode 100644 app/controllers/badges_controller.rb create mode 100644 spec/controllers/badges_controller_spec.rb diff --git a/app/assets/javascripts/discourse/models/badge.js b/app/assets/javascripts/discourse/models/badge.js index 3a4ad3b875..7fa14bf614 100644 --- a/app/assets/javascripts/discourse/models/badge.js +++ b/app/assets/javascripts/discourse/models/badge.js @@ -164,7 +164,7 @@ Discourse.Badge.reopenClass({ @returns {Promise} a promise that resolves to an array of `Discourse.Badge` **/ findAll: function() { - return Discourse.ajax('/admin/badges').then(function(badgesJson) { + return Discourse.ajax('/badges.json').then(function(badgesJson) { return Discourse.Badge.createFromJson(badgesJson); }); } diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js index 0dcc467aeb..53fc50ef30 100644 --- a/app/assets/javascripts/discourse/routes/application_routes.js +++ b/app/assets/javascripts/discourse/routes/application_routes.js @@ -94,4 +94,6 @@ Discourse.Route.buildRoutes(function() { this.route('signup', {path: '/signup'}); this.route('login', {path: '/login'}); + + this.route('badges'); }); diff --git a/app/assets/javascripts/discourse/routes/badges_route.js b/app/assets/javascripts/discourse/routes/badges_route.js new file mode 100644 index 0000000000..4852fc4bea --- /dev/null +++ b/app/assets/javascripts/discourse/routes/badges_route.js @@ -0,0 +1,13 @@ +/** + Shows a list of all badges. + + @class BadgesRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ +Discourse.BadgesRoute = Discourse.Route.extend({ + model: function() { + return Discourse.Badge.findAll(); + } +}); diff --git a/app/assets/javascripts/discourse/templates/badges.js.handlebars b/app/assets/javascripts/discourse/templates/badges.js.handlebars new file mode 100644 index 0000000000..334ce7c59d --- /dev/null +++ b/app/assets/javascripts/discourse/templates/badges.js.handlebars @@ -0,0 +1,13 @@ +
+

{{i18n badges.title}}

+ + + {{#each}} + + + + + + {{/each}} +
{{user-badge badge=this}}{{description}}{{i18n badges.awarded count=grant_count}}
+
diff --git a/app/assets/stylesheets/desktop/user-badges.scss b/app/assets/stylesheets/desktop/user-badges.scss index 66b4ac2024..9141d4f0ec 100644 --- a/app/assets/stylesheets/desktop/user-badges.scss +++ b/app/assets/stylesheets/desktop/user-badges.scss @@ -1,14 +1,16 @@ .user-badge { padding: 3px 8px; border: 1px solid $secondary-border-color; - font-size: 12px; + font-size: $base-font-size * 0.86; line-height: 16px; margin: 0; display: inline-block; + background-color: $primary_background_color; .fa { - padding-right: 5px; - font-size: 16px; + padding-right: 3px; + font-size: 1.4em; + vertical-align: bottom; } &.badge-type-gold .fa { @@ -23,3 +25,29 @@ color: #cd7f32; } } + +table.badges-listing { + margin-top: 20px; + border-bottom: 1px solid $primary-border-color; + + .user-badge { + font-size: $base-font-size; + } + + td { + padding: 10px 20px; + } + + td.grant-count { + font-size: 0.8em; + color: $secondary_text_color; + } + + td.badge, td.grant-count { + white-space: nowrap; + } + + tr { + border-top: 1px solid $primary-border-color; + } +} diff --git a/app/controllers/admin/badges_controller.rb b/app/controllers/admin/badges_controller.rb index 1cfb1ef8ed..92b119af80 100644 --- a/app/controllers/admin/badges_controller.rb +++ b/app/controllers/admin/badges_controller.rb @@ -1,9 +1,4 @@ class Admin::BadgesController < Admin::AdminController - def index - badges = Badge.all.to_a - render_serialized(badges, BadgeSerializer, root: "badges") - end - def badge_types badge_types = BadgeType.all.to_a render_serialized(badge_types, BadgeTypeSerializer, root: "badge_types") diff --git a/app/controllers/badges_controller.rb b/app/controllers/badges_controller.rb new file mode 100644 index 0000000000..c256cbed60 --- /dev/null +++ b/app/controllers/badges_controller.rb @@ -0,0 +1,6 @@ +class BadgesController < ApplicationController + def index + badges = Badge.all.to_a + render_serialized(badges, BadgeSerializer, root: "badges") + end +end diff --git a/app/serializers/badge_serializer.rb b/app/serializers/badge_serializer.rb index 05173cc30c..34b7295984 100644 --- a/app/serializers/badge_serializer.rb +++ b/app/serializers/badge_serializer.rb @@ -1,5 +1,5 @@ class BadgeSerializer < ApplicationSerializer - attributes :id, :name, :description + attributes :id, :name, :description, :grant_count has_one :badge_type end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 0820df06c5..f35abee763 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1768,12 +1768,16 @@ en: mark_watching: 'm then w Mark topic as watching' badges: + title: Badges badge_count: one: "1 Badge" other: "%{count} Badges" more_badges: one: "+1 More" other: "+%{count} More" + awarded: + one: "1 awarded" + other: "%{count} awarded" example_badge: name: Example Badge description: This is a generic example badge. diff --git a/config/routes.rb b/config/routes.rb index 89fd083787..3afb6af372 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -242,6 +242,7 @@ Discourse::Application.routes.draw do end resources :user_actions + resources :badges, only: [:index] resources :user_badges, only: [:index, :create, :destroy] # We've renamed popular to latest. If people access it we want a permanent redirect. diff --git a/spec/controllers/admin/badges_controller_spec.rb b/spec/controllers/admin/badges_controller_spec.rb index 5359c278f7..62674af346 100644 --- a/spec/controllers/admin/badges_controller_spec.rb +++ b/spec/controllers/admin/badges_controller_spec.rb @@ -9,18 +9,6 @@ describe Admin::BadgesController do let!(:user) { log_in(:admin) } let!(:badge) { Fabricate(:badge) } - context '.index' do - it 'returns success' do - xhr :get, :index - response.should be_success - end - - it 'returns JSON' do - xhr :get, :index - ::JSON.parse(response.body)["badges"].should be_present - end - end - context '.badge_types' do it 'returns success' do xhr :get, :badge_types diff --git a/spec/controllers/badges_controller_spec.rb b/spec/controllers/badges_controller_spec.rb new file mode 100644 index 0000000000..60bd0ed368 --- /dev/null +++ b/spec/controllers/badges_controller_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe BadgesController do + let!(:badge) { Fabricate(:badge) } + + context 'index' do + it 'should return a list of all badges' do + xhr :get, :index + + response.status.should == 200 + parsed = JSON.parse(response.body) + parsed["badges"].length.should == 1 + end + end +end From 3136217fc105cca1949f0d7e6d28196148de8e86 Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Wed, 16 Apr 2014 20:26:11 +0530 Subject: [PATCH 6/9] Add badge page. --- .../javascripts/discourse/models/badge.js | 13 +++++++++ .../discourse/models/user_badge.js | 17 ++++++++++++ .../discourse/routes/application_routes.js | 4 ++- ...{badges_route.js => badges_index_route.js} | 4 +-- .../discourse/routes/badges_show_route.js | 24 +++++++++++++++++ .../index.js.handlebars} | 0 .../templates/badges/show.js.handlebars | 27 +++++++++++++++++++ .../components/user-badge.js.handlebars | 10 ++++--- .../stylesheets/desktop/user-badges.scss | 3 ++- app/controllers/badges_controller.rb | 6 +++++ app/controllers/user_badges_controller.rb | 12 ++++++--- app/serializers/user_badge_serializer.rb | 1 + config/routes.rb | 1 + spec/controllers/badges_controller_spec.rb | 9 +++++++ .../user_badges_controller_spec.rb | 12 +++++++-- test/javascripts/models/user_badge_test.js | 8 ++++++ 16 files changed, 138 insertions(+), 13 deletions(-) rename app/assets/javascripts/discourse/routes/{badges_route.js => badges_index_route.js} (68%) create mode 100644 app/assets/javascripts/discourse/routes/badges_show_route.js rename app/assets/javascripts/discourse/templates/{badges.js.handlebars => badges/index.js.handlebars} (100%) create mode 100644 app/assets/javascripts/discourse/templates/badges/show.js.handlebars diff --git a/app/assets/javascripts/discourse/models/badge.js b/app/assets/javascripts/discourse/models/badge.js index 7fa14bf614..4bc61a95ec 100644 --- a/app/assets/javascripts/discourse/models/badge.js +++ b/app/assets/javascripts/discourse/models/badge.js @@ -167,5 +167,18 @@ Discourse.Badge.reopenClass({ return Discourse.ajax('/badges.json').then(function(badgesJson) { return Discourse.Badge.createFromJson(badgesJson); }); + }, + + /** + Returns a `Discourse.Badge` that has the given ID. + + @method findById + @param {Number} id ID of the badge + @returns {Promise} a promise that resolves to a `Discourse.Badge` + **/ + findById: function(id) { + return Discourse.ajax("/badges/" + id).then(function(badgeJson) { + return Discourse.Badge.createFromJson(badgeJson); + }); } }); diff --git a/app/assets/javascripts/discourse/models/user_badge.js b/app/assets/javascripts/discourse/models/user_badge.js index 3d521c1fa1..b19a3a25a7 100644 --- a/app/assets/javascripts/discourse/models/user_badge.js +++ b/app/assets/javascripts/discourse/models/user_badge.js @@ -54,6 +54,9 @@ Discourse.UserBadge.reopenClass({ userBadges = userBadges.map(function(userBadgeJson) { var userBadge = Discourse.UserBadge.create(userBadgeJson); userBadge.set('badge', badges[userBadge.get('badge_id')]); + if (userBadge.get('user_id')) { + userBadge.set('user', users[userBadge.get('user_id')]); + } if (userBadge.get('granted_by_id')) { userBadge.set('granted_by', users[userBadge.get('granted_by_id')]); } @@ -71,6 +74,7 @@ Discourse.UserBadge.reopenClass({ Find all badges for a given username. @method findByUsername + @param {String} username @returns {Promise} a promise that resolves to an array of `Discourse.UserBadge`. **/ findByUsername: function(username) { @@ -79,6 +83,19 @@ Discourse.UserBadge.reopenClass({ }); }, + /** + Find all badge grants for a given badge ID. + + @method findById + @param {String} badgeId + @returns {Promise} a promise that resolves to an array of `Discourse.UserBadge`. + **/ + findByBadgeId: function(badgeId) { + return Discourse.ajax("/user_badges.json?badge_id=" + badgeId).then(function(json) { + return Discourse.UserBadge.createFromJson(json); + }); + }, + /** Grant the badge having id `badgeId` to the user identified by `username`. diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js index 53fc50ef30..261b929174 100644 --- a/app/assets/javascripts/discourse/routes/application_routes.js +++ b/app/assets/javascripts/discourse/routes/application_routes.js @@ -95,5 +95,7 @@ Discourse.Route.buildRoutes(function() { this.route('signup', {path: '/signup'}); this.route('login', {path: '/login'}); - this.route('badges'); + this.resource('badges', function() { + this.route('show', {path: '/:id/:slug'}); + }); }); diff --git a/app/assets/javascripts/discourse/routes/badges_route.js b/app/assets/javascripts/discourse/routes/badges_index_route.js similarity index 68% rename from app/assets/javascripts/discourse/routes/badges_route.js rename to app/assets/javascripts/discourse/routes/badges_index_route.js index 4852fc4bea..6563af0d77 100644 --- a/app/assets/javascripts/discourse/routes/badges_route.js +++ b/app/assets/javascripts/discourse/routes/badges_index_route.js @@ -1,12 +1,12 @@ /** Shows a list of all badges. - @class BadgesRoute + @class BadgesIndexRoute @extends Discourse.Route @namespace Discourse @module Discourse **/ -Discourse.BadgesRoute = Discourse.Route.extend({ +Discourse.BadgesIndexRoute = Discourse.Route.extend({ model: function() { return Discourse.Badge.findAll(); } diff --git a/app/assets/javascripts/discourse/routes/badges_show_route.js b/app/assets/javascripts/discourse/routes/badges_show_route.js new file mode 100644 index 0000000000..d076932504 --- /dev/null +++ b/app/assets/javascripts/discourse/routes/badges_show_route.js @@ -0,0 +1,24 @@ +/** + Shows a particular badge. + + @class BadgesShowRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ +Discourse.BadgesShowRoute = Ember.Route.extend({ + serialize: function(model) { + return {id: model.get('id'), slug: model.get('name').replace(/[^A-Za-z0-9_]+/g, '-').toLowerCase()}; + }, + + model: function(params) { + return Discourse.Badge.findById(params.id); + }, + + setupController: function(controller, model) { + Discourse.UserBadge.findByBadgeId(model.get('id')).then(function(userBadges) { + controller.set('userBadges', userBadges); + }); + controller.set('model', model); + } +}); diff --git a/app/assets/javascripts/discourse/templates/badges.js.handlebars b/app/assets/javascripts/discourse/templates/badges/index.js.handlebars similarity index 100% rename from app/assets/javascripts/discourse/templates/badges.js.handlebars rename to app/assets/javascripts/discourse/templates/badges/index.js.handlebars diff --git a/app/assets/javascripts/discourse/templates/badges/show.js.handlebars b/app/assets/javascripts/discourse/templates/badges/show.js.handlebars new file mode 100644 index 0000000000..ce161dcf02 --- /dev/null +++ b/app/assets/javascripts/discourse/templates/badges/show.js.handlebars @@ -0,0 +1,27 @@ +
+

+ {{#link-to 'badges.index'}}{{i18n badges.title}}{{/link-to}} + + {{name}} +

+ + + + + + + +
{{user-badge badge=this}}{{description}}{{i18n badges.awarded count=grant_count}}
+ + {{#if userBadges}} +

{{i18n users}}

+
+ {{#each userBadges}} + {{#link-to 'userActivity' user}} + {{avatar user imageSize="large"}} + {{/link-to}} + {{/each}} + {{else}} +
{{i18n loading}}
+ {{/if}} +
diff --git a/app/assets/javascripts/discourse/templates/components/user-badge.js.handlebars b/app/assets/javascripts/discourse/templates/components/user-badge.js.handlebars index b934b3b1fa..ca2070b7e3 100644 --- a/app/assets/javascripts/discourse/templates/components/user-badge.js.handlebars +++ b/app/assets/javascripts/discourse/templates/components/user-badge.js.handlebars @@ -1,4 +1,6 @@ - - - {{badge.name}} - +{{#link-to 'badges.show' badge}} + + + {{badge.name}} + +{{/link-to}} diff --git a/app/assets/stylesheets/desktop/user-badges.scss b/app/assets/stylesheets/desktop/user-badges.scss index 9141d4f0ec..941e715a2a 100644 --- a/app/assets/stylesheets/desktop/user-badges.scss +++ b/app/assets/stylesheets/desktop/user-badges.scss @@ -1,5 +1,6 @@ .user-badge { padding: 3px 8px; + color: $primary_text_color; border: 1px solid $secondary-border-color; font-size: $base-font-size * 0.86; line-height: 16px; @@ -27,7 +28,7 @@ } table.badges-listing { - margin-top: 20px; + margin: 20px 0; border-bottom: 1px solid $primary-border-color; .user-badge { diff --git a/app/controllers/badges_controller.rb b/app/controllers/badges_controller.rb index c256cbed60..a8908afd4f 100644 --- a/app/controllers/badges_controller.rb +++ b/app/controllers/badges_controller.rb @@ -3,4 +3,10 @@ class BadgesController < ApplicationController badges = Badge.all.to_a render_serialized(badges, BadgeSerializer, root: "badges") end + + def show + params.require(:id) + badge = Badge.find(params[:id]) + render_serialized(badge, BadgeSerializer, root: "badge") + end end diff --git a/app/controllers/user_badges_controller.rb b/app/controllers/user_badges_controller.rb index ef5bbf3345..daba1ddc9f 100644 --- a/app/controllers/user_badges_controller.rb +++ b/app/controllers/user_badges_controller.rb @@ -1,8 +1,14 @@ class UserBadgesController < ApplicationController def index - params.require(:username) - user = fetch_user_from_params - render_serialized(user.user_badges, UserBadgeSerializer, root: "user_badges") + params.permit(:username) + if params[:username] + user = fetch_user_from_params + user_badges = user.user_badges + else + badge = fetch_badge_from_params + user_badges = badge.user_badges.order('granted_at DESC').limit(20).to_a + end + render_serialized(user_badges, UserBadgeSerializer, root: "user_badges") end def create diff --git a/app/serializers/user_badge_serializer.rb b/app/serializers/user_badge_serializer.rb index d91dfb9162..eda18b11ea 100644 --- a/app/serializers/user_badge_serializer.rb +++ b/app/serializers/user_badge_serializer.rb @@ -1,6 +1,7 @@ class UserBadgeSerializer < ApplicationSerializer attributes :id, :granted_at + has_one :user has_one :badge has_one :granted_by, serializer: BasicUserSerializer, root: :users end diff --git a/config/routes.rb b/config/routes.rb index 3afb6af372..2bf6bfa356 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -243,6 +243,7 @@ Discourse::Application.routes.draw do resources :user_actions resources :badges, only: [:index] + get "/badges/:id(/:slug)" => "badges#show" resources :user_badges, only: [:index, :create, :destroy] # We've renamed popular to latest. If people access it we want a permanent redirect. diff --git a/spec/controllers/badges_controller_spec.rb b/spec/controllers/badges_controller_spec.rb index 60bd0ed368..945d641512 100644 --- a/spec/controllers/badges_controller_spec.rb +++ b/spec/controllers/badges_controller_spec.rb @@ -12,4 +12,13 @@ describe BadgesController do parsed["badges"].length.should == 1 end end + + context 'show' do + it "should return a badge" do + xhr :get, :show, id: badge.id + response.status.should == 200 + parsed = JSON.parse(response.body) + parsed["badge"].should be_present + end + end end diff --git a/spec/controllers/user_badges_controller_spec.rb b/spec/controllers/user_badges_controller_spec.rb index 311d448f41..87fc240e6e 100644 --- a/spec/controllers/user_badges_controller_spec.rb +++ b/spec/controllers/user_badges_controller_spec.rb @@ -7,17 +7,25 @@ describe UserBadgesController do context 'index' do let!(:user_badge) { UserBadge.create(badge: badge, user: user, granted_by: Discourse.system_user, granted_at: Time.now) } - it 'requires username to be specified' do + it 'requires username or badge_id to be specified' do expect { xhr :get, :index }.to raise_error end - it 'returns the user\'s badges' do + it 'returns user_badges for a user' do xhr :get, :index, username: user.username response.status.should == 200 parsed = JSON.parse(response.body) parsed["user_badges"].length.should == 1 end + + it 'returns user_badges for a badge' do + xhr :get, :index, badge_id: badge.id + + response.status.should == 200 + parsed = JSON.parse(response.body) + parsed["user_badges"].length.should == 1 + end end context 'create' do diff --git a/test/javascripts/models/user_badge_test.js b/test/javascripts/models/user_badge_test.js index eb56100df9..9c7c94de64 100644 --- a/test/javascripts/models/user_badge_test.js +++ b/test/javascripts/models/user_badge_test.js @@ -25,6 +25,14 @@ test('findByUsername', function() { ok(Discourse.ajax.calledOnce, "makes an AJAX call"); }); +test('findByBadgeId', function() { + this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve(multipleBadgesJson)); + Discourse.UserBadge.findByBadgeId(880).then(function(badges) { + ok(Array.isArray(badges), "returns an array"); + }); + ok(Discourse.ajax.calledOnce, "makes an AJAX call"); +}); + test('grant', function() { this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve(singleBadgeJson)); Discourse.UserBadge.grant(1, "username").then(function(userBadge) { From b55734da911227e2db53d13e49fef98894357ee6 Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Thu, 17 Apr 2014 00:19:28 +0530 Subject: [PATCH 7/9] Add badges tab to user profile. --- .../discourse/controllers/user_controller.js | 4 +++ .../discourse/routes/application_routes.js | 2 ++ .../discourse/routes/user_badges_route.js | 25 +++++++++++++++++++ .../templates/user/badges.js.handlebars | 5 ++++ .../templates/user/user.js.handlebars | 10 ++++++++ .../stylesheets/desktop/user-badges.scss | 21 ++++++++++++++++ config/routes.rb | 1 + 7 files changed, 68 insertions(+) create mode 100644 app/assets/javascripts/discourse/routes/user_badges_route.js create mode 100644 app/assets/javascripts/discourse/templates/user/badges.js.handlebars diff --git a/app/assets/javascripts/discourse/controllers/user_controller.js b/app/assets/javascripts/discourse/controllers/user_controller.js index 65b0362744..1054198763 100644 --- a/app/assets/javascripts/discourse/controllers/user_controller.js +++ b/app/assets/javascripts/discourse/controllers/user_controller.js @@ -18,6 +18,10 @@ Discourse.UserController = Discourse.ObjectController.extend({ return this.get('viewingSelf') || Discourse.User.currentProp('admin'); }.property('viewingSelf'), + showBadges: function() { + return Discourse.SiteSettings.enable_badges; + }.property(), + privateMessageView: function() { return (this.get('userActionType') === Discourse.UserAction.TYPES.messages_sent) || (this.get('userActionType') === Discourse.UserAction.TYPES.messages_received); diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js index 261b929174..fb739f5858 100644 --- a/app/assets/javascripts/discourse/routes/application_routes.js +++ b/app/assets/javascripts/discourse/routes/application_routes.js @@ -78,6 +78,8 @@ Discourse.Route.buildRoutes(function() { }); }); + this.route('badges'); + this.resource('userPrivateMessages', { path: '/private-messages' }, function() { this.route('mine'); this.route('unread'); diff --git a/app/assets/javascripts/discourse/routes/user_badges_route.js b/app/assets/javascripts/discourse/routes/user_badges_route.js new file mode 100644 index 0000000000..97ad6ddf92 --- /dev/null +++ b/app/assets/javascripts/discourse/routes/user_badges_route.js @@ -0,0 +1,25 @@ +/** + This route shows a user's badges. + + @class UserBadgesRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ +Discourse.UserBadgesRoute = Discourse.Route.extend({ + model: function() { + return Discourse.UserBadge.findByUsername(this.modelFor('user').get('username_lower')); + }, + + setupController: function(controller, model) { + this.controllerFor('user').set('indexStream', false); + if (this.controllerFor('user_activity').get('content')) { + this.controllerFor('user_activity').set('userActionType', -1); + } + controller.set('model', model); + }, + + renderTemplate: function() { + this.render('user/badges', {into: 'user', outlet: 'userOutlet'}); + } +}); diff --git a/app/assets/javascripts/discourse/templates/user/badges.js.handlebars b/app/assets/javascripts/discourse/templates/user/badges.js.handlebars new file mode 100644 index 0000000000..6cbf2003cf --- /dev/null +++ b/app/assets/javascripts/discourse/templates/user/badges.js.handlebars @@ -0,0 +1,5 @@ +
+ {{#each}} + {{user-badge badge=badge}} + {{/each}} +
diff --git a/app/assets/javascripts/discourse/templates/user/user.js.handlebars b/app/assets/javascripts/discourse/templates/user/user.js.handlebars index 882f9999c0..0cf25536aa 100644 --- a/app/assets/javascripts/discourse/templates/user/user.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/user.js.handlebars @@ -13,6 +13,16 @@ {{#each stat in statsExcludingPms}} {{discourse-activity-filter content=stat user=model userActionType=userActionType indexStream=indexStream}} {{/each}} + {{#if showBadges}} + {{#link-to 'user.badges' tagName="li"}} + {{#link-to 'user.badges'}} + + {{i18n badges.title}} + ({{badge_count}}) + + {{/link-to}} + {{/link-to}} + {{/if}} {{#if canSeePrivateMessages}} diff --git a/app/assets/stylesheets/desktop/user-badges.scss b/app/assets/stylesheets/desktop/user-badges.scss index 941e715a2a..2be02acb1f 100644 --- a/app/assets/stylesheets/desktop/user-badges.scss +++ b/app/assets/stylesheets/desktop/user-badges.scss @@ -1,3 +1,4 @@ +/* Default badge styles. */ .user-badge { padding: 3px 8px; color: $primary_text_color; @@ -27,6 +28,26 @@ } } +/* User badge listing. */ +.user-badges-list { + text-align: center; + + .user-badge { + max-width: 80px; + text-align: center; + vertical-align: top; + margin: 10px; + border: none; + + .fa { + display: block; + font-size: 50px; + margin-bottom: 5px; + } + } +} + +/* Badge listing in /badges. */ table.badges-listing { margin: 20px 0; border-bottom: 1px solid $primary-border-color; diff --git a/config/routes.rb b/config/routes.rb index 2bf6bfa356..bb3b6e64b7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -195,6 +195,7 @@ Discourse::Application.routes.draw do post "users/:username/send_activation_email" => "users#send_activation_email", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/activity" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/activity/:filter" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/badges" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} delete "users/:username" => "users#destroy", constraints: {username: USERNAME_ROUTE_FORMAT} get "uploads/:site/:id/:sha.:extension" => "uploads#show", constraints: {site: /\w+/, id: /\d+/, sha: /[a-z0-9]{15,16}/i, extension: /\w{2,}/} From 89f45901bcb268d148390da41fae061288f81f0e Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Thu, 17 Apr 2014 01:29:45 +0530 Subject: [PATCH 8/9] Create notification when badge is granted. --- .../discourse/controllers/notification_controller.js | 3 +++ app/models/notification.rb | 2 +- app/services/badge_granter.rb | 10 +++++++++- config/locales/client.en.yml | 1 + config/locales/server.en.yml | 1 + spec/services/badge_granter_spec.rb | 6 ++++-- 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/notification_controller.js b/app/assets/javascripts/discourse/controllers/notification_controller.js index 19db113cad..765ca1d85a 100644 --- a/app/assets/javascripts/discourse/controllers/notification_controller.js +++ b/app/assets/javascripts/discourse/controllers/notification_controller.js @@ -8,6 +8,9 @@ Discourse.NotificationController = Discourse.ObjectController.extend({ }.property(), link: function() { + if (this.get('data.badge_id')) { + return '' + this.get('data.badge_name') + ''; + } if (this.blank("data.topic_title")) { return ""; } diff --git a/app/models/notification.rb b/app/models/notification.rb index 77b53b854b..a1a459e7eb 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -28,7 +28,7 @@ class Notification < ActiveRecord::Base @types ||= Enum.new( :mentioned, :replied, :quoted, :edited, :liked, :private_message, :invited_to_private_message, :invitee_accepted, :posted, :moved_post, - :linked + :linked, :granted_badge ) end diff --git a/app/services/badge_granter.rb b/app/services/badge_granter.rb index 5511cf9f50..53b3d1fb96 100644 --- a/app/services/badge_granter.rb +++ b/app/services/badge_granter.rb @@ -23,6 +23,10 @@ class BadgeGranter if @granted_by != Discourse.system_user StaffActionLogger.new(@granted_by).log_badge_grant(user_badge) end + + @user.notifications.create(notification_type: Notification.types[:granted_badge], + data: { badge_id: @badge.id, + badge_name: @badge.name }.to_json) end end @@ -32,10 +36,14 @@ class BadgeGranter def self.revoke(user_badge, options={}) UserBadge.transaction do user_badge.destroy! - Badge.decrement_counter 'grant_count', user_badge.badge.id + Badge.decrement_counter 'grant_count', user_badge.badge_id if options[:revoked_by] StaffActionLogger.new(options[:revoked_by]).log_badge_revoke(user_badge) end + # Revoke badge -- This is inefficient, but not very easy to optimize unless + # the data hash is converted into a hstore. + notification = user_badge.user.notifications.where(notification_type: Notification.types[:granted_badge]).where("data LIKE ?", "%" + user_badge.badge_id.to_s + "%").select {|n| n.data_hash["badge_id"] == user_badge.badge_id }.first + notification && notification.destroy end end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index f35abee763..c493fe74b7 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -598,6 +598,7 @@ en: moved_post: " {{username}} moved {{link}}" total_flagged: "total flagged posts" linked: " {{username}} {{link}}" + granted_badge: " {{link}}" upload_selector: title: "Add an image" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 37af0e5461..972386d71d 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -888,6 +888,7 @@ en: invited_to_private_message: "%{display_username} invited you to a private message: %{link}" invitee_accepted: "%{display_username} accepted your invitation" linked: "%{display_username} linked you in %{link}" + granted_badge: "You were granted the badge %{link}" search: within_post: "#%{post_number} by %{username}: %{excerpt}" diff --git a/spec/services/badge_granter_spec.rb b/spec/services/badge_granter_spec.rb index 6801bc969d..476bc6a4b4 100644 --- a/spec/services/badge_granter_spec.rb +++ b/spec/services/badge_granter_spec.rb @@ -40,9 +40,10 @@ describe BadgeGranter do user_badge.should_not be_present end - it 'increments grant_count on the badge' do + it 'increments grant_count on the badge and creates a notification' do BadgeGranter.grant(badge, user) badge.reload.grant_count.should eq(1) + user.notifications.where(notification_type: Notification.types[:granted_badge]).first.data_hash["badge_id"].should == badge.id end end @@ -52,12 +53,13 @@ describe BadgeGranter do let(:admin) { Fabricate(:admin) } let!(:user_badge) { BadgeGranter.grant(badge, user) } - it 'revokes the badge and decrements grant_count' do + it 'revokes the badge, deletes the notification and decrements grant_count' do badge.reload.grant_count.should eq(1) StaffActionLogger.any_instance.expects(:log_badge_revoke).with(user_badge) BadgeGranter.revoke(user_badge, revoked_by: admin) UserBadge.where(user: user, badge: badge).first.should_not be_present badge.reload.grant_count.should eq(0) + user.notifications.where(notification_type: Notification.types[:granted_badge]).should be_empty end end From b62606e7f11a92b7c7e74ef0241f2e5746e86b84 Mon Sep 17 00:00:00 2001 From: Vikhyat Korrapati Date: Thu, 17 Apr 2014 05:36:29 +0530 Subject: [PATCH 9/9] Remove color_hexcode column from badge_types. --- app/models/badge_type.rb | 2 -- app/serializers/badge_type_serializer.rb | 2 +- config/locales/server.en.yml | 6 ------ db/fixtures/700_badge_types.rb | 9 +++------ ...140416235757_remove_color_hexcode_from_badge_types.rb | 5 +++++ spec/fabricators/badge_fabricator.rb | 1 - spec/models/badge_type.rb | 1 - test/javascripts/models/badge_test.js | 6 +++--- test/javascripts/models/user_badge_test.js | 4 ++-- 9 files changed, 14 insertions(+), 22 deletions(-) create mode 100644 db/migrate/20140416235757_remove_color_hexcode_from_badge_types.rb diff --git a/app/models/badge_type.rb b/app/models/badge_type.rb index ede4401853..abebf9495d 100644 --- a/app/models/badge_type.rb +++ b/app/models/badge_type.rb @@ -2,7 +2,6 @@ class BadgeType < ActiveRecord::Base has_many :badges validates :name, presence: true, uniqueness: true - validates :color_hexcode, presence: true end # == Schema Information @@ -11,7 +10,6 @@ end # # id :integer not null, primary key # name :string(255) not null -# color_hexcode :string(255) not null # created_at :datetime # updated_at :datetime # diff --git a/app/serializers/badge_type_serializer.rb b/app/serializers/badge_type_serializer.rb index bd6ed272d5..199c99a377 100644 --- a/app/serializers/badge_type_serializer.rb +++ b/app/serializers/badge_type_serializer.rb @@ -1,3 +1,3 @@ class BadgeTypeSerializer < ApplicationSerializer - attributes :id, :name, :color_hexcode + attributes :id, :name end diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 972386d71d..ac2c6bd561 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1475,9 +1475,3 @@ en: message_to_blank: "message.to is blank" text_part_body_blank: "text_part.body is blank" body_blank: "body is blank" - - badges: - types: - gold: Gold - silver: Silver - bronze: Bronze diff --git a/db/fixtures/700_badge_types.rb b/db/fixtures/700_badge_types.rb index 475817e85e..2cdec2b416 100644 --- a/db/fixtures/700_badge_types.rb +++ b/db/fixtures/700_badge_types.rb @@ -1,17 +1,14 @@ BadgeType.seed do |b| b.id = 1 - b.name = I18n.t('badges.types.gold') - b.color_hexcode = "ffd700" + b.name = "Gold" end BadgeType.seed do |b| b.id = 2 - b.name = I18n.t('badges.types.silver') - b.color_hexcode = "c0c0c0" + b.name = "Silver" end BadgeType.seed do |b| b.id = 3 - b.name = I18n.t('badges.types.bronze') - b.color_hexcode = "cd7f32" + b.name = "Bronze" end diff --git a/db/migrate/20140416235757_remove_color_hexcode_from_badge_types.rb b/db/migrate/20140416235757_remove_color_hexcode_from_badge_types.rb new file mode 100644 index 0000000000..9a19c17a8f --- /dev/null +++ b/db/migrate/20140416235757_remove_color_hexcode_from_badge_types.rb @@ -0,0 +1,5 @@ +class RemoveColorHexcodeFromBadgeTypes < ActiveRecord::Migration + def change + remove_column :badge_types, :color_hexcode, :string + end +end diff --git a/spec/fabricators/badge_fabricator.rb b/spec/fabricators/badge_fabricator.rb index 7ba52d8b4b..d3a5f78d7f 100644 --- a/spec/fabricators/badge_fabricator.rb +++ b/spec/fabricators/badge_fabricator.rb @@ -1,6 +1,5 @@ Fabricator(:badge_type) do name { sequence(:name) {|i| "Silver #{i}" } } - color_hexcode "c0c0c0" end Fabricator(:badge) do diff --git a/spec/models/badge_type.rb b/spec/models/badge_type.rb index 9f152f0d8a..552518e7c7 100644 --- a/spec/models/badge_type.rb +++ b/spec/models/badge_type.rb @@ -5,6 +5,5 @@ describe BadgeType do it { should validate_presence_of :name } it { should validate_uniqueness_of :name } - it { should validate_presence_of :color_hexcode } end diff --git a/test/javascripts/models/badge_test.js b/test/javascripts/models/badge_test.js index dbd1c7549d..a4365e352a 100644 --- a/test/javascripts/models/badge_test.js +++ b/test/javascripts/models/badge_test.js @@ -26,7 +26,7 @@ test('translatedDescription', function() { }); test('createFromJson array', function() { - var badgesJson = {"badge_types":[{"id":6,"name":"Silver 1","color_hexcode":"#c0c0c0"}],"badges":[{"id":1126,"name":"Badge 1","description":null,"badge_type_id":6}]}; + var badgesJson = {"badge_types":[{"id":6,"name":"Silver 1"}],"badges":[{"id":1126,"name":"Badge 1","description":null,"badge_type_id":6}]}; var badges = Discourse.Badge.createFromJson(badgesJson); @@ -36,7 +36,7 @@ test('createFromJson array', function() { }); test('createFromJson single', function() { - var badgeJson = {"badge_types":[{"id":6,"name":"Silver 1","color_hexcode":"#c0c0c0"}],"badge":{"id":1126,"name":"Badge 1","description":null,"badge_type_id":6}}; + var badgeJson = {"badge_types":[{"id":6,"name":"Silver 1"}],"badge":{"id":1126,"name":"Badge 1","description":null,"badge_type_id":6}}; var badge = Discourse.Badge.createFromJson(badgeJson); @@ -44,7 +44,7 @@ test('createFromJson single', function() { }); test('updateFromJson', function() { - var badgeJson = {"badge_types":[{"id":6,"name":"Silver 1","color_hexcode":"#c0c0c0"}],"badge":{"id":1126,"name":"Badge 1","description":null,"badge_type_id":6}}; + var badgeJson = {"badge_types":[{"id":6,"name":"Silver 1"}],"badge":{"id":1126,"name":"Badge 1","description":null,"badge_type_id":6}}; var badge = Discourse.Badge.create({name: "Badge 1"}); badge.updateFromJson(badgeJson); equal(badge.get('id'), 1126, "id is set"); diff --git a/test/javascripts/models/user_badge_test.js b/test/javascripts/models/user_badge_test.js index 9c7c94de64..589d34752e 100644 --- a/test/javascripts/models/user_badge_test.js +++ b/test/javascripts/models/user_badge_test.js @@ -1,7 +1,7 @@ module("Discourse.UserBadge"); -var singleBadgeJson = {"badges":[{"id":874,"name":"Badge 2","description":null,"badge_type_id":7}],"badge_types":[{"id":7,"name":"Silver 2","color_hexcode":"#c0c0c0"}],"users":[{"id":13470,"username":"anne3","avatar_template":"//www.gravatar.com/avatar/a4151b1fd72089c54e2374565a87da7f.png?s={size}\u0026r=pg\u0026d=identicon"}],"user_badge":{"id":665,"granted_at":"2014-03-09T20:30:01.190-04:00","badge_id":874,"granted_by_id":13470}}, - multipleBadgesJson = {"badges":[{"id":880,"name":"Badge 8","description":null,"badge_type_id":13}],"badge_types":[{"id":13,"name":"Silver 8","color_hexcode":"#c0c0c0"}],"users":[],"user_badges":[{"id":668,"granted_at":"2014-03-09T20:30:01.420-04:00","badge_id":880,"granted_by_id":null}]}; +var singleBadgeJson = {"badges":[{"id":874,"name":"Badge 2","description":null,"badge_type_id":7}],"badge_types":[{"id":7,"name":"Silver 2"}],"users":[{"id":13470,"username":"anne3","avatar_template":"//www.gravatar.com/avatar/a4151b1fd72089c54e2374565a87da7f.png?s={size}\u0026r=pg\u0026d=identicon"}],"user_badge":{"id":665,"granted_at":"2014-03-09T20:30:01.190-04:00","badge_id":874,"granted_by_id":13470}}, + multipleBadgesJson = {"badges":[{"id":880,"name":"Badge 8","description":null,"badge_type_id":13}],"badge_types":[{"id":13,"name":"Silver 8"}],"users":[],"user_badges":[{"id":668,"granted_at":"2014-03-09T20:30:01.420-04:00","badge_id":880,"granted_by_id":null}]}; test('createFromJson single', function() { var userBadge = Discourse.UserBadge.createFromJson(singleBadgeJson);