diff --git a/app/models/activity_observer.rb b/app/models/activity_observer.rb new file mode 100644 index 00000000..46564161 --- /dev/null +++ b/app/models/activity_observer.rb @@ -0,0 +1,12 @@ +class ActivityObserver < ActiveRecord::Observer + observe :issue, :merge_request, :note + + def after_create(record) + Event.create( + :project => record.project, + :target_id => record.id, + :target_type => record.class.name, + :action => Event.determine_action(record) + ) + end +end diff --git a/app/models/event.rb b/app/models/event.rb index c2d09f1b..5cb75247 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,17 +1,36 @@ class Event < ActiveRecord::Base + Created = 1 + Updated = 2 + Closed = 3 + Reopened = 4 + Pushed = 5 + Commented = 6 + belongs_to :project + belongs_to :target, :polymorphic => true + serialize :data + + def self.determine_action(record) + if [Issue, MergeRequest].include? record.class + Event::Created + elsif record.kind_of? Note + Event::Commented + end + end end # == Schema Information # # Table name: events # -# id :integer not null, primary key -# data_type :string(255) -# data_id :string(255) -# title :string(255) -# data :text -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# target_type :string(255) +# target_id :integer +# title :string(255) +# data :text +# project_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# action :integer # + diff --git a/app/models/project.rb b/app/models/project.rb index 93999639..122f59fb 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -3,6 +3,7 @@ require "grit" class Project < ActiveRecord::Base belongs_to :owner, :class_name => "User" + has_many :events, :dependent => :destroy has_many :merge_requests, :dependent => :destroy has_many :issues, :dependent => :destroy, :order => "position" has_many :users_projects, :dependent => :destroy diff --git a/app/models/wiki.rb b/app/models/wiki.rb index 0f19567c..ad3e4a38 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -44,3 +44,4 @@ end # slug :string(255) # user_id :integer # + diff --git a/config/application.rb b/config/application.rb index bdd5bbf3..a3ef29c0 100644 --- a/config/application.rb +++ b/config/application.rb @@ -23,7 +23,7 @@ module Gitlab # config.plugins = [ :exception_notification, :ssl_requirement, :all ] # Activate observers that should always be running. - config.active_record.observers = :mailer_observer + config.active_record.observers = :mailer_observer, :activity_observer # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. diff --git a/db/migrate/20120228130210_create_events.rb b/db/migrate/20120228130210_create_events.rb index 2f15ff30..c01f557a 100644 --- a/db/migrate/20120228130210_create_events.rb +++ b/db/migrate/20120228130210_create_events.rb @@ -1,8 +1,9 @@ class CreateEvents < ActiveRecord::Migration def change create_table :events do |t| - t.string :data_type, :null => true - t.string :data_id, :null => true + t.string :target_type, :null => true + t.integer :target_id, :null => true + t.string :title, :null => true t.text :data, :null => true t.integer :project_id, :null => true diff --git a/db/migrate/20120228134252_add_action_to_event.rb b/db/migrate/20120228134252_add_action_to_event.rb new file mode 100644 index 00000000..aade3d90 --- /dev/null +++ b/db/migrate/20120228134252_add_action_to_event.rb @@ -0,0 +1,5 @@ +class AddActionToEvent < ActiveRecord::Migration + def change + add_column :events, :action, :integer, :null => true + end +end diff --git a/db/schema.rb b/db/schema.rb index b9a43370..a0baf8e2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,16 +11,17 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120228130210) do +ActiveRecord::Schema.define(:version => 20120228134252) do create_table "events", :force => true do |t| - t.string "data_type" - t.string "data_id" + t.string "target_type" + t.integer "target_id" t.string "title" t.text "data" t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "action" end create_table "issues", :force => true do |t| diff --git a/spec/factories.rb b/spec/factories.rb index 6d7a4cb7..2ca8d764 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -32,10 +32,14 @@ end Factory.add(:issue, Issue) do |obj| obj.title = Faker::Lorem.sentence + obj.author = Factory :user + obj.assignee = Factory :user end Factory.add(:merge_request, MergeRequest) do |obj| obj.title = Faker::Lorem.sentence + obj.author = Factory :user + obj.assignee = Factory :user obj.source_branch = "master" obj.target_branch = "master" obj.closed = false @@ -64,3 +68,8 @@ Factory.add(:wikis, WebHook) do |obj| obj.title = Faker::Lorem.sentence obj.content = Faker::Lorem.sentence end + +Factory.add(:event, Event) do |obj| + obj.title = Faker::Lorem.sentence + obj.project = Factory(:project) +end diff --git a/spec/models/activity_observer_spec.rb b/spec/models/activity_observer_spec.rb new file mode 100644 index 00000000..c8f09159 --- /dev/null +++ b/spec/models/activity_observer_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe ActivityObserver do + let(:project) { Factory :project } + + describe "Merge Request created" do + before do + @merge_request = Factory :merge_request, :project => project + @event = Event.last + end + + it { @event.should_not be_nil } + it { @event.project.should == project } + it { @event.action.should == Event::Created } + it { @event.target.should == @merge_request } + end + + describe "Issue created" do + before do + @issue = Factory :issue, :project => project + @event = Event.last + end + + it { @event.should_not be_nil } + it { @event.project.should == project } + it { @event.action.should == Event::Created } + it { @event.target.should == @issue } + end + + describe "Issue commented" do + before do + @issue = Factory :issue, :project => project + @note = Factory :note, :noteable => @issue, :project => project + @event = Event.last + end + + it { @event.should_not be_nil } + it { @event.project.should == project } + it { @event.action.should == Event::Commented } + it { @event.target.should == @note } + end +end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 5aacac0e..50266fcf 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -2,18 +2,31 @@ # # Table name: events # -# id :integer not null, primary key -# data_type :string(255) -# data_id :string(255) -# title :string(255) -# data :text -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# target_type :string(255) +# target_id :integer +# title :string(255) +# data :text +# project_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# action :integer # require 'spec_helper' describe Event do - pending "add some examples to (or delete) #{__FILE__}" + describe "Associations" do + it { should belong_to(:project) } + end + + describe "Creation" do + before do + @event = Factory :event + end + + it "should create a valid event" do + @event.should be_valid + end + end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index c3260a8d..e97aaec1 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' describe Project do describe "Associations" do + it { should have_many(:events) } it { should have_many(:users) } it { should have_many(:users_projects) } it { should have_many(:issues) }