user_notification 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +1 -0
  5. data/Rakefile +18 -0
  6. data/lib/generators/user_notification/migration/migration_generator.rb +17 -0
  7. data/lib/generators/user_notification/migration/templates/migration.rb +24 -0
  8. data/lib/generators/user_notification/notification/notification_generator.rb +17 -0
  9. data/lib/generators/user_notification/notification/templates/notification.rb +3 -0
  10. data/lib/generators/user_notification.rb +14 -0
  11. data/lib/user_notification/actions/creation.rb +15 -0
  12. data/lib/user_notification/actions/destruction.rb +15 -0
  13. data/lib/user_notification/actions/update.rb +15 -0
  14. data/lib/user_notification/activity.rb +6 -0
  15. data/lib/user_notification/common.rb +342 -0
  16. data/lib/user_notification/config.rb +63 -0
  17. data/lib/user_notification/models/activist.rb +9 -0
  18. data/lib/user_notification/models/adapter.rb +5 -0
  19. data/lib/user_notification/models/notification.rb +13 -0
  20. data/lib/user_notification/models/trackable.rb +9 -0
  21. data/lib/user_notification/orm/active_record/activist.rb +48 -0
  22. data/lib/user_notification/orm/active_record/adapter.rb +16 -0
  23. data/lib/user_notification/orm/active_record/notification.rb +24 -0
  24. data/lib/user_notification/orm/active_record/trackable.rb +15 -0
  25. data/lib/user_notification/orm/active_record.rb +5 -0
  26. data/lib/user_notification/orm/mongo_mapper/activist.rb +46 -0
  27. data/lib/user_notification/orm/mongo_mapper/adapter.rb +12 -0
  28. data/lib/user_notification/orm/mongo_mapper/notification.rb +33 -0
  29. data/lib/user_notification/orm/mongo_mapper/trackable.rb +11 -0
  30. data/lib/user_notification/orm/mongo_mapper.rb +4 -0
  31. data/lib/user_notification/orm/mongoid/activist.rb +45 -0
  32. data/lib/user_notification/orm/mongoid/adapter.rb +12 -0
  33. data/lib/user_notification/orm/mongoid/notification.rb +26 -0
  34. data/lib/user_notification/orm/mongoid/trackable.rb +11 -0
  35. data/lib/user_notification/orm/mongoid.rb +4 -0
  36. data/lib/user_notification/renderable.rb +118 -0
  37. data/lib/user_notification/roles/deactivatable.rb +42 -0
  38. data/lib/user_notification/roles/tracked.rb +183 -0
  39. data/lib/user_notification/utility/store_controller.rb +37 -0
  40. data/lib/user_notification/utility/view_helpers.rb +26 -0
  41. data/lib/user_notification/version.rb +4 -0
  42. data/lib/user_notification.rb +68 -0
  43. data/test/migrations/001_create_notifications.rb +24 -0
  44. data/test/migrations/002_create_articles.rb +11 -0
  45. data/test/migrations/003_create_users.rb +8 -0
  46. data/test/migrations/004_add_nonstandard_to_notifications.rb +7 -0
  47. data/test/mongo_mapper.yml +4 -0
  48. data/test/mongoid.yml +6 -0
  49. data/test/test_activist.rb +56 -0
  50. data/test/test_common.rb +168 -0
  51. data/test/test_controller_integration.rb +41 -0
  52. data/test/test_generators.rb +30 -0
  53. data/test/test_helper.rb +124 -0
  54. data/test/test_notification.rb +67 -0
  55. data/test/test_tracking.rb +378 -0
  56. data/test/test_view_helpers.rb +36 -0
  57. data/test/views/layouts/_notification.erb +1 -0
  58. data/test/views/user_notification/_test.erb +8 -0
  59. metadata +260 -0
