diff --git a/app/models/topic_list.rb b/app/models/topic_list.rb index e0b3fd8353..4a56c86d01 100644 --- a/app/models/topic_list.rb +++ b/app/models/topic_list.rb @@ -6,6 +6,25 @@ class TopicList cattr_accessor :preloaded_custom_fields self.preloaded_custom_fields = Set.new + def self.on_preload(&blk) + (@preload ||= Set.new) << blk + end + + def self.cancel_preload(&blk) + if @preload + @preload.delete blk + if @preload.length == 0 + @preload = nil + end + end + end + + def self.preload(topics) + if @preload + @preload.each{|preload| preload.call(topics)} + end + end + attr_accessor :more_topics_url, :prev_topics_url, :draft, @@ -97,6 +116,8 @@ class TopicList Topic.preload_custom_fields(@topics, preloaded_custom_fields) end + TopicList.preload(@topics) + @topics end diff --git a/app/models/user_auth_token.rb b/app/models/user_auth_token.rb index 02366dd1f9..23acf4360d 100644 --- a/app/models/user_auth_token.rb +++ b/app/models/user_auth_token.rb @@ -72,11 +72,16 @@ class UserAuthToken < ActiveRecord::Base end if mark_seen && user_token && !user_token.auth_token_seen && user_token.auth_token == token - user_token.update_columns(auth_token_seen: true) + # we must protect against concurrency issues here + changed_rows = UserAuthToken.where(id: user_token.id, auth_token: token).update_all(auth_token_seen: true) + if changed_rows == 1 + # not doing a reload so we don't risk loading a rotated token + user_token.auth_token_seen = true + end if SiteSetting.verbose_auth_token_logging UserAuthTokenLog.create( - action: "seen token", + action: changed_rows == 0 ? "seen wrong token" : "seen token", user_auth_token_id: user_token.id, user_id: user_token.user_id, auth_token: user_token.auth_token, diff --git a/lib/email/message_builder.rb b/lib/email/message_builder.rb index f1d247239f..3a2a6b1756 100644 --- a/lib/email/message_builder.rb +++ b/lib/email/message_builder.rb @@ -40,7 +40,7 @@ module Email string = allow_reply_by_email? ? "user_notifications.reply_by_email" : "user_notifications.visit_link_to_respond" string << "_pm" if @opts[:private_reply] end - @template_args[:respond_instructions] = "-- \n" + I18n.t(string, @template_args) + @template_args[:respond_instructions] = "---\n" + I18n.t(string, @template_args) end if @opts[:add_unsubscribe_link] diff --git a/lib/tasks/docker.rake b/lib/tasks/docker.rake index 8e847c698f..1c48a7e1b7 100644 --- a/lib/tasks/docker.rake +++ b/lib/tasks/docker.rake @@ -38,7 +38,7 @@ task 'docker:test' do @good &&= run_or_fail("eslint --ext .es6 app/assets/javascripts") @good &&= run_or_fail("eslint --ext .es6 test/javascripts") @good &&= run_or_fail("eslint test/javascripts") - @good &&= run_or_fail("bundle exec rake qunit:test") + @good &&= run_or_fail("bundle exec rake qunit:test['200000']") end ensure diff --git a/lib/validators/password_validator.rb b/lib/validators/password_validator.rb index ea1bdec5cb..ced6b2f990 100644 --- a/lib/validators/password_validator.rb +++ b/lib/validators/password_validator.rb @@ -18,7 +18,7 @@ class PasswordValidator < ActiveModel::EachValidator record.errors.add(attribute, :same_as_current) elsif SiteSetting.block_common_passwords && CommonPasswords.common_password?(value) record.errors.add(attribute, :common) - elsif value.chars.inject(Hash.new(0)) { |h,char| h[char] += 1; h }.reject { |k,v| v > 1 }.size < SiteSetting.password_unique_characters + elsif value.chars.uniq.length < SiteSetting.password_unique_characters record.errors.add(attribute, :unique_characters) end end diff --git a/lib/version.rb b/lib/version.rb index 3326f8a82d..f53d8a83ea 100644 --- a/lib/version.rb +++ b/lib/version.rb @@ -5,7 +5,7 @@ module Discourse MAJOR = 1 MINOR = 8 TINY = 0 - PRE = 'beta5' + PRE = 'beta6' STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end diff --git a/spec/components/validators/password_validator_spec.rb b/spec/components/validators/password_validator_spec.rb index 7dc1b3f4b9..bbccc2f4e3 100644 --- a/spec/components/validators/password_validator_spec.rb +++ b/spec/components/validators/password_validator_spec.rb @@ -93,19 +93,20 @@ describe PasswordValidator do end it "adds an error when there are too few unique characters" do + SiteSetting.password_unique_characters = 6 @password = "aaaaaa5432" validate expect(record.errors[:password]).to include(password_error_message(:unique_characters)) end it "doesn't add an error when there are enough unique characters" do - @password = "aaaaa54321" + @password = "aaaaa54322" validate expect(record.errors[:password]).not_to be_present end it "counts capital letters as different" do - @password = "aaaAaa5432" + @password = "aaaAaa543A" validate expect(record.errors[:password]).not_to be_present end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 7849594d55..47a3246704 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -613,9 +613,9 @@ describe UsersController do auth[:authenticator_name] = 'twitter' auth[:extra_data] = twitter_auth - TwitterUserInfo.expects(:create) - post_user + + expect(TwitterUserInfo.count).to eq(1) end end end diff --git a/spec/models/topic_list_spec.rb b/spec/models/topic_list_spec.rb index 319137f051..29ea180008 100644 --- a/spec/models/topic_list_spec.rb +++ b/spec/models/topic_list_spec.rb @@ -1,7 +1,12 @@ require 'rails_helper' describe TopicList do - let!(:topic) { Fabricate(:topic) } + let!(:topic) { + t = Fabricate(:topic) + t.allowed_user_ids = [t.user.id] + t + } + let(:user) { topic.user } let(:topic_list) { TopicList.new("liked", user, [topic]) } @@ -23,6 +28,23 @@ describe TopicList do end end + context "preload" do + it "allows preloading of data" do + preloaded_topic = false + preloader = lambda do |topics| + expect(topics.length).to eq(1) + preloaded_topic = true + end + + TopicList.on_preload(&preloader) + + topic_list.topics + expect(preloaded_topic).to eq(true) + + TopicList.cancel_preload(&preloader) + end + end + context "DiscourseTagging enabled" do before do SiteSetting.tagging_enabled = true