Commit fed22b92dd594209d4d4217bd4b5e90408d23de9

Authored by Jared Pace
1 parent 0c314215
Exists in master and in 1 other branch production

Allow users to watch projects and have projects through those watchers

app/models/user.rb
@@ -8,7 +8,24 @@ class User @@ -8,7 +8,24 @@ class User
8 8
9 field :name 9 field :name
10 field :admin, :type => Boolean, :default => false 10 field :admin, :type => Boolean, :default => false
  11 +
  12 + after_destroy :destroy_watchers
11 13
12 validates_presence_of :name 14 validates_presence_of :name
13 - 15 +
  16 + # Mongoid doesn't seem to currently support
  17 + # referencing embedded documents
  18 + def watchers
  19 + App.all.map(&:watchers).flatten.select {|w| w.user_id == id}
  20 + end
  21 +
  22 + def apps
  23 + App.where('watchers.user_id' => id)
  24 + end
  25 +
  26 + protected
  27 +
  28 + def destroy_watchers
  29 + watchers.each(&:destroy)
  30 + end
14 end 31 end
app/models/watcher.rb
@@ -5,7 +5,14 @@ class Watcher @@ -5,7 +5,14 @@ class Watcher
5 field :email 5 field :email
6 6
7 embedded_in :app, :inverse_of => :watchers 7 embedded_in :app, :inverse_of => :watchers
  8 + referenced_in :user
8 9
9 - validates_presence_of :email 10 + validate :ensure_user_or_email
  11 +
  12 + protected
  13 +
  14 + def ensure_user_or_email
  15 + errors.add(:base, "You must specify either a user or an email address") unless user.present? || email.present?
  16 + end
10 17
11 end 18 end
spec/controllers/apps_controller_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 -describe AppsController, :focused => true do 3 +describe AppsController do
4 4
5 it_requires_authentication 5 it_requires_authentication
6 it_requires_admin_privileges :for => {:new => :get, :edit => :get, :create => :post, :update => :put, :destroy => :delete} 6 it_requires_admin_privileges :for => {:new => :get, :edit => :get, :create => :post, :update => :put, :destroy => :delete}
spec/models/user_spec.rb
@@ -10,4 +10,33 @@ describe User do @@ -10,4 +10,33 @@ describe User do
10 end 10 end
11 end 11 end
12 12
  13 + context 'Watchers' do
  14 +
  15 + it 'has many watchers' do
  16 + user = Factory(:user)
  17 + watcher = Factory(:watcher, :user => user, :email => nil)
  18 + user.watchers.should_not be_empty
  19 + user.watchers.should include(watcher)
  20 + end
  21 +
  22 + it "destroys any related watchers when it is destroyed" do
  23 + user = Factory(:user)
  24 + app = Factory(:app)
  25 + watcher = Factory(:watcher, :app => app, :user => user, :email => nil)
  26 + user.watchers.should_not be_empty
  27 + user.destroy
  28 + app.reload.watchers.should_not include(watcher)
  29 + end
  30 +
  31 + it "has many apps through watchers" do
  32 + user = Factory(:user)
  33 + watched_app = Factory(:app)
  34 + unwatched_app = Factory(:app)
  35 + watcher = Factory(:watcher, :app => watched_app, :user => user, :email => nil)
  36 + user.apps.all.should include(watched_app)
  37 + user.apps.all.should_not include(unwatched_app)
  38 + end
  39 +
  40 + end
  41 +
13 end 42 end
spec/models/watcher_spec.rb
@@ -3,11 +3,22 @@ require 'spec_helper' @@ -3,11 +3,22 @@ require 'spec_helper'
3 describe Watcher do 3 describe Watcher do
4 4
5 context 'validations' do 5 context 'validations' do
6 - it 'requires an email address' do  
7 - watcher = Factory.build(:watcher, :email => nil) 6 + it 'requires an email address or an associated user' do
  7 + watcher = Factory.build(:watcher, :email => nil, :user => nil)
8 watcher.should_not be_valid 8 watcher.should_not be_valid
9 - watcher.errors[:email].should include("can't be blank") 9 + watcher.errors[:base].should include("You must specify either a user or an email address")
  10 +
  11 + watcher.email = 'watcher@example.com'
  12 + watcher.should be_valid
  13 +
  14 + watcher.email = nil
  15 + watcher.should_not be_valid
  16 +
  17 + watcher.user = Factory(:user)
  18 + watcher.should be_valid
10 end 19 end
  20 +
  21 +
11 end 22 end
12 23
13 end 24 end