diff --git a/app/models/post_action.rb b/app/models/post_action.rb index 933d6ddd3..801155df0 100644 --- a/app/models/post_action.rb +++ b/app/models/post_action.rb @@ -96,10 +96,10 @@ class PostAction < ActiveRecord::Base return unless opts[:message] && [:notify_moderators, :notify_user].include?(post_action_type) - target_group_names, target_usernames = nil + target_usernames = nil if post_action_type == :notify_moderators - target_group_names = target_moderators + target_usernames = "community" else target_usernames = post.user.username end @@ -111,10 +111,9 @@ class PostAction < ActiveRecord::Base subtype = post_action_type == :notify_moderators ? TopicSubtype.notify_moderators : TopicSubtype.notify_user - if target_usernames.present? || target_group_names.present? + if target_usernames.present? PostCreator.new(user, target_usernames: target_usernames, - target_group_names: target_group_names, archetype: Archetype.private_message, subtype: subtype, title: title, diff --git a/app/models/report.rb b/app/models/report.rb index bfd8dd397..1df58560c 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -38,7 +38,7 @@ class Report end def self.report_signups(report) - report_about report, User, :count_by_signup_date + report_about report, User.real, :count_by_signup_date end def self.report_topics(report) @@ -76,7 +76,7 @@ class Report def self.report_users_by_trust_level(report) report.data = [] - User.counts_by_trust_level.each do |level, count| + User.real.group('trust_level').count.each do |level, count| report.data << {x: level.to_i, y: count} end end diff --git a/app/models/user.rb b/app/models/user.rb index f4b8d9a32..9e95c50bf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -76,6 +76,8 @@ class User < ActiveRecord::Base scope :blocked, -> { where(blocked: true) } # no index scope :banned, -> { where('banned_till IS NOT NULL AND banned_till > ?', Time.zone.now) } # no index scope :not_banned, -> { where('banned_till IS NULL') } + # excluding fake users like the community user + scope :real, -> { where('id > 0') } module NewTopicDuration ALWAYS = -1 @@ -475,10 +477,6 @@ class User < ActiveRecord::Base where('created_at > ?', sinceDaysAgo.days.ago).group('date(created_at)').order('date(created_at)').count end - def self.counts_by_trust_level - group('trust_level').count - end - def update_topic_reply_count self.topic_reply_count = Topic diff --git a/db/fixtures/users.rb b/db/fixtures/users.rb new file mode 100644 index 000000000..75c5472f3 --- /dev/null +++ b/db/fixtures/users.rb @@ -0,0 +1,21 @@ +user = User.where("id <> -1 and username_lower = 'community'").first +if user + user.username = UserNameSuggester.suggest('community') + user.save +end + +User.seed do |u| + u.id = -1 + u.name = 'Community' + u.username = 'community' + u.username_lower = 'community' + u.email = 'no_email' + u.password = SecureRandom.hex + u.bio_raw = 'I am a community user, I clean up the forum and make sure it runs well.' + u.active = true + u.admin = true + u.moderator = true + u.email_direct = false + u.approved = true + u.email_private_messages = false +end diff --git a/db/seeds.rb b/db/seeds.rb deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/discourse.rb b/lib/discourse.rb index c67f5c8a3..e7c01539d 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -131,8 +131,7 @@ module Discourse # Either returns the system_username user or the first admin. def self.system_user user = User.where(username_lower: SiteSetting.system_username).first if SiteSetting.system_username.present? - user = User.admins.order(:id).first if user.blank? - user + user ||= User.admins.real.order(:id).first end def self.store diff --git a/lib/guardian.rb b/lib/guardian.rb index 9b87b82fb..d19d8ec7c 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -40,8 +40,12 @@ class Guardian def is_developer? @user && is_admin? && - Rails.configuration.respond_to?(:developer_emails) && - Rails.configuration.developer_emails.include?(@user.email) + (Rails.env.development? || + ( + Rails.configuration.respond_to?(:developer_emails) && + Rails.configuration.developer_emails.include?(@user.email) + ) + ) end # Can the user see the object? @@ -348,8 +352,12 @@ class Guardian # not secure, or I can see it (not(topic.read_restricted_category?) || can_see_category?(topic.category)) && - # not private, or I am allowed (or an admin) - (not(topic.private_message?) || authenticated? && (topic.all_allowed_users.where(id: @user.id).exists? || is_admin?)) + # NOTE + # At the moment staff can see PMs, there is some talk of restricting this, however + # we still need to allow staff to join PMs for the case of flagging ones + + # not private, or I am allowed (or is staff) + (not(topic.private_message?) || authenticated? && (topic.all_allowed_users.where(id: @user.id).exists? || is_staff?)) end end diff --git a/lib/jobs/enqueue_digest_emails.rb b/lib/jobs/enqueue_digest_emails.rb index 651156ff6..40fc30bf0 100644 --- a/lib/jobs/enqueue_digest_emails.rb +++ b/lib/jobs/enqueue_digest_emails.rb @@ -12,7 +12,8 @@ module Jobs def target_user_ids # Users who want to receive emails and haven't been emailed in the last day - query = User.where(email_digests: true, active: true) + query = User.real + .where(email_digests: true, active: true) .where("COALESCE(last_emailed_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 DAY'::INTERVAL * digest_after_days)") .where("COALESCE(last_seen_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 DAY'::INTERVAL * digest_after_days)") diff --git a/lib/post_creator.rb b/lib/post_creator.rb index f159f8920..1a1427f68 100644 --- a/lib/post_creator.rb +++ b/lib/post_creator.rb @@ -69,6 +69,7 @@ class PostCreator update_topic_stats update_user_counts publish + ensure_in_allowed_users if guardian.is_staff? @post.advance_draft_sequence @post.save_reply_relationships end @@ -104,6 +105,14 @@ class PostCreator protected + def ensure_in_allowed_users + return unless @topic.private_message? + + unless @topic.topic_allowed_users.where(user_id: @user.id).exists? + @topic.topic_allowed_users.create!(user_id: @user.id) + end + end + def secure_group_ids(topic) @secure_group_ids ||= if topic.category && topic.category.read_restricted? topic.category.secure_group_ids diff --git a/spec/components/admin_user_index_query_spec.rb b/spec/components/admin_user_index_query_spec.rb index 689de3cc1..f5b16bec5 100644 --- a/spec/components/admin_user_index_query_spec.rb +++ b/spec/components/admin_user_index_query_spec.rb @@ -2,6 +2,10 @@ require 'spec_helper' require_dependency 'admin_user_index_query' describe AdminUserIndexQuery do + def real_users_count(query) + query.find_users_query.where('users.id > 0').count + end + describe "sql order" do it "has default" do query = ::AdminUserIndexQuery.new({}) @@ -19,19 +23,20 @@ describe AdminUserIndexQuery do TrustLevel.levels.each do |key, value| it "#{key} returns no records" do query = ::AdminUserIndexQuery.new({ query: key.to_s }) - expect(query.find_users.count).to eq(0) + expect(real_users_count(query)).to eq(0) end end end + describe "users with trust level" do TrustLevel.levels.each do |key, value| it "finds user with trust #{key}" do Fabricate(:user, trust_level: TrustLevel.levels[key]) query = ::AdminUserIndexQuery.new({ query: key.to_s }) - expect(query.find_users.count).to eq(1) + expect(real_users_count(query)).to eq(1) end end @@ -62,7 +67,7 @@ describe AdminUserIndexQuery do it "finds the admin" do query = ::AdminUserIndexQuery.new({ query: 'admins' }) - expect(query.find_users.count).to eq(1) + expect(real_users_count(query)).to eq(1) end end @@ -73,7 +78,7 @@ describe AdminUserIndexQuery do it "finds the moderator" do query = ::AdminUserIndexQuery.new({ query: 'moderators' }) - expect(query.find_users.count).to eq(1) + expect(real_users_count(query)).to eq(1) end end diff --git a/spec/components/discourse_spec.rb b/spec/components/discourse_spec.rb index a330261f9..f9a50e695 100644 --- a/spec/components/discourse_spec.rb +++ b/spec/components/discourse_spec.rb @@ -47,7 +47,6 @@ describe Discourse do end end - context '#system_user' do let!(:admin) { Fabricate(:admin) } diff --git a/spec/components/jobs/importer_spec.rb b/spec/components/jobs/importer_spec.rb index c3c63bb50..fee853b74 100644 --- a/spec/components/jobs/importer_spec.rb +++ b/spec/components/jobs/importer_spec.rb @@ -1,546 +1,540 @@ require 'spec_helper' -# Sam ... not running any of these specs for now, we are not using this code anywhere -# we can revisit when we have a ui and working import export system. -# -# -# -# @Neil strongly suggest we move this stuff to a branch including all the lib stuff +describe Jobs::Importer do + def stub_schema_changes + Jobs::Importer.any_instance.stubs(:create_backup_schema).returns( true ) + Jobs::Importer.any_instance.stubs(:backup_and_setup_table).returns( true ) + end -# describe Jobs::Importer do -# def stub_schema_changes -# Jobs::Importer.any_instance.stubs(:create_backup_schema).returns( true ) -# Jobs::Importer.any_instance.stubs(:backup_and_setup_table).returns( true ) -# end -# -# def stub_data_loading -# Jobs::Importer.any_instance.stubs(:set_schema_info).returns( true ) -# Jobs::Importer.any_instance.stubs(:load_table).returns( true ) -# Jobs::Importer.any_instance.stubs(:create_indexes).returns( true ) -# end -# -# before do -# Discourse.stubs(:enable_maintenance_mode).returns(true) -# Discourse.stubs(:disable_maintenance_mode).returns(true) -# Jobs::Importer.any_instance.stubs(:log).returns(true) -# Jobs::Importer.any_instance.stubs(:extract_uploads).returns(true) -# Jobs::Importer.any_instance.stubs(:extract_files).returns(true) -# Jobs::Importer.any_instance.stubs(:tmp_directory).returns( File.join(Rails.root, 'tmp', 'importer_spec') ) -# @importer_args = { filename: 'importer_spec.json.gz' } -# end -# -# context "SiteSetting to enable imports" do -# it "should exist" do -# SiteSetting.all_settings.detect {|s| s[:setting] == :allow_import }.should be_present -# end -# -# it "should default to false" do -# SiteSetting.allow_import?.should be_false -# end -# end -# -# context 'when import is disabled' do -# before do -# stub_schema_changes -# stub_data_loading -# Import::JsonDecoder.stubs(:new).returns( stub_everything ) -# SiteSetting.stubs(:allow_import).returns(false) -# end -# -# describe "execute" do -# it "should raise an error" do -# expect { -# Jobs::Importer.new.execute( @importer_args ) -# }.to raise_error(Import::ImportDisabledError) -# end -# -# it "should not start an import" do -# Import::JsonDecoder.expects(:new).never -# Jobs::Importer.any_instance.expects(:backup_tables).never -# Discourse.expects(:enable_maintenance_mode).never -# Jobs::Importer.new.execute( @importer_args ) rescue nil -# end -# end -# end -# -# context 'when import is enabled' do -# before do -# SiteSetting.stubs(:allow_import).returns(true) -# end -# -# describe "execute" do -# before do -# stub_data_loading -# end -# -# shared_examples_for "when import should not be started" do -# it "should not start an import" do -# Import::JsonDecoder.expects(:new).never -# Jobs::Importer.any_instance.expects(:backup_tables).never -# Jobs::Importer.new.execute( @invalid_args ) rescue nil -# end -# -# it "should not put the site in maintenance mode" do -# Discourse.expects(:enable_maintenance_mode).never -# Jobs::Importer.new.execute( @invalid_args ) rescue nil -# end -# end -# -# context "when an import is already running" do -# before do -# Import::JsonDecoder.stubs(:new).returns( stub_everything ) -# Import.stubs(:is_import_running?).returns( true ) -# end -# -# it "should raise an error" do -# expect { -# Jobs::Importer.new.execute( @importer_args ) -# }.to raise_error(Import::ImportInProgressError) -# end -# -# it_should_behave_like "when import should not be started" -# end -# -# context "when an export is running" do -# before do -# Export.stubs(:is_export_running?).returns( true ) -# end -# -# it "should raise an error" do -# expect { -# Jobs::Importer.new.execute( @importer_args ) -# }.to raise_error(Export::ExportInProgressError) -# end -# -# it_should_behave_like "when import should not be started" -# end -# -# context "when no export or import are running" do -# before do -# Import.stubs(:is_import_running?).returns( false ) -# Export.stubs(:is_export_running?).returns( false ) -# end -# -# it "without specifying a format should use json as the default format" do -# stub_schema_changes -# Import::JsonDecoder.expects(:new).returns( stub_everything ) -# Jobs::Importer.new.execute( @importer_args.reject { |key, val| key == :format } ) -# end -# -# it "when specifying json as the format it should use json" do -# stub_schema_changes -# Import::JsonDecoder.expects(:new).returns( stub_everything ) -# Jobs::Importer.new.execute( @importer_args.merge(format: :json) ) -# end -# -# context "when specifying an invalid format" do -# before do -# stub_schema_changes -# @invalid_args = @importer_args.merge( format: :smoke_signals ) -# end -# -# it "should raise an error" do -# expect { -# Jobs::Importer.new.execute( @invalid_args ) -# }.to raise_error(Import::FormatInvalidError) -# end -# -# it_should_behave_like "when import should not be started" -# end -# -# context "when filename is not given" do -# before do -# stub_schema_changes -# @invalid_args = @importer_args.reject { |k,v| k == :filename } -# end -# -# it "should raise an error" do -# expect { -# Jobs::Importer.new.execute( @invalid_args ) -# }.to raise_error(Import::FilenameMissingError) -# end -# -# it_should_behave_like "when import should not be started" -# end -# -# context "before loading data into tables" do -# before do -# Import::JsonDecoder.stubs(:new).returns( stub_everything ) -# stub_data_loading -# end -# -# shared_examples_for "a successful call to execute" do -# it "should make a backup of the users table" do -# Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([User]) -# Jobs::Importer.new.execute(@importer_args) -# User.exec_sql_row_count("SELECT table_name FROM information_schema.tables WHERE table_schema = 'backup' AND table_name = 'users'").should == 1 -# end -# -# pending "should have a users table that's empty" do -# @user1 = Fabricate(:user) -# # community user needs to be accounted for -# User.count.should == 2 -# Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([User]) -# Jobs::Importer.new.execute(@importer_args) -# User.count.should == 1 -# end -# -# it "should indicate that an import is running" do -# seq = sequence('call sequence') -# Import.expects(:set_import_started).in_sequence(seq).at_least_once -# Import.expects(:set_import_is_not_running).in_sequence(seq).at_least_once -# Jobs::Importer.new.execute(@importer_args) -# end -# -# it "should put the site in maintenance mode" do -# seq = sequence('call sequence') -# Import.is_import_running?.should be_false -# Discourse.expects(:enable_maintenance_mode).in_sequence(seq).at_least_once -# Jobs::Importer.any_instance.expects(:backup_tables).in_sequence(seq).at_least_once -# Jobs::Importer.any_instance.expects(:load_data).in_sequence(seq).at_least_once -# # fails here -# Jobs::Importer.new.execute( @importer_args ) -# end -# -# it "should take the site out of maintenance mode when it's done" do -# seq = sequence('call sequence') -# Jobs::Importer.any_instance.expects(:backup_tables).in_sequence(seq).at_least_once -# Jobs::Importer.any_instance.expects(:load_data).in_sequence(seq).at_least_once -# Discourse.expects(:disable_maintenance_mode).in_sequence(seq).at_least_once -# Jobs::Importer.new.execute( @importer_args ) -# end -# end -# -# context "the first time an import is run" do -# it_should_behave_like "a successful call to execute" -# end -# -# context "the second time an import is run" do -# before do -# Jobs::Importer.new.execute(@importer_args) -# end -# it_should_behave_like "a successful call to execute" -# end -# end -# -# # -# # Import notifications don't work from the rake task. Why is activerecord inserting an "id" value of NULL? -# # -# # PG::Error: ERROR: null value in column "id" violates not-null constraint -# # : INSERT INTO "topic_allowed_users" ("created_at", "id", "topic_id", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" -# # -# -# # context "when it finishes successfully" do -# # before do -# # stub_schema_changes -# # Import::JsonDecoder.stubs(:new).returns( stub_everything ) -# # end -# -# # context "and no user was given" do -# # it "should not send a notification to anyone" do -# # expect { -# # Jobs::Importer.new.execute( @importer_args ) -# # }.to_not change { Notification.count } -# # end -# # end -# -# # context "and a user was given" do -# # before do -# # @user = Fabricate(:user) -# # @admin = Fabricate(:admin) -# # end -# -# # it "should send a notification to the user who started the import" do -# # expect { -# # Jobs::Importer.new.execute( @importer_args.merge( user_id: @user.id ) ) -# # }.to change { Notification.count }.by(1) -# # end -# # end -# # end -# end -# end -# -# describe "set_schema_info" do -# context "when source is Discourse" do -# before do -# @current_version = '20121216230719' -# Export.stubs(:current_schema_version).returns(@current_version) -# @valid_args = { source: 'discourse', version: @current_version, table_count: Export.models_included_in_export.size } -# end -# -# it "succeeds when receiving the current schema version" do -# Jobs::Importer.new.set_schema_info( @valid_args ).should be_true -# end -# -# it "succeeds when receiving an older schema version" do -# Jobs::Importer.new.set_schema_info( @valid_args.merge( version: "#{@current_version.to_i - 1}") ).should be_true -# end -# -# it "raises an error if version is not given" do -# expect { -# Jobs::Importer.new.set_schema_info( @valid_args.reject {|key, val| key == :version} ) -# }.to raise_error(ArgumentError) -# end -# -# it "raises an error when receiving a newer schema version" do -# expect { -# Jobs::Importer.new.set_schema_info( @valid_args.merge( version: "#{@current_version.to_i + 1}") ) -# }.to raise_error(Import::UnsupportedSchemaVersion) -# end -# -# it "raises an error when it doesn't get the number of tables it expects" do -# expect { -# Jobs::Importer.new.set_schema_info( @valid_args.merge( table_count: 2 ) ) -# }.to raise_error(Import::WrongTableCountError) -# end -# end -# -# it "raises an error when it receives an unsupported source" do -# expect { -# Jobs::Importer.new.set_schema_info( source: 'digg' ) -# }.to raise_error(Import::UnsupportedExportSource) -# end -# end -# -# describe "load_table" do -# before do -# stub_schema_changes -# @valid_field_list = ["id", "notification_type", "user_id", "data", "read", "created_at", "updated_at", "topic_id", "post_number", "post_action_id"] -# @valid_notifications_row_data = [ -# ['1409', '5', '1227', '', 't', '2012-12-07 19:59:56.691592', '2012-12-07 19:59:56.691592', '303', '16', '420'], -# ['1408', '4', '1188', '', 'f', '2012-12-07 18:40:30.460404', '2012-12-07 18:40:30.460404', '304', '1', '421'] -# ] -# end -# -# context "when export data is at the current scheam version" do -# before do -# Import.stubs(:adapters_for_version).returns({}) -# end -# -# context "with good data" do -# it "should add rows to the notifcations table given valid row data" do -# Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) -# Notification.count.should == @valid_notifications_row_data.length -# end -# -# it "should successfully load rows with double quote literals in the values" do -# @valid_notifications_row_data[0][3] = "{\"topic_title\":\"Errors, errbit and you!\",\"display_username\":\"Coding Horror\"}" -# Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) -# Notification.count.should == @valid_notifications_row_data.length -# end -# -# it "should successfully load rows with single quote literals in the values" do -# @valid_notifications_row_data[0][3] = "{\"topic_title\":\"Bacon's Delicious, Am I Right\",\"display_username\":\"Celine Dion\"}" -# Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) -# Notification.count.should == @valid_notifications_row_data.length -# end -# -# it "should succesfully load rows with null values" do -# @valid_notifications_row_data[0][7] = nil -# @valid_notifications_row_data[1][9] = nil -# Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) -# Notification.count.should == @valid_notifications_row_data.length -# end -# -# it "should successfully load rows with question marks in the values" do -# @valid_notifications_row_data[0][3] = "{\"topic_title\":\"Who took my sandwich?\",\"display_username\":\"Lunchless\"}" -# Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) -# Notification.count.should == @valid_notifications_row_data.length -# end -# end -# -# context "with fewer than the expected number of fields for a table" do -# before do -# @short_field_list = ["id", "notification_type", "user_id", "data", "read", "created_at", "updated_at", "topic_id", "post_number"] -# @short_notifications_row_data = [ -# ['1409', '5', '1227', '', 't', '2012-12-07 19:59:56.691592', '2012-12-07 19:59:56.691592', '303', '16'], -# ['1408', '4', '1188', '', 'f', '2012-12-07 18:40:30.460404', '2012-12-07 18:40:30.460404', '304', '1'] -# ] -# end -# -# it "should not raise an error" do -# expect { -# Jobs::Importer.new.load_table('notifications', @short_field_list, @short_notifications_row_data, @short_notifications_row_data.size) -# }.to_not raise_error -# end -# end -# -# context "with more than the expected number of fields for a table" do -# before do -# @too_long_field_list = ["id", "notification_type", "user_id", "data", "read", "created_at", "updated_at", "topic_id", "post_number", "post_action_id", "extra_col"] -# @too_long_notifications_row_data = [ -# ['1409', '5', '1227', '', 't', '2012-12-07 19:59:56.691592', '2012-12-07 19:59:56.691592', '303', '16', '420', 'extra'], -# ['1408', '4', '1188', '', 'f', '2012-12-07 18:40:30.460404', '2012-12-07 18:40:30.460404', '304', '1', '421', 'extra'] -# ] -# end -# -# it "should raise an error" do -# expect { -# Jobs::Importer.new.load_table('notifications', @too_long_field_list, @too_long_notifications_row_data, @too_long_notifications_row_data.size) -# }.to raise_error(Import::WrongFieldCountError) -# end -# end -# -# context "with an unrecognized table name" do -# it "should not raise an error" do -# expect { -# Jobs::Importer.new.load_table('pork_chops', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) -# }.to_not raise_error -# end -# -# it "should report a warning" do -# Jobs::Importer.any_instance.expects(:add_warning).once -# Jobs::Importer.new.load_table('pork_chops', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) -# end -# end -# end -# -# context "when import adapters are needed" do -# before do -# @version = (Export.current_schema_version.to_i - 1).to_s -# Export.stubs(:current_schema_version).returns( @version ) -# end -# -# it "should apply the adapter" do -# @adapter = mock('adapter', apply_to_column_names: @valid_field_list, apply_to_row: @valid_notifications_row_data[0]) -# Import.expects(:adapters_for_version).at_least_once.returns({'notifications' => [@adapter]}) -# Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data[0,1], 1) -# end -# end -# end -# -# describe "create_indexes" do -# before do -# Import::JsonDecoder.stubs(:new).returns( stub_everything ) -# Jobs::Importer.any_instance.stubs(:set_schema_info).returns( true ) -# Jobs::Importer.any_instance.stubs(:load_table).returns( true ) -# end -# -# it "should create the same indexes on the new tables" do -# Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([Topic]) -# expect { -# Jobs::Importer.new.execute( @importer_args ) -# }.to_not change{ Topic.exec_sql("SELECT indexname FROM pg_indexes WHERE tablename = 'topics' and schemaname = 'public';").map {|x| x['indexname']}.sort } -# end -# -# it "should create primary keys" do -# Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([User]) -# Jobs::Importer.new.execute( @importer_args ) -# User.connection.primary_key('users').should_not be_nil -# end -# end -# -# describe "rollback" do -# it "should not get called if format parameter is invalid" do -# stub_data_loading -# Jobs::Importer.any_instance.stubs(:start_import).raises(Import::FormatInvalidError) -# Jobs::Importer.any_instance.expects(:rollback).never -# Jobs::Importer.new.execute( @importer_args ) rescue nil -# end -# -# context "when creating the backup schema fails" do -# it "should not call rollback" do -# stub_data_loading -# Jobs::Importer.any_instance.stubs(:create_backup_schema).raises(RuntimeError) -# Jobs::Importer.any_instance.expects(:rollback).never -# Jobs::Importer.new.execute( @importer_args ) rescue nil -# end -# end -# -# shared_examples_for "a case when rollback is needed" do -# before do -# Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([User]) -# @user1, @user2 = Fabricate(:user), Fabricate(:user) -# @user_row1 = User.connection.select_rows("select * from users order by id DESC limit 1") -# @user_row1[0] = '11111' # change the id -# @export_data = { -# schema: { source: 'discourse', version: '20121201205642'}, -# users: { -# fields: User.columns.map(&:name), -# rows: [ *@user_row1 ] -# } -# } -# @testIO = StringIO.new(@export_data.to_json, 'r') -# Import::JsonDecoder.any_instance.stubs(:input_stream).returns(@testIO) -# end -# -# it "should call rollback" do -# Jobs::Importer.any_instance.expects(:rollback).once -# Jobs::Importer.new.execute( @importer_args ) rescue nil -# end -# -# it "should restore the data" do -# expect { -# Jobs::Importer.new.execute( @importer_args ) rescue nil -# }.to_not change { User.count } -# users = User.all -# users.should include(@user1) -# users.should include(@user2) -# end -# -# it "should take the site out of maintenance mode" do -# Discourse.expects(:disable_maintenance_mode).at_least_once -# Jobs::Importer.new.execute( @importer_args ) rescue nil -# end -# end -# -# context "when backing up a table fails" do -# it "should not call rollback" do # because the transaction will rollback automatically -# stub_data_loading -# Jobs::Importer.any_instance.stubs(:backup_and_setup_table).raises(ActiveRecord::StatementInvalid) -# Jobs::Importer.any_instance.expects(:rollback).never -# Jobs::Importer.new.execute( @importer_args ) rescue nil -# end -# end -# -# context "when export source is invalid" do -# before do -# Jobs::Importer.any_instance.stubs(:set_schema_info).raises(Import::UnsupportedExportSource) -# end -# it_should_behave_like "a case when rollback is needed" -# end -# -# context "when schema version is not supported" do -# before do -# Jobs::Importer.any_instance.stubs(:set_schema_info).raises(Import::UnsupportedSchemaVersion) -# end -# it_should_behave_like "a case when rollback is needed" -# end -# -# context "when schema info in export file is invalid for some other reason" do -# before do -# Jobs::Importer.any_instance.stubs(:set_schema_info).raises(ArgumentError) -# end -# it_should_behave_like "a case when rollback is needed" -# end -# -# context "when loading a table fails" do -# before do -# Jobs::Importer.any_instance.stubs(:load_table).raises(ActiveRecord::StatementInvalid) -# end -# it_should_behave_like "a case when rollback is needed" -# end -# -# context "when creating indexes fails" do -# before do -# Jobs::Importer.any_instance.stubs(:create_indexes).raises(ActiveRecord::StatementInvalid) -# end -# it_should_behave_like "a case when rollback is needed" -# end -# -# context "when table count is wrong" do -# before do -# Jobs::Importer.any_instance.stubs(:set_schema_info).raises(Import::WrongTableCountError) -# end -# it_should_behave_like "a case when rollback is needed" -# end -# -# context "when field count for a table is wrong" do -# before do -# Jobs::Importer.any_instance.stubs(:load_table).raises(Import::WrongFieldCountError) -# end -# it_should_behave_like "a case when rollback is needed" -# end -# end -# end -# end + def stub_data_loading + Jobs::Importer.any_instance.stubs(:set_schema_info).returns( true ) + Jobs::Importer.any_instance.stubs(:load_table).returns( true ) + Jobs::Importer.any_instance.stubs(:create_indexes).returns( true ) + end + + before do + Discourse.stubs(:enable_maintenance_mode).returns(true) + Discourse.stubs(:disable_maintenance_mode).returns(true) + Jobs::Importer.any_instance.stubs(:log).returns(true) + Jobs::Importer.any_instance.stubs(:extract_uploads).returns(true) + Jobs::Importer.any_instance.stubs(:extract_files).returns(true) + Jobs::Importer.any_instance.stubs(:tmp_directory).returns( File.join(Rails.root, 'tmp', 'importer_spec') ) + @importer_args = { filename: 'importer_spec.json.gz' } + end + + context "SiteSetting to enable imports" do + it "should exist" do + SiteSetting.all_settings.detect {|s| s[:setting] == :allow_import }.should be_present + end + + it "should default to false" do + SiteSetting.allow_import?.should be_false + end + end + + context 'when import is disabled' do + before do + stub_schema_changes + stub_data_loading + Import::JsonDecoder.stubs(:new).returns( stub_everything ) + SiteSetting.stubs(:allow_import).returns(false) + end + + describe "execute" do + it "should raise an error" do + expect { + Jobs::Importer.new.execute( @importer_args ) + }.to raise_error(Import::ImportDisabledError) + end + + it "should not start an import" do + Import::JsonDecoder.expects(:new).never + Jobs::Importer.any_instance.expects(:backup_tables).never + Discourse.expects(:enable_maintenance_mode).never + Jobs::Importer.new.execute( @importer_args ) rescue nil + end + end + end + + context 'when import is enabled' do + before do + SiteSetting.stubs(:allow_import).returns(true) + end + + describe "execute" do + before do + stub_data_loading + end + + shared_examples_for "when import should not be started" do + it "should not start an import" do + Import::JsonDecoder.expects(:new).never + Jobs::Importer.any_instance.expects(:backup_tables).never + Jobs::Importer.new.execute( @invalid_args ) rescue nil + end + + it "should not put the site in maintenance mode" do + Discourse.expects(:enable_maintenance_mode).never + Jobs::Importer.new.execute( @invalid_args ) rescue nil + end + end + + context "when an import is already running" do + before do + Import::JsonDecoder.stubs(:new).returns( stub_everything ) + Import.stubs(:is_import_running?).returns( true ) + end + + it "should raise an error" do + expect { + Jobs::Importer.new.execute( @importer_args ) + }.to raise_error(Import::ImportInProgressError) + end + + it_should_behave_like "when import should not be started" + end + + context "when an export is running" do + before do + Export.stubs(:is_export_running?).returns( true ) + end + + it "should raise an error" do + expect { + Jobs::Importer.new.execute( @importer_args ) + }.to raise_error(Export::ExportInProgressError) + end + + it_should_behave_like "when import should not be started" + end + + context "when no export or import are running" do + before do + Import.stubs(:is_import_running?).returns( false ) + Export.stubs(:is_export_running?).returns( false ) + end + + it "without specifying a format should use json as the default format" do + stub_schema_changes + Import::JsonDecoder.expects(:new).returns( stub_everything ) + Jobs::Importer.new.execute( @importer_args.reject { |key, val| key == :format } ) + end + + it "when specifying json as the format it should use json" do + stub_schema_changes + Import::JsonDecoder.expects(:new).returns( stub_everything ) + Jobs::Importer.new.execute( @importer_args.merge(format: :json) ) + end + + context "when specifying an invalid format" do + before do + stub_schema_changes + @invalid_args = @importer_args.merge( format: :smoke_signals ) + end + + it "should raise an error" do + expect { + Jobs::Importer.new.execute( @invalid_args ) + }.to raise_error(Import::FormatInvalidError) + end + + it_should_behave_like "when import should not be started" + end + + context "when filename is not given" do + before do + stub_schema_changes + @invalid_args = @importer_args.reject { |k,v| k == :filename } + end + + it "should raise an error" do + expect { + Jobs::Importer.new.execute( @invalid_args ) + }.to raise_error(Import::FilenameMissingError) + end + + it_should_behave_like "when import should not be started" + end + + context "before loading data into tables" do + before do + Import::JsonDecoder.stubs(:new).returns( stub_everything ) + stub_data_loading + end + + shared_examples_for "a successful call to execute" do + it "should make a backup of the users table" do + Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([User]) + Jobs::Importer.new.execute(@importer_args) + User.exec_sql_row_count("SELECT table_name FROM information_schema.tables WHERE table_schema = 'backup' AND table_name = 'users'").should == 1 + end + + # Neil, please have a look here + pending "should have a users table that's empty" do + @user1 = Fabricate(:user) + # community user needs to be accounted for + User.count.should == 2 + Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([User]) + Jobs::Importer.new.execute(@importer_args) + User.count.should == 1 + end + + it "should indicate that an import is running" do + seq = sequence('call sequence') + Import.expects(:set_import_started).in_sequence(seq).at_least_once + Import.expects(:set_import_is_not_running).in_sequence(seq).at_least_once + Jobs::Importer.new.execute(@importer_args) + end + + it "should put the site in maintenance mode" do + seq = sequence('call sequence') + Import.is_import_running?.should be_false + Discourse.expects(:enable_maintenance_mode).in_sequence(seq).at_least_once + Jobs::Importer.any_instance.expects(:backup_tables).in_sequence(seq).at_least_once + Jobs::Importer.any_instance.expects(:load_data).in_sequence(seq).at_least_once + # fails here + Jobs::Importer.new.execute( @importer_args ) + end + + it "should take the site out of maintenance mode when it's done" do + seq = sequence('call sequence') + Jobs::Importer.any_instance.expects(:backup_tables).in_sequence(seq).at_least_once + Jobs::Importer.any_instance.expects(:load_data).in_sequence(seq).at_least_once + Discourse.expects(:disable_maintenance_mode).in_sequence(seq).at_least_once + Jobs::Importer.new.execute( @importer_args ) + end + end + + context "the first time an import is run" do + it_should_behave_like "a successful call to execute" + end + + context "the second time an import is run" do + before do + Jobs::Importer.new.execute(@importer_args) + end + it_should_behave_like "a successful call to execute" + end + end + + # + # Import notifications don't work from the rake task. Why is activerecord inserting an "id" value of NULL? + # + # PG::Error: ERROR: null value in column "id" violates not-null constraint + # : INSERT INTO "topic_allowed_users" ("created_at", "id", "topic_id", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" + # + + # context "when it finishes successfully" do + # before do + # stub_schema_changes + # Import::JsonDecoder.stubs(:new).returns( stub_everything ) + # end + + # context "and no user was given" do + # it "should not send a notification to anyone" do + # expect { + # Jobs::Importer.new.execute( @importer_args ) + # }.to_not change { Notification.count } + # end + # end + + # context "and a user was given" do + # before do + # @user = Fabricate(:user) + # @admin = Fabricate(:admin) + # end + + # it "should send a notification to the user who started the import" do + # expect { + # Jobs::Importer.new.execute( @importer_args.merge( user_id: @user.id ) ) + # }.to change { Notification.count }.by(1) + # end + # end + # end + end + end + + describe "set_schema_info" do + context "when source is Discourse" do + before do + @current_version = '20121216230719' + Export.stubs(:current_schema_version).returns(@current_version) + @valid_args = { source: 'discourse', version: @current_version, table_count: Export.models_included_in_export.size } + end + + it "succeeds when receiving the current schema version" do + Jobs::Importer.new.set_schema_info( @valid_args ).should be_true + end + + it "succeeds when receiving an older schema version" do + Jobs::Importer.new.set_schema_info( @valid_args.merge( version: "#{@current_version.to_i - 1}") ).should be_true + end + + it "raises an error if version is not given" do + expect { + Jobs::Importer.new.set_schema_info( @valid_args.reject {|key, val| key == :version} ) + }.to raise_error(ArgumentError) + end + + it "raises an error when receiving a newer schema version" do + expect { + Jobs::Importer.new.set_schema_info( @valid_args.merge( version: "#{@current_version.to_i + 1}") ) + }.to raise_error(Import::UnsupportedSchemaVersion) + end + + it "raises an error when it doesn't get the number of tables it expects" do + expect { + Jobs::Importer.new.set_schema_info( @valid_args.merge( table_count: 2 ) ) + }.to raise_error(Import::WrongTableCountError) + end + end + + it "raises an error when it receives an unsupported source" do + expect { + Jobs::Importer.new.set_schema_info( source: 'digg' ) + }.to raise_error(Import::UnsupportedExportSource) + end + end + + describe "load_table" do + before do + stub_schema_changes + @valid_field_list = ["id", "notification_type", "user_id", "data", "read", "created_at", "updated_at", "topic_id", "post_number", "post_action_id"] + @valid_notifications_row_data = [ + ['1409', '5', '1227', '', 't', '2012-12-07 19:59:56.691592', '2012-12-07 19:59:56.691592', '303', '16', '420'], + ['1408', '4', '1188', '', 'f', '2012-12-07 18:40:30.460404', '2012-12-07 18:40:30.460404', '304', '1', '421'] + ] + end + + context "when export data is at the current scheam version" do + before do + Import.stubs(:adapters_for_version).returns({}) + end + + context "with good data" do + it "should add rows to the notifcations table given valid row data" do + Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) + Notification.count.should == @valid_notifications_row_data.length + end + + it "should successfully load rows with double quote literals in the values" do + @valid_notifications_row_data[0][3] = "{\"topic_title\":\"Errors, errbit and you!\",\"display_username\":\"Coding Horror\"}" + Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) + Notification.count.should == @valid_notifications_row_data.length + end + + it "should successfully load rows with single quote literals in the values" do + @valid_notifications_row_data[0][3] = "{\"topic_title\":\"Bacon's Delicious, Am I Right\",\"display_username\":\"Celine Dion\"}" + Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) + Notification.count.should == @valid_notifications_row_data.length + end + + it "should succesfully load rows with null values" do + @valid_notifications_row_data[0][7] = nil + @valid_notifications_row_data[1][9] = nil + Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) + Notification.count.should == @valid_notifications_row_data.length + end + + it "should successfully load rows with question marks in the values" do + @valid_notifications_row_data[0][3] = "{\"topic_title\":\"Who took my sandwich?\",\"display_username\":\"Lunchless\"}" + Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) + Notification.count.should == @valid_notifications_row_data.length + end + end + + context "with fewer than the expected number of fields for a table" do + before do + @short_field_list = ["id", "notification_type", "user_id", "data", "read", "created_at", "updated_at", "topic_id", "post_number"] + @short_notifications_row_data = [ + ['1409', '5', '1227', '', 't', '2012-12-07 19:59:56.691592', '2012-12-07 19:59:56.691592', '303', '16'], + ['1408', '4', '1188', '', 'f', '2012-12-07 18:40:30.460404', '2012-12-07 18:40:30.460404', '304', '1'] + ] + end + + it "should not raise an error" do + expect { + Jobs::Importer.new.load_table('notifications', @short_field_list, @short_notifications_row_data, @short_notifications_row_data.size) + }.to_not raise_error + end + end + + context "with more than the expected number of fields for a table" do + before do + @too_long_field_list = ["id", "notification_type", "user_id", "data", "read", "created_at", "updated_at", "topic_id", "post_number", "post_action_id", "extra_col"] + @too_long_notifications_row_data = [ + ['1409', '5', '1227', '', 't', '2012-12-07 19:59:56.691592', '2012-12-07 19:59:56.691592', '303', '16', '420', 'extra'], + ['1408', '4', '1188', '', 'f', '2012-12-07 18:40:30.460404', '2012-12-07 18:40:30.460404', '304', '1', '421', 'extra'] + ] + end + + it "should raise an error" do + expect { + Jobs::Importer.new.load_table('notifications', @too_long_field_list, @too_long_notifications_row_data, @too_long_notifications_row_data.size) + }.to raise_error(Import::WrongFieldCountError) + end + end + + context "with an unrecognized table name" do + it "should not raise an error" do + expect { + Jobs::Importer.new.load_table('pork_chops', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) + }.to_not raise_error + end + + it "should report a warning" do + Jobs::Importer.any_instance.expects(:add_warning).once + Jobs::Importer.new.load_table('pork_chops', @valid_field_list, @valid_notifications_row_data, @valid_notifications_row_data.size) + end + end + end + + context "when import adapters are needed" do + before do + @version = (Export.current_schema_version.to_i - 1).to_s + Export.stubs(:current_schema_version).returns( @version ) + end + + it "should apply the adapter" do + @adapter = mock('adapter', apply_to_column_names: @valid_field_list, apply_to_row: @valid_notifications_row_data[0]) + Import.expects(:adapters_for_version).at_least_once.returns({'notifications' => [@adapter]}) + Jobs::Importer.new.load_table('notifications', @valid_field_list, @valid_notifications_row_data[0,1], 1) + end + end + end + + describe "create_indexes" do + before do + Import::JsonDecoder.stubs(:new).returns( stub_everything ) + Jobs::Importer.any_instance.stubs(:set_schema_info).returns( true ) + Jobs::Importer.any_instance.stubs(:load_table).returns( true ) + end + + it "should create the same indexes on the new tables" do + Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([Topic]) + expect { + Jobs::Importer.new.execute( @importer_args ) + }.to_not change{ Topic.exec_sql("SELECT indexname FROM pg_indexes WHERE tablename = 'topics' and schemaname = 'public';").map {|x| x['indexname']}.sort } + end + + it "should create primary keys" do + Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([User]) + Jobs::Importer.new.execute( @importer_args ) + User.connection.primary_key('users').should_not be_nil + end + end + + describe "rollback" do + it "should not get called if format parameter is invalid" do + stub_data_loading + Jobs::Importer.any_instance.stubs(:start_import).raises(Import::FormatInvalidError) + Jobs::Importer.any_instance.expects(:rollback).never + Jobs::Importer.new.execute( @importer_args ) rescue nil + end + + context "when creating the backup schema fails" do + it "should not call rollback" do + stub_data_loading + Jobs::Importer.any_instance.stubs(:create_backup_schema).raises(RuntimeError) + Jobs::Importer.any_instance.expects(:rollback).never + Jobs::Importer.new.execute( @importer_args ) rescue nil + end + end + + shared_examples_for "a case when rollback is needed" do + before do + Jobs::Importer.any_instance.stubs(:ordered_models_for_import).returns([User]) + @user1, @user2 = Fabricate(:user), Fabricate(:user) + @user_row1 = User.connection.select_rows("select * from users order by id DESC limit 1") + @user_row1[0] = '11111' # change the id + @export_data = { + schema: { source: 'discourse', version: '20121201205642'}, + users: { + fields: User.columns.map(&:name), + rows: [ *@user_row1 ] + } + } + @testIO = StringIO.new(@export_data.to_json, 'r') + Import::JsonDecoder.any_instance.stubs(:input_stream).returns(@testIO) + end + + it "should call rollback" do + Jobs::Importer.any_instance.expects(:rollback).once + Jobs::Importer.new.execute( @importer_args ) rescue nil + end + + it "should restore the data" do + expect { + Jobs::Importer.new.execute( @importer_args ) rescue nil + }.to_not change { User.count } + users = User.all + users.should include(@user1) + users.should include(@user2) + end + + it "should take the site out of maintenance mode" do + Discourse.expects(:disable_maintenance_mode).at_least_once + Jobs::Importer.new.execute( @importer_args ) rescue nil + end + end + + context "when backing up a table fails" do + it "should not call rollback" do # because the transaction will rollback automatically + stub_data_loading + Jobs::Importer.any_instance.stubs(:backup_and_setup_table).raises(ActiveRecord::StatementInvalid) + Jobs::Importer.any_instance.expects(:rollback).never + Jobs::Importer.new.execute( @importer_args ) rescue nil + end + end + + context "when export source is invalid" do + before do + Jobs::Importer.any_instance.stubs(:set_schema_info).raises(Import::UnsupportedExportSource) + end + it_should_behave_like "a case when rollback is needed" + end + + context "when schema version is not supported" do + before do + Jobs::Importer.any_instance.stubs(:set_schema_info).raises(Import::UnsupportedSchemaVersion) + end + it_should_behave_like "a case when rollback is needed" + end + + context "when schema info in export file is invalid for some other reason" do + before do + Jobs::Importer.any_instance.stubs(:set_schema_info).raises(ArgumentError) + end + it_should_behave_like "a case when rollback is needed" + end + + context "when loading a table fails" do + before do + Jobs::Importer.any_instance.stubs(:load_table).raises(ActiveRecord::StatementInvalid) + end + it_should_behave_like "a case when rollback is needed" + end + + context "when creating indexes fails" do + before do + Jobs::Importer.any_instance.stubs(:create_indexes).raises(ActiveRecord::StatementInvalid) + end + it_should_behave_like "a case when rollback is needed" + end + + context "when table count is wrong" do + before do + Jobs::Importer.any_instance.stubs(:set_schema_info).raises(Import::WrongTableCountError) + end + it_should_behave_like "a case when rollback is needed" + end + + context "when field count for a table is wrong" do + before do + Jobs::Importer.any_instance.stubs(:load_table).raises(Import::WrongFieldCountError) + end + it_should_behave_like "a case when rollback is needed" + end + end + end +end diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb index 8aaa2fa25..767e1ca13 100644 --- a/spec/components/post_creator_spec.rb +++ b/spec/components/post_creator_spec.rb @@ -310,6 +310,14 @@ describe PostCreator do # does not notify an unrelated user unrelated.notifications.count.should == 0 post.topic.subtype.should == TopicSubtype.user_to_user + + # if a mod replies they should be added to the allowed user list + mod = Fabricate(:moderator) + PostCreator.create(mod, raw: 'hi there welcome topic, I am a mod', + topic_id: post.topic_id) + + post.topic.reload + post.topic.topic_allowed_users.where(user_id: mod.id).count.should == 1 end end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 217da8f07..bb8c61101 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -21,6 +21,18 @@ describe Group do end end + def real_admins + Group[:admins].user_ids - [-1] + end + + def real_moderators + Group[:moderators].user_ids - [-1] + end + + def real_staff + Group[:staff].user_ids - [-1] + end + it "Can update moderator/staff/admin groups correctly" do admin = Fabricate(:admin) @@ -28,33 +40,33 @@ describe Group do Group.refresh_automatic_groups!(:admins, :staff, :moderators) - Group[:admins].user_ids.should == [admin.id] - Group[:moderators].user_ids.should == [moderator.id] - Group[:staff].user_ids.sort.should == [moderator.id,admin.id].sort + real_admins.should == [admin.id] + real_moderators.should == [moderator.id] + real_staff.sort.should == [moderator.id,admin.id].sort admin.admin = false admin.save Group.refresh_automatic_group!(:admins) - Group[:admins].user_ids.should == [] + real_admins.should == [] moderator.revoke_moderation! admin.grant_admin! - Group[:admins].user_ids.should == [admin.id] - Group[:staff].user_ids.should == [admin.id] + real_admins.should == [admin.id] + real_staff.should == [admin.id] admin.revoke_admin! - Group[:admins].user_ids.should == [] - Group[:staff].user_ids.should == [] + real_admins.should == [] + real_staff.should == [] admin.grant_moderation! - Group[:moderators].user_ids.should == [admin.id] - Group[:staff].user_ids.should == [admin.id] + real_moderators.should == [admin.id] + real_staff.should == [admin.id] admin.revoke_moderation! - Group[:admins].user_ids.should == [] - Group[:staff].user_ids.should == [] + real_admins.should == [] + real_staff.should == [] end it "Correctly updates automatic trust level groups" do @@ -87,12 +99,12 @@ describe Group do groups.count.should == Group::AUTO_GROUPS.count g = groups.find{|g| g.id == Group::AUTO_GROUPS[:admins]} - g.users.count.should == 1 - g.user_count.should == 1 + g.users.count.should == 2 + g.user_count.should == 2 g = groups.find{|g| g.id == Group::AUTO_GROUPS[:staff]} - g.users.count.should == 1 - g.user_count.should == 1 + g.users.count.should == 2 + g.user_count.should == 2 g = groups.find{|g| g.id == Group::AUTO_GROUPS[:trust_level_2]} g.users.count.should == 1 diff --git a/spec/models/post_action_spec.rb b/spec/models/post_action_spec.rb index 561560718..ba4ad3d9b 100644 --- a/spec/models/post_action_spec.rb +++ b/spec/models/post_action_spec.rb @@ -41,10 +41,9 @@ describe PostAction do describe 'notify_moderators' do before do PostAction.stubs(:create) - PostAction.expects(:target_moderators).returns("moderators") end - it "sends an email to all moderators if selected" do + it "sends an email to community if selected" do post = build(:post, id: 1000) PostCreator.any_instance.expects(:create).returns(post) PostAction.act(build(:user), build(:post), PostActionType.types[:notify_moderators], message: "this is my special message");