diff --git a/db/migrate/20160504064737_add_index_for_latest_meeting_activity.rb b/db/migrate/20160504064737_add_index_for_latest_meeting_activity.rb new file mode 100644 index 0000000000..167467ad85 --- /dev/null +++ b/db/migrate/20160504064737_add_index_for_latest_meeting_activity.rb @@ -0,0 +1,5 @@ +class AddIndexForLatestMeetingActivity < ActiveRecord::Migration + def change + add_index :meetings, [:project_id, :updated_at] + end +end diff --git a/lib/open_project/meeting/engine.rb b/lib/open_project/meeting/engine.rb index bd6701e62b..f472e73d65 100644 --- a/lib/open_project/meeting/engine.rb +++ b/lib/open_project/meeting/engine.rb @@ -73,6 +73,11 @@ module OpenProject::Meeting require 'open_project/meeting/hooks' end + initializer 'meeting.register_latest_project_activity' do + Project.register_latest_project_activity on: ::Meeting, + attribute: :updated_at + end + config.to_prepare do # load classes so that all User.before_destroy filters are loaded require_dependency 'meeting' diff --git a/spec/models/project/activity_spec.rb b/spec/models/project/activity_spec.rb new file mode 100644 index 0000000000..f269c50d90 --- /dev/null +++ b/spec/models/project/activity_spec.rb @@ -0,0 +1,81 @@ +#-- copyright +# OpenProject Meeting Plugin +# +# Copyright (C) 2011-2014 the OpenProject Foundation (OPF) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See doc/COPYRIGHT.md for more details. +#++ + +require 'spec_helper' + +describe Project::Activity, type: :model do + let(:project) do + FactoryGirl.create(:project) + end + + let(:initial_time) { Time.now } + + let(:meeting) do + FactoryGirl.create(:meeting, + project: project) + end + + let(:meeting2) do + FactoryGirl.create(:meeting, + project: project) + end + + let(:work_package) do + FactoryGirl.create(:work_package, + project: project) + end + + def latest_activity + Project.with_latest_activity.find(project.id).latest_activity_at + end + + describe '.with_latest_activity' do + it 'is the latest meeting update' do + meeting.update_attribute(:updated_at, initial_time - 10.seconds) + meeting2.update_attribute(:updated_at, initial_time - 20.seconds) + meeting.reload + meeting2.reload + + expect(latest_activity).to eql meeting.updated_at + end + + it 'takes the time stamp of the latest activity across models' do + work_package.update_attribute(:updated_at, initial_time - 10.seconds) + meeting.update_attribute(:updated_at, initial_time - 20.seconds) + + work_package.reload + meeting.reload + + # Order: + # work_package + # meeting + + expect(latest_activity).to eql work_package.updated_at + + work_package.update_attribute(:updated_at, meeting.updated_at - 10.seconds) + + # Order: + # meeting + # work_package + + expect(latest_activity).to eql meeting.updated_at + end + end +end