require 'rails_helper' require_dependency 'badge' describe Badge do it { is_expected.to belong_to(:badge_type) } it { is_expected.to belong_to(:badge_grouping) } it { is_expected.to have_many(:user_badges).dependent(:destroy) } it { is_expected.to validate_presence_of(:name) } it { is_expected.to validate_presence_of(:badge_type) } it { is_expected.to validate_uniqueness_of(:name) } it 'has a valid system attribute for new badges' do expect(Badge.create!(name: "test", badge_type_id: 1).system?).to be false end it 'auto translates name' do badge = Badge.find_by_name("Basic User") name_english = badge.name begin I18n.locale = 'fr' expect(badge.display_name).not_to eq(name_english) ensure I18n.locale = :en end end it 'handles changes on badge description and long description correctly for system badges' do badge = Badge.find_by_name("Basic User") badge.description = badge.description.dup badge.long_description = badge.long_description.dup badge.save badge.reload expect(badge[:description]).to eq(nil) expect(badge[:long_description]).to eq(nil) badge.description = "testing" badge.long_description = "testing it" badge.save badge.reload expect(badge[:description]).to eq("testing") expect(badge[:long_description]).to eq("testing it") end it 'can ensure consistency' do b = Badge.first b.grant_count = 100 b.save UserBadge.create!(user_id: -100, badge_id: b.id, granted_at: 1.minute.ago, granted_by_id: -1) UserBadge.create!(user_id: User.first.id, badge_id: b.id, granted_at: 1.minute.ago, granted_by_id: -1) Badge.ensure_consistency! b.reload expect(b.grant_count).to eq(1) end describe '#manually_grantable?' do let(:badge) { Fabricate(:badge, name: 'Test Badge') } subject { badge.manually_grantable? } context 'when system badge' do before { badge.system = true } it { is_expected.to be false } end context 'when has query' do before { badge.query = 'SELECT id FROM users' } it { is_expected.to be false } end context 'when neither system nor has query' do before { badge.update_columns(system: false, query: nil) } it { is_expected.to be true } end end describe '.i18n_name' do it 'transforms to lower case letters, and replaces spaces with underscores' do expect(Badge.i18n_name('Basic User')).to eq('basic_user') end end describe '.display_name' do it 'fetches from translations when i18n_name key exists' do expect(Badge.display_name('basic_user')).to eq('Basic') expect(Badge.display_name('Basic User')).to eq('Basic') end it 'fallbacks to argument value when translation does not exist' do expect(Badge.display_name('Not In Translations')).to eq('Not In Translations') end end context "PopularLink badge" do let(:popular_link_badge) do Badge.find(Badge::PopularLink) end before do popular_link_badge.query = BadgeQueries.linking_badge(2) popular_link_badge.save! end it "is awarded" do post = create_post(raw: "https://www.discourse.org/") TopicLinkClick.create_from(url: "https://www.discourse.org/", post_id: post.id, topic_id: post.topic.id, ip: "192.168.0.100") BadgeGranter.backfill(popular_link_badge) expect(UserBadge.where(user_id: post.user.id, badge_id: Badge::PopularLink).count).to eq(0) TopicLinkClick.create_from(url: "https://www.discourse.org/", post_id: post.id, topic_id: post.topic.id, ip: "192.168.0.101") BadgeGranter.backfill(popular_link_badge) expect(UserBadge.where(user_id: post.user.id, badge_id: Badge::PopularLink).count).to eq(1) end it "is not awarded for links in a restricted category" do category = Fabricate(:category) post = create_post(raw: "https://www.discourse.org/", category: category) category.set_permissions({}) category.save! TopicLinkClick.create_from(url: "https://www.discourse.org/", post_id: post.id, topic_id: post.topic.id, ip: "192.168.0.100") TopicLinkClick.create_from(url: "https://www.discourse.org/", post_id: post.id, topic_id: post.topic.id, ip: "192.168.0.101") BadgeGranter.backfill(popular_link_badge) expect(UserBadge.where(user_id: post.user.id, badge_id: Badge::PopularLink).count).to eq(0) end end end