@@ -0,0 +1,37 @@
1
+ module UserNotification
2
+ # @private
3
+ @@controllers = Hash.new
4
+ # Lambda called after the thread is destroyed.
5
+ Finalizer = lambda { |id|
6
+ @@controllers.delete id
7
+ }
8
+
9
+ class << self
10
+ # Setter for remembering controller instance
11
+ def set_controller(controller)
12
+ unless @@controllers.has_key?(Thread.current.object_id)
13
+ ObjectSpace.define_finalizer Thread.current, Finalizer
14
+ end if RUBY_VERSION != "1.9.3"
15
+ @@controllers[Thread.current.object_id] = controller
16
+ end
17
+
18
+ # Getter for accessing the controller instance
19
+ def get_controller
20
+ @@controllers[Thread.current.object_id]
21
+ end
22
+ end
23
+
24
+ # Module included in controllers to allow p_a access to controller instance
25
+ module StoreController
26
+ extend ActiveSupport::Concern
27
+
28
+ included do
29
+ before_filter :store_controller_for_user_notification
30
+ end
31
+
32
+ # Before filter executed to remember current controller
33
+ def store_controller_for_user_notification
34
+ UserNotification.set_controller(self)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ # Provides a shortcut from views to the rendering method.
2
+ module UserNotification
3
+ # Module extending ActionView::Base and adding `render_notification` helper.
4
+ module ViewHelpers
5
+ # View helper for rendering an notification, calls {UserNotification::Notification#render} internally.
6
+ def render_notification notifications, options = {}
7
+ if notifications.is_a? UserNotification::Notification
8
+ notifications.render self, options
9
+ elsif notifications.respond_to?(:map)
10
+ # depend on ORMs to fetch as needed
11
+ # maybe we can support Postgres streaming with this?
12
+ notifications.map {|notification| notification.render self, options.dup }.join.html_safe
13
+ end
14
+ end
15
+ alias_method :render_notifications, :render_notification
16
+
17
+ # Helper for setting content_for in notification partial, needed to
18
+ # flush remains in between partial renders.
19
+ def single_content_for(name, content = nil, &block)
20
+ @view_flow.set(name, ActiveSupport::SafeBuffer.new)
21
+ content_for(name, content, &block)
22
+ end
23
+ end
24
+
25
+ ActionView::Base.class_eval { include ViewHelpers }
26
+ end
@@ -0,0 +1,4 @@
1
+ module UserNotification
2
+ # A constant with gem's version
3
+ VERSION = '0.0.1'
4
+ end
@@ -0,0 +1,68 @@
1
+ require 'active_support'
2
+ require 'action_view'
3
+ # +user_notification+ keeps track of changes made to models
4
+ # and allows you to display them to the users.
5
+ #
6
+ # Check {UserNotification::Tracked::ClassMethods#tracked} for more details about customizing and specifying
7
+ # ownership to users.
8
+ module UserNotification
9
+ extend ActiveSupport::Concern
10
+ extend ActiveSupport::Autoload
11
+
12
+ autoload :Notification, 'user_notification/models/notification'
13
+ autoload :Activist, 'user_notification/models/activist'
14
+ autoload :Adapter, 'user_notification/models/adapter'
15
+ autoload :Trackable, 'user_notification/models/trackable'
16
+ autoload :Common
17
+ autoload :Config
18
+ autoload :Creation, 'user_notification/actions/creation.rb'
19
+ autoload :Deactivatable,'user_notification/roles/deactivatable.rb'
20
+ autoload :Destruction, 'user_notification/actions/destruction.rb'
21
+ autoload :Renderable
22
+ autoload :Tracked, 'user_notification/roles/tracked.rb'
23
+ autoload :Update, 'user_notification/actions/update.rb'
24
+ autoload :VERSION
25
+
26
+ # Switches UserNotification on or off.
27
+ # @param value [Boolean]
28
+ # @since 0.5.0
29
+ def self.enabled=(value)
30
+ UserNotification.config.enabled = value
31
+ end
32
+
33
+ # Returns `true` if UserNotification is on, `false` otherwise.
34
+ # Enabled by default.
35
+ # @return [Boolean]
36
+ # @since 0.5.0
37
+ def self.enabled?
38
+ !!UserNotification.config.enabled
39
+ end
40
+
41
+ # Returns UserNotification's configuration object.
42
+ # @since 0.5.0
43
+ def self.config
44
+ @@config ||= UserNotification::Config.instance
45
+ end
46
+
47
+ # Method used to choose which ORM to load
48
+ # when UserNotification::Notification class is being autoloaded
49
+ def self.inherit_orm(model="Notification")
50
+ orm = UserNotification.config.orm
51
+ require "user_notification/orm/#{orm.to_s}"
52
+ "UserNotification::ORM::#{orm.to_s.classify}::#{model}".constantize
53
+ end
54
+
55
+ # Module to be included in ActiveRecord models. Adds required functionality.
56
+ module Model
57
+ extend ActiveSupport::Concern
58
+ included do
59
+ include Common
60
+ include Deactivatable
61
+ include Tracked
62
+ include Activist # optional associations by recipient|owner
63
+ end
64
+ end
65
+ end
66
+
67
+ require 'user_notification/utility/store_controller'
68
+ require 'user_notification/utility/view_helpers'
@@ -0,0 +1,24 @@
1
+ # Migration responsible for creating a table with notifications
2
+ class CreateNotifications < ActiveRecord::Migration
3
+ # Create table
4
+ def self.up
5
+ create_table :notifications do |t|
6
+ t.belongs_to :trackable, :polymorphic => true
7
+ t.belongs_to :owner, :polymorphic => true
8
+ t.string :key
9
+ t.text :parameters
10
+ t.belongs_to :recipient, :polymorphic => true
11
+ t.boolwan :read, default: false
12
+
13
+ t.timestamps
14
+ end
15
+
16
+ add_index :notifications, [:trackable_id, :trackable_type]
17
+ add_index :notifications, [:owner_id, :owner_type]
18
+ add_index :notifications, [:recipient_id, :recipient_type]
19
+ end
20
+ # Drop table
21
+ def self.down
22
+ drop_table :notifications
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ class CreateArticles < ActiveRecord::Migration
2
+ def self.up
3
+ puts "creating"
4
+ create_table :articles do |t|
5
+ t.string :name
6
+ t.boolean :published
7
+ t.belongs_to :user
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :name
5
+ t.timestamps
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ class AddNonstandardToNotifications < ActiveRecord::Migration
2
+ def change
3
+ change_table :notifications do |t|
4
+ t.string :nonstandard
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ test:
2
+ host: 127.0.0.1
3
+ port: 27017
4
+ database: user_notification_test
data/test/mongoid.yml ADDED
@@ -0,0 +1,6 @@
1
+ test:
2
+ sessions:
3
+ default:
4
+ hosts:
5
+ - 127.0.0.1:27017
6
+ database: user_notification_test
@@ -0,0 +1,56 @@
1
+ require 'test_helper'
2
+
3
+ describe UserNotification::Activist do
4
+ it 'adds owner association' do
5
+ klass = article
6
+ klass.must_respond_to :activist
7
+ klass.activist
8
+ klass.new.must_respond_to :notifications
9
+ case ENV["PA_ORM"]
10
+ when "active_record"
11
+ klass.reflect_on_association(:notifications_as_owner).options[:as].must_equal :owner
12
+ when "mongoid"
13
+ klass.reflect_on_association(:notifications_as_owner).options[:inverse_of].must_equal :owner
14
+ when "mongo_mapper"
15
+ klass.associations[:notifications_as_owner].options[:as].must_equal :owner
16
+ end
17
+
18
+ if ENV["PA_ORM"] == "mongo_mapper"
19
+ klass.associations[:notifications_as_owner].options[:class_name].must_equal "::UserNotification::Notification"
20
+ else
21
+ klass.reflect_on_association(:notifications_as_owner).options[:class_name].must_equal "::UserNotification::Notification"
22
+ end
23
+ end
24
+
25
+ it 'returns notifications from association' do
26
+ case UserNotification::Config.orm
27
+ when :active_record
28
+ class ActivistUser < ActiveRecord::Base
29
+ include UserNotification::Model
30
+ self.table_name = 'users'
31
+ activist
32
+ end
33
+ when :mongoid
34
+ class ActivistUser
35
+ include Mongoid::Document
36
+ include UserNotification::Model
37
+ activist
38
+
39
+ field :name, type: String
40
+ end
41
+ when :mongo_mapper
42
+ class ActivistUser
43
+ include MongoMapper::Document
44
+ include UserNotification::Model
45
+ activist
46
+
47
+ key :name, String
48
+ end
49
+ end
50
+ owner = ActivistUser.create(:name => "Peter Pan")
51
+ a = article(owner: owner).new
52
+ a.save
53
+
54
+ owner.notifications_as_owner.length.must_equal 1
55
+ end
56
+ end
@@ -0,0 +1,168 @@
1
+ require 'test_helper'
2
+
3
+ describe UserNotification::Common do
4
+ before do
5
+ @owner = User.create(:name => "Peter Pan")
6
+ @recipient = User.create(:name => "Bruce Wayne")
7
+ @options = {:params => {:author_name => "Peter",
8
+ :summary => "Default summary goes here..."},
9
+ :owner => @owner, :recipient => @recipient}
10
+ end
11
+ subject { article(@options).new }
12
+
13
+ it 'prioritizes parameters passed to #create_notification' do
14
+ subject.save
15
+ subject.create_notification(:test, params: {author_name: 'Pan'}).parameters[:author_name].must_equal 'Pan'
16
+ subject.create_notification(:test, parameters: {author_name: 'Pan'}).parameters[:author_name].must_equal 'Pan'
17
+ subject.create_notification(:test, params: {author_name: nil}).parameters[:author_name].must_be_nil
18
+ subject.create_notification(:test, parameters: {author_name: nil}).parameters[:author_name].must_be_nil
19
+ end
20
+
21
+ it 'prioritizes owner passed to #create_notification' do
22
+ subject.save
23
+ subject.create_notification(:test, owner: @recipient).owner.must_equal @recipient
24
+ subject.create_notification(:test, owner: nil).owner.must_be_nil
25
+ end
26
+
27
+ it 'prioritizes recipient passed to #create_notification' do
28
+ subject.save
29
+ subject.create_notification(:test, recipient: @owner).recipient.must_equal @owner
30
+ subject.create_notification(:test, recipient: nil).recipient.must_be_nil
31
+ end
32
+
33
+ it 'uses global fields' do
34
+ subject.save
35
+ notification = subject.notifications.last
36
+ notification.parameters.must_equal @options[:params]
37
+ notification.owner.must_equal @owner
38
+ end
39
+
40
+ it 'allows custom fields' do
41
+ subject.save
42
+ subject.create_notification :with_custom_fields, nonstandard: "Custom allowed"
43
+ subject.notifications.last.nonstandard.must_equal "Custom allowed"
44
+ end
45
+
46
+ it '#create_notification returns a new notification object' do
47
+ subject.save
48
+ subject.create_notification("some.key").wont_be_nil
49
+ end
50
+
51
+ it 'allows passing owner through #create_notification' do
52
+ article = article().new
53
+ article.save
54
+ notification = article.create_notification("some.key", :owner => @owner)
55
+ notification.owner.must_equal @owner
56
+ end
57
+
58
+ it 'allows resolving custom fields' do
59
+ subject.name = "Resolving is great"
60
+ subject.published = true
61
+ subject.save
62
+ subject.create_notification :with_custom_fields, nonstandard: :name
63
+ subject.notifications.last.nonstandard.must_equal "Resolving is great"
64
+ subject.create_notification :with_custom_fields_2, nonstandard: proc {|_, model| model.published.to_s}
65
+ subject.notifications.last.nonstandard.must_equal "true"
66
+ end
67
+
68
+ it 'inherits instance parameters' do
69
+ subject.notification :params => {:author_name => "Michael"}
70
+ subject.save
71
+ notification = subject.notifications.last
72
+
73
+ notification.parameters[:author_name].must_equal "Michael"
74
+ end
75
+
76
+ it 'accepts instance recipient' do
77
+ subject.notification :recipient => @recipient
78
+ subject.save
79
+ subject.notifications.last.recipient.must_equal @recipient
80
+ end
81
+
82
+ it 'accepts instance owner' do
83
+ subject.notification :owner => @owner
84
+ subject.save
85
+ subject.notifications.last.owner.must_equal @owner
86
+ end
87
+
88
+ it 'accepts owner as a symbol' do
89
+ klass = article(:owner => :user)
90
+ @article = klass.new(:user => @owner)
91
+ @article.save
92
+ notification = @article.notifications.last
93
+
94
+ notification.owner.must_equal @owner
95
+ end
96
+
97
+ describe '#extract_key' do
98
+ describe 'for class#notification_key method' do
99
+ before do
100
+ @article = article(:owner => :user).new(:user => @owner)
101
+ end
102
+
103
+ it 'assigns key to value of notification_key if set' do
104
+ def @article.notification_key; "my_custom_key" end
105
+
106
+ @article.extract_key(:create, {}).must_equal "my_custom_key"
107
+ end
108
+
109
+ it 'assigns key based on class name as fallback' do
110
+ def @article.notification_key; nil end
111
+
112
+ @article.extract_key(:create).must_equal "article.create"
113
+ end
114
+
115
+ it 'assigns key value from options hash' do
116
+ @article.extract_key(:create, :key => :my_custom_key).must_equal "my_custom_key"
117
+ end
118
+ end
119
+
120
+ describe 'for camel cased classes' do
121
+ before do
122
+ class CamelCase < article(:owner => :user)
123
+ def self.name; 'CamelCase' end
124
+ end
125
+ @camel_case = CamelCase.new
126
+ end
127
+
128
+ it 'assigns generates key from class name' do
129
+ @camel_case.extract_key(:create, {}).must_equal "camel_case.create"
130
+ end
131
+ end
132
+
133
+ describe 'for namespaced classes' do
134
+ before do
135
+ module ::MyNamespace;
136
+ class CamelCase < article(:owner => :user)
137
+ def self.name; 'MyNamespace::CamelCase' end
138
+ end
139
+ end
140
+ @namespaced_camel_case = MyNamespace::CamelCase.new
141
+ end
142
+
143
+ it 'assigns key value from options hash' do
144
+ @namespaced_camel_case.extract_key(:create, {}).must_equal "my_namespace_camel_case.create"
145
+ end
146
+ end
147
+ end
148
+
149
+ # no key implicated or given
150
+ specify { ->{subject.prepare_settings}.must_raise UserNotification::NoKeyProvided }
151
+
152
+ describe 'resolving values' do
153
+ it 'allows procs with models and controllers' do
154
+ context = mock('context')
155
+ context.expects(:accessor).times(2).returns(5)
156
+ controller = mock('controller')
157
+ controller.expects(:current_user).returns(:cu)
158
+ UserNotification.set_controller(controller)
159
+ p = proc {|controller, model|
160
+ assert_equal :cu, controller.current_user
161
+ assert_equal 5, model.accessor
162
+ }
163
+ UserNotification.resolve_value(context, p)
164
+ UserNotification.resolve_value(context, :accessor)
165
+ end
166
+ end
167
+
168
+ end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ class StoringController < ActionView::TestCase::TestController
4
+ include UserNotification::StoreController
5
+ include ActionController::Testing::ClassMethods
6
+ end
7
+
8
+ describe UserNotification::StoreController do
9
+ it 'stores controller' do
10
+ controller = StoringController.new
11
+ UserNotification.set_controller(controller)
12
+ controller.must_be_same_as UserNotification.instance_eval { class_variable_get(:@@controllers)[Thread.current.object_id] }
13
+ controller.must_be_same_as UserNotification.get_controller
14
+ end
15
+
16
+ it 'stores controller with a filter in controller' do
17
+ controller = StoringController.new
18
+ controller._process_action_callbacks.select {|c| c.kind == :before}.map(&:filter).must_include :store_controller_for_user_notification
19
+ controller.instance_eval { store_controller_for_user_notification }
20
+ controller.must_be_same_as UserNotification.class_eval { class_variable_get(:@@controllers)[Thread.current.object_id] }
21
+ end
22
+
23
+ it 'stores controller in a threadsafe way' do
24
+ reset_controllers
25
+ UserNotification.set_controller(1)
26
+ UserNotification.get_controller.must_equal 1
27
+
28
+ a = Thread.new {
29
+ UserNotification.set_controller(2)
30
+ UserNotification.get_controller.must_equal 2
31
+ }
32
+
33
+ UserNotification.get_controller.must_equal 1
34
+ # cant really test finalizers though
35
+ end
36
+
37
+ private
38
+ def reset_controllers
39
+ UserNotification.class_eval { class_variable_set(:@@controllers, {}) }
40
+ end
41
+ end
@@ -0,0 +1,30 @@
1
+ if ENV["PA_ORM"] == "active_record"
2
+
3
+ require 'test_helper'
4
+ require 'rails/generators/test_case'
5
+ require 'generators/user_notification/notification/notification_generator'
6
+ require 'generators/user_notification/migration/migration_generator'
7
+
8
+ class TestNotificationGenerator < Rails::Generators::TestCase
9
+ tests UserNotification::Generators::NotificationGenerator
10
+ destination File.expand_path("../tmp", File.dirname(__FILE__))
11
+ setup :prepare_destination
12
+
13
+ def test_generating_notification_model
14
+ run_generator
15
+ assert_file "app/models/notification.rb"
16
+ end
17
+ end
18
+
19
+ class TestMigrationGenerator < Rails::Generators::TestCase
20
+ tests UserNotification::Generators::MigrationGenerator
21
+ destination File.expand_path("../tmp", File.dirname(__FILE__))
22
+ setup :prepare_destination
23
+
24
+ def test_generating_notification_model
25
+ run_generator
26
+ assert_migration "db/migrate/create_notifications.rb"
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,124 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup(:default, :test)
4
+
5
+ unless ENV['NOCOV']
6
+ require 'simplecov'
7
+ SimpleCov.start do
8
+ add_filter "/test/"
9
+ end
10
+ end
11
+ $:.unshift File.expand_path('../../lib/', __FILE__)
12
+ require 'active_support/testing/setup_and_teardown'
13
+ require 'user_notification'
14
+ require 'minitest/autorun'
15
+ require 'minitest/pride' if ENV['WITH_PRIDE'] or ENV['PRIDE']
16
+
17
+ UserNotification::Config.orm = (ENV['PA_ORM'] || :active_record)
18
+
19
+ case UserNotification::Config.orm
20
+ when :active_record
21
+ require 'active_record'
22
+ require 'active_record/connection_adapters/sqlite3_adapter'
23
+ require 'stringio' # silence the output
24
+ $stdout = StringIO.new # from migrator
25
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
26
+ ActiveRecord::Migrator.migrate(File.expand_path('../migrations', __FILE__))
27
+ $stdout = STDOUT
28
+
29
+ def article(options = {})
30
+ klass = Class.new(ActiveRecord::Base) do
31
+ self.table_name = 'articles'
32
+ include UserNotification::Model
33
+ tracked options
34
+ belongs_to :user
35
+
36
+ def self.name
37
+ "Article"
38
+ end
39
+
40
+ if ::ActiveRecord::VERSION::MAJOR < 4
41
+ attr_accessible :name, :published, :user
42
+ end
43
+ end
44
+ klass
45
+ end
46
+ class User < ActiveRecord::Base; end
47
+
48
+ if ::ActiveRecord::VERSION::MAJOR < 4
49
+ UserNotification::Notification.class_eval do
50
+ attr_accessible :nonstandard
51
+ end
52
+ end
53
+ when :mongoid
54
+ require 'mongoid'
55
+
56
+ Mongoid.load!(File.expand_path("test/mongoid.yml"), :test)
57
+
58
+ class User
59
+ include Mongoid::Document
60
+ include Mongoid::Timestamps
61
+
62
+ has_many :articles
63
+
64
+ field :name, type: String
65
+ end
66
+
67
+ class Article
68
+ include Mongoid::Document
69
+ include Mongoid::Timestamps
70
+ include UserNotification::Model
71
+
72
+ belongs_to :user
73
+
74
+ field :name, type: String
75
+ field :published, type: Boolean
76
+ end
77
+
78
+ def article(options = {})
79
+ Article.class_eval do
80
+ set_user_notification_class_defaults
81
+ tracked options
82
+ end
83
+ Article
84
+ end
85
+
86
+ when :mongo_mapper
87
+ require 'mongo_mapper'
88
+
89
+ config = YAML.load(File.read("test/mongo_mapper.yml"))
90
+ MongoMapper.setup(config, :test)
91
+
92
+ class User
93
+ include MongoMapper::Document
94
+
95
+ has_many :articles
96
+
97
+ key :name, String
98
+ timestamps!
99
+ end
100
+
101
+ class Article
102
+ include MongoMapper::Document
103
+ include UserNotification::Model
104
+
105
+ belongs_to :user
106
+
107
+ key :name, String
108
+ key :published, Boolean
109
+ end
110
+
111
+ def article(options = {})
112
+ Article.class_eval do
113
+ set_user_notification_class_defaults
114
+ tracked options
115
+ end
116
+ Article
117
+ end
118
+ end
119
+
120
+ class ViewSpec < MiniTest::Spec
121
+ include ActiveSupport::Testing::SetupAndTeardown
122
+ include ActionView::TestCase::Behavior
123
+ end
124
+ MiniTest::Spec.register_spec_type(/Rendering$/, ViewSpec)