live-activity 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fe8df6a8d020963d1afb51c4f68a711008cf404a
4
+ data.tar.gz: 6c9215b22a933a080d89f809e6278acda4d47da5
5
+ SHA512:
6
+ metadata.gz: 85250962c209b1a30435eb3feedc56b449db92f559b514aec2d000038ed31e95475a5520ef924f59f5351592d42910b8b872d0cf70223cf469e25e799d719403
7
+ data.tar.gz: b3a405bce7b9146729f35be6c59c78a7c66c6b5b8fe9719517aafb45b4eb3b6b19646e7c82e3295f089f6c167474da9aa8096efa992920ecbe36551edfc32dbc
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,2 @@
1
+ rvm:
2
+ - 1.9.2
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development, :test do
4
+ gem 'sqlite3', '~> 1.3.7'
5
+ end
6
+
7
+ # Specify your gem's dependencies in live_activity.gemspec
8
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Andreas Saebjoernsen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # LiveActivity
2
+
3
+ LiveActivity is a simple Ruby activity stream gem for use with the ActiveRecord ODM framework.
4
+
5
+ This gem is inspired by Streama by Christopher Pappas.
6
+
7
+ [![Build Status](https://secure.travis-ci.org/digitalplaywright/live-activity.png)](http://travis-ci.org/digitalplaywright/live-activity) [![Dependency Status](https://gemnasium.com/digitalplaywright/live-activity.png)](https://gemnasium.com/digitalplaywright/live-activity) [![Code Climate](https://codeclimate.com/github/digitalplaywright/live-activity.png)](https://codeclimate.com/github/digitalplaywright/live-activity)
8
+
9
+
10
+ ## Install
11
+
12
+ gem install live_activity
13
+
14
+ ## Usage
15
+
16
+ ### Create migration for activities and migrate the database (in your Rails project):
17
+
18
+ ```ruby
19
+ rails g public_activity:migration
20
+ rake db:migrate
21
+ ```
22
+
23
+ A join table must also be created for all receivers. E.g if users are receivers:
24
+
25
+ ``` ruby
26
+ create_table :activities_users, :id => false do |t|
27
+ t.references :activity, :user
28
+ end
29
+
30
+ add_index :activities_users, [:activity_id, :user_id ]
31
+ ```
32
+
33
+ ### Define Activities
34
+
35
+ Create an Activity model and define the activities and the fields you would like to cache within the activity.
36
+
37
+ An activity consists of an actor, a verb, an act_object, and a target.
38
+
39
+ ``` ruby
40
+ class Activity < ActiveRecord::Base
41
+ include LiveActivity::Activity
42
+
43
+ has_and_belongs_to_many :users
44
+
45
+ activity :new_enquiry do
46
+ actor :User
47
+ act_object :Article
48
+ act_target :Volume
49
+ end
50
+ end
51
+ ```
52
+
53
+ The activity verb is implied from the activity name, in the above example the verb is :new_enquiry
54
+
55
+ The act_object may be the entity performing the activity, or the entity on which the activity was performed.
56
+ e.g John(actor) shared a video(act_object)
57
+
58
+ The target is the act_object that the verb is enacted on.
59
+ e.g. Geraldine(actor) posted a photo(act_object) to her album(target)
60
+
61
+ This is based on the Activity Streams 1.0 specification (http://activitystrea.ms)
62
+
63
+ ### Setup Actors
64
+
65
+ Include the Actor module in a class and override the default followers method.
66
+
67
+ ``` ruby
68
+ class User < ActiveRecord::Base
69
+ include LiveActivity::Actor
70
+
71
+ has_and_belongs_to_many :activities
72
+
73
+ end
74
+ ```
75
+
76
+
77
+
78
+ ### Publishing Activity
79
+
80
+ In your controller or background worker:
81
+
82
+ ``` ruby
83
+ current_user.publish_activity(:new_enquiry, :act_object => @enquiry, :target => @listing)
84
+ ```
85
+
86
+ This will publish the activity to the mongoid act_objects returned by the #followers method in the Actor.
87
+
88
+ To send your activity to different receievers, pass in an additional :receivers parameter.
89
+
90
+ ``` ruby
91
+ current_user.publish_activity(:new_enquiry, :act_object => @enquiry, :target => @listing, :receivers => :friends) # calls friends method
92
+ ```
93
+
94
+ ``` ruby
95
+ current_user.publish_activity(:new_enquiry, :act_object => @enquiry, :target => @listing, :receivers => current_user.find(:all, :conditions => {:group_id => mygroup}))
96
+ ```
97
+
98
+ ## Retrieving Activity
99
+
100
+ To retrieve all activity for an actor
101
+
102
+ ``` ruby
103
+ current_user.activity_stream
104
+ ```
105
+
106
+ To retrieve and filter to a particular activity type
107
+
108
+ ``` ruby
109
+ current_user.activity_stream(:verb => 'new_enquiry')
110
+ ```
111
+
112
+ #### Options
113
+
114
+ Additional options can be required:
115
+
116
+ ``` ruby
117
+ class Activity < ActiveRecord::Base
118
+ include LiveActivity::Activity
119
+
120
+ has_and_belongs_to_many :users
121
+
122
+ activity :new_enquiry do
123
+ actor :User
124
+ act_object :Article
125
+ act_target :Volume
126
+ option :country
127
+ option :city
128
+ end
129
+ end
130
+ ```
131
+
132
+ The option fields are stored using the ActiveRecord 'store' feature.
133
+
134
+
135
+ #### Bond type
136
+
137
+ A verb can have one bond type. This bond type can be used to classify and quickly retrieve
138
+ activity feed items that belong to a particular aggregate feed, like e.g the global feed.
139
+
140
+ ``` ruby
141
+ class Activity < ActiveRecord::Base
142
+ include LiveActivity::Activity
143
+
144
+ has_and_belongs_to_many :users
145
+
146
+ activity :new_enquiry do
147
+ actor :User
148
+ act_object :Article
149
+ act_target :Volume
150
+ bond_type :global
151
+ end
152
+ end
153
+ ```
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'yard'
4
+ require 'yard/rake/yardoc_task'
5
+ require 'rake/testtask'
6
+
7
+ task :default => :test
8
+
9
+ desc 'Generate documentation for the live_stream plugin.'
10
+ YARD::Rake::YardocTask.new do |doc|
11
+ doc.files = ['lib/**/*.rb']
12
+ end
13
+
14
+ Rake::TestTask.new do |t|
15
+ t.libs << "test"
16
+ t.test_files = FileList['test/test*.rb', 'test/unit/*_test.rb']
17
+ end
18
+
@@ -0,0 +1,17 @@
1
+ require 'generators/live_stream'
2
+ require 'rails/generators/active_record'
3
+
4
+ module LiveActivity
5
+ module Generators
6
+ # Activity generator that creates activity model file from template
7
+ class ActivityGenerator < ActiveRecord::Generators::Base
8
+ extend Base
9
+
10
+ argument :name, :type => :string, :default => 'activity'
11
+ # Create model in project's folder
12
+ def generate_files
13
+ copy_file 'activity.rb', "app/models/#{name}.rb"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ # Activity model for customisation & custom methods
2
+ class Activity < ActiveRecord::Base
3
+ include LiveActivity::Activity
4
+
5
+ end
@@ -0,0 +1,17 @@
1
+ require 'generators/live_stream'
2
+ require 'rails/generators/active_record'
3
+
4
+ module LiveStream
5
+ module Generators
6
+ # Migration generator that creates migration file from template
7
+ class MigrationGenerator < ActiveRecord::Generators::Base
8
+ extend Base
9
+
10
+ argument :name, :type => :string, :default => 'create_activities'
11
+ # Create migration in project's folder
12
+ def generate_files
13
+ migration_template 'migration.rb', "db/migrate/#{name}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ # Migration responsible for creating a table with activities
2
+ class CreateActivities < ActiveRecord::Migration
3
+ # Create table
4
+ def self.up
5
+ create_table :activities do |t|
6
+ t.belongs_to :actor, :polymorphic => true
7
+ t.belongs_to :act_object, :polymorphic => true
8
+ t.belongs_to :act_target, :polymorphic => true
9
+
10
+ t.string :verb
11
+ t.string :description
12
+ t.string :options
13
+ t.string :bond_type
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ create_table :activities_users, :id => false do |t|
19
+ t.references :activity, :user
20
+ end
21
+
22
+ add_index :activities_users, [:activity_id, :user_id ]
23
+
24
+ add_index :activities, [:verb]
25
+ add_index :activities, [:actor_id, :actor_type]
26
+ add_index :activities, [:act_object_id, :act_object_type]
27
+ add_index :activities, [:act_target_id, :act_target_type]
28
+ end
29
+ # Drop table
30
+ def self.down
31
+ drop_table :activities
32
+ end
33
+ end
@@ -0,0 +1,14 @@
1
+ require 'rails/generators/named_base'
2
+
3
+ module LiveActivity
4
+ # A generator module with Activity table schema.
5
+ module Generators
6
+ # A base module
7
+ module Base
8
+ # Get path for migration template
9
+ def source_root
10
+ @_live_activity_source_root ||= File.expand_path(File.join('../live_activity', generator_name, 'templates'), __FILE__)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,183 @@
1
+ module LiveActivity
2
+ module Activity
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+ store :options
8
+
9
+ belongs_to :actor, :polymorphic => true
10
+ belongs_to :act_object, :polymorphic => true
11
+ belongs_to :act_target, :polymorphic => true
12
+
13
+ validates_presence_of :actor_id, :actor_type, :verb
14
+ end
15
+
16
+ module ClassMethods
17
+
18
+ # Defines a new Activity2 type and registers a definition
19
+ #
20
+ # @param [ String ] name The name of the activity
21
+ #
22
+ # @example Define a new activity
23
+ # activity(:enquiry) do
24
+ # actor :user, :cache => [:full_name]
25
+ # act_object :enquiry, :cache => [:subject]
26
+ # act_target :listing, :cache => [:title]
27
+ # end
28
+ #
29
+ # @return [Definition] Returns the registered definition
30
+ def activity(name, &block)
31
+ definition = LiveActivity::DefinitionDSL.new(name)
32
+ definition.instance_eval(&block)
33
+ LiveActivity::Definition.register(definition)
34
+ end
35
+
36
+ # Publishes an activity using an activity name and data
37
+ #
38
+ # @param [ String ] verb The verb of the activity
39
+ # @param [ Hash ] data The data to initialize the activity with.
40
+ #
41
+ # @return [LiveActivity::Activity2] An Activity instance with data
42
+ def publish(verb, data)
43
+ new.publish({:verb => verb}.merge(data))
44
+ end
45
+
46
+ end
47
+
48
+
49
+
50
+ # Publishes the activity to the receivers
51
+ #
52
+ # @param [ Hash ] options The options to publish with.
53
+ #
54
+ def publish(data = {})
55
+ assign_properties(data)
56
+
57
+ self
58
+ end
59
+
60
+
61
+ def refresh_data
62
+ save(:validate => false)
63
+ end
64
+
65
+ protected
66
+
67
+ def assign_properties(data = {})
68
+
69
+ self.verb = data.delete(:verb)
70
+
71
+ cur_receivers = data.delete(:receivers)
72
+
73
+
74
+
75
+ [:actor, :act_object, :act_target].each do |type|
76
+
77
+ cur_object = data[type]
78
+
79
+ unless cur_object
80
+ if definition.send(type.to_sym)
81
+ raise verb.to_json
82
+ #raise LiveActivity::InvalidData.new(type)
83
+ else
84
+ next
85
+
86
+ end
87
+ end
88
+
89
+ class_sym = cur_object.class.name.to_sym
90
+
91
+ raise LiveActivity::InvalidData.new(class_sym) unless definition.send(type) == class_sym
92
+
93
+ case type
94
+ when :actor
95
+ self.actor = cur_object
96
+ when :act_object
97
+ self.act_object = cur_object
98
+ when :act_target
99
+ self.act_target = cur_object
100
+ else
101
+ raise "unknown type"
102
+ end
103
+
104
+ data.delete(type)
105
+
106
+ end
107
+
108
+ [:grouped_actor].each do |group|
109
+
110
+
111
+ grp_object = data[group]
112
+
113
+ if grp_object == nil
114
+ if definition.send(group.to_sym)
115
+ raise verb.to_json
116
+ #raise LiveActivity::InvalidData.new(group)
117
+ else
118
+ next
119
+
120
+ end
121
+ end
122
+
123
+ grp_object.each do |cur_obj|
124
+ raise LiveActivity::InvalidData.new(class_sym) unless definition.send(group) == cur_obj.class.name.to_sym
125
+
126
+ self.grouped_actors << cur_obj
127
+
128
+ end
129
+
130
+ data.delete(group)
131
+
132
+ end
133
+
134
+ cur_bond_type = definition.send(:bond_type)
135
+
136
+ if cur_bond_type
137
+ write_attribute( :bond_type, cur_bond_type.to_s )
138
+ end
139
+
140
+ def_options = definition.send(:options)
141
+ def_options.each do |cur_option|
142
+ cur_object = data[cur_option]
143
+
144
+ if cur_object
145
+
146
+ if cur_option == :description
147
+ self.description = cur_object
148
+ else
149
+ options[cur_option] = cur_object
150
+ end
151
+ data.delete(cur_option)
152
+
153
+ else
154
+ #all options defined must be used
155
+ raise Streama::InvalidData.new(cur_object[0])
156
+ end
157
+ end
158
+
159
+ if data.size > 0
160
+ raise "unexpected arguments: " + data.to_json
161
+ end
162
+
163
+
164
+
165
+ self.save
166
+
167
+
168
+ if cur_receivers
169
+ cur_receivers.each do |sp|
170
+ send(sp.class.to_s.tableize) << sp
171
+ end
172
+ end
173
+
174
+
175
+ end
176
+
177
+ def definition
178
+ @definition ||= LiveActivity::Definition.find(verb)
179
+ end
180
+
181
+
182
+ end
183
+ end
@@ -0,0 +1,53 @@
1
+ module LiveActivity
2
+
3
+ module Actor
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ cattr_accessor :activity_klass
8
+
9
+ has_many :created_activities, :class_name => "Activity", :as => :actor
10
+ has_many :act_object_activities, :class_name => "Activity", :as => :act_object
11
+ has_many :act_target_activities, :class_name => "Activity", :as => :act_target
12
+
13
+
14
+ end
15
+
16
+ module ClassMethods
17
+
18
+ def activity_class(klass)
19
+ self.activity_klass = klass.to_s
20
+ end
21
+
22
+ end
23
+
24
+
25
+ # Publishes the activity to the receivers
26
+ #
27
+ # @param [ Hash ] options The options to publish with.
28
+ #
29
+ # @example publish an activity with a act_object and act_target
30
+ # current_user.publish_activity(:enquiry, :act_object => @enquiry, :act_target => @listing)
31
+ #
32
+ def publish_activity(name, options={})
33
+ options[:receivers] = self.send(options[:receivers]) if options[:receivers].is_a?(Symbol)
34
+ activity = activity_class.publish(name, {:actor => self}.merge(options))
35
+ end
36
+
37
+ def activity_class
38
+ @activity_klass ||= activity_klass ? activity_klass.classify.constantize : ::Activity
39
+ end
40
+
41
+ def activity_stream(options = {})
42
+
43
+ if options.empty?
44
+ activities
45
+ else
46
+ activities.where(options)
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,48 @@
1
+ module LiveActivity
2
+
3
+ class Definition
4
+
5
+ attr_reader :name, :actor, :act_object, :act_target, :grouped_actor, :bond_type, :options, :receivers
6
+
7
+ # @param dsl [LiveActivity::DefinitionDSL] A DSL act_object
8
+ def initialize(definition)
9
+ @name = definition[:name]
10
+ @actor = definition[:actor] || nil
11
+ @act_object = definition[:act_object] || nil
12
+ @act_target = definition[:act_target] || nil
13
+ @grouped_actor = definition[:grouped_actor] || nil
14
+ @bond_type = definition[:bond_type] || nil
15
+ @options = definition[:options] || []
16
+ end
17
+
18
+ #
19
+ # Registers a new definition
20
+ #
21
+ # @param definition [Definition] The definition to register
22
+ # @return [Definition] Returns the registered definition
23
+ def self.register(definition)
24
+ return false unless definition.is_a? DefinitionDSL
25
+ definition = new(definition)
26
+ self.registered << definition
27
+ return definition || false
28
+ end
29
+
30
+ # List of registered definitions
31
+ # @return [Array<LiveActivity::Definition>]
32
+ def self.registered
33
+ @definitions ||= []
34
+ end
35
+
36
+ def self.find(name)
37
+ unless definition = registered.find{|definition| definition.name == name.to_sym}
38
+ raise LiveActivity::InvalidActivity, "Could not find a definition for `#{name}`"
39
+ else
40
+ definition
41
+ end
42
+ end
43
+
44
+
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,48 @@
1
+ require 'active_support'
2
+
3
+ module LiveActivity
4
+
5
+ class DefinitionDSL
6
+
7
+ attr_reader :attributes
8
+
9
+ def initialize(name)
10
+ @attributes = {
11
+ :name => name.to_sym,
12
+ :actor => nil,
13
+ :act_object => nil,
14
+ :act_target => nil,
15
+ :grouped_actor => nil,
16
+ :reverses => nil,
17
+ :bond_type => nil,
18
+ :options => nil
19
+ }
20
+ end
21
+
22
+ def add_option(option)
23
+ @attributes[:options] ||= []
24
+
25
+ @attributes[:options] << option
26
+ end
27
+
28
+ def option(text)
29
+ add_option( text )
30
+ end
31
+
32
+ delegate :[], :to => :@attributes
33
+
34
+ def self.data_methods(*args)
35
+ args.each do |method|
36
+ define_method method do |*args|
37
+
38
+ @attributes[method] = args[0]
39
+
40
+ end
41
+ end
42
+ end
43
+
44
+ data_methods :actor, :act_object, :act_target, :grouped_actor, :bond_type
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,44 @@
1
+ module LiveActivity
2
+
3
+ class LiveActivityError < StandardError
4
+ end
5
+
6
+ class InvalidActivity < LiveActivityError
7
+ end
8
+
9
+ # This error is raised when an act_object isn't defined
10
+ # as an actor, act_object or act_target
11
+ #
12
+ # Example:
13
+ #
14
+ # <tt>InvalidField.new('field_name')</tt>
15
+ class InvalidData < LiveActivityError
16
+ attr_reader :message
17
+
18
+ def initialize message
19
+ @message = "Invalid Data: #{message}"
20
+ end
21
+
22
+ end
23
+
24
+ # This error is raised when trying to store a field that doesn't exist
25
+ #
26
+ # Example:
27
+ #
28
+ # <tt>InvalidField.new('field_name')</tt>
29
+ class InvalidField < LiveActivityError
30
+ attr_reader :message
31
+
32
+ def initialize message
33
+ @message = "Invalid Field: #{message}"
34
+ end
35
+
36
+ end
37
+
38
+ class ActivityNotSaved < LiveActivityError
39
+ end
40
+
41
+ class NoFollowersDefined < LiveActivityError
42
+ end
43
+
44
+ end
@@ -0,0 +1,3 @@
1
+ module LiveActivity
2
+ VERSION = "0.3.2"
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_record'
2
+ require 'active_support'
3
+ require 'active_support/core_ext/module/delegation.rb'
4
+ require "live_activity/version"
5
+ require "live_activity/actor"
6
+ require "live_activity/activity"
7
+ require "live_activity/definition"
8
+ require "live_activity/definition_dsl"
9
+ require "live_activity/errors"
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "live_activity/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "live-activity"
7
+ s.version = LiveActivity::VERSION
8
+ s.authors = ["Andreas Saebjoernsen"]
9
+ s.email = ["andreas.saebjoernsen@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Activity Streams for rails}
12
+ s.description = %q{LiveActivity is a simple activity stream gem for use with the Mongoid ODM framework}
13
+
14
+ s.rubyforge_project = "live-activity"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.required_ruby_version = '>= 1.9.2'
22
+
23
+ s.add_dependency 'activerecord', '>= 3'
24
+ s.add_dependency 'activesupport', '>= 3'
25
+ s.add_dependency 'actionpack', '>= 3'
26
+ end
@@ -0,0 +1,33 @@
1
+ # Migration responsible for creating a table with activities
2
+ class CreateActivities < ActiveRecord::Migration
3
+ # Create table
4
+ def self.up
5
+ create_table :activities do |t|
6
+ t.belongs_to :actor, :polymorphic => true
7
+ t.belongs_to :act_object, :polymorphic => true
8
+ t.belongs_to :act_target, :polymorphic => true
9
+
10
+ t.string :verb
11
+ t.string :description
12
+ t.string :options
13
+ t.string :bond_type
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ create_table :activities_users, :id => false do |t|
19
+ t.references :activity, :user
20
+ end
21
+
22
+ add_index :activities_users, [:activity_id, :user_id ]
23
+
24
+ add_index :activities, [:verb]
25
+ add_index :activities, [:actor_id, :actor_type]
26
+ add_index :activities, [:act_object_id, :act_object_type]
27
+ add_index :activities, [:act_target_id, :act_target_type]
28
+ end
29
+ # Drop table
30
+ def self.down
31
+ drop_table :activities
32
+ end
33
+ 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 AddNonstandardToActivities < ActiveRecord::Migration
2
+ def change
3
+ change_table :activities do |t|
4
+ t.string :nonstandard
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ class CreateVolumes < ActiveRecord::Migration
2
+ def self.up
3
+ puts "creating"
4
+ create_table :volumes do |t|
5
+ t.belongs_to :user
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,77 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup(:default, :test)
4
+
5
+ $:.unshift File.expand_path('../../lib/', __FILE__)
6
+ require 'active_support/testing/setup_and_teardown'
7
+ require 'live_activity'
8
+ require 'minitest/autorun'
9
+
10
+ #LiveStream.config # touch config to load ORM, needed in some separate tests
11
+
12
+ require 'active_record'
13
+ require 'active_record/connection_adapters/sqlite3_adapter'
14
+
15
+
16
+ class ActiveSupport::TestCase
17
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
18
+ #
19
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
20
+ # -- they do not yet inherit this setting
21
+ #fixtures :all
22
+
23
+ # Add more helper methods to be used by all tests here...
24
+ end
25
+
26
+ class Activity < ActiveRecord::Base
27
+ include LiveActivity::Activity
28
+
29
+ has_and_belongs_to_many :users
30
+
31
+ activity :new_enquiry do
32
+ actor :User
33
+ act_object :Article
34
+ act_target :Volume
35
+ #option :description
36
+ end
37
+
38
+ activity :test_description do
39
+ actor :User
40
+ act_object :Article
41
+ act_target :Volume
42
+ option :description
43
+ end
44
+
45
+ activity :test_option do
46
+ actor :User
47
+ act_object :Article
48
+ act_target :Volume
49
+ option :country
50
+ end
51
+
52
+ activity :test_bond_type do
53
+ actor :User
54
+ act_object :Article
55
+ act_target :Volume
56
+ bond_type :global
57
+ end
58
+
59
+ end
60
+
61
+ class User < ActiveRecord::Base
62
+ include LiveActivity::Actor
63
+
64
+ has_and_belongs_to_many :activities
65
+
66
+ end
67
+
68
+ class Article < ActiveRecord::Base
69
+
70
+ end
71
+
72
+ class Volume < ActiveRecord::Base
73
+
74
+ end
75
+
76
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
77
+ ActiveRecord::Migrator.migrate(File.expand_path('../migrations', __FILE__))
@@ -0,0 +1,85 @@
1
+ class ActivityTest < ActiveSupport::TestCase
2
+
3
+ def test_truth
4
+ assert true
5
+ end
6
+
7
+ def test_register_definition
8
+
9
+ @definition = Activity.activity(:test_activity) do
10
+ actor :user, :cache => [:full_name]
11
+ act_object :listing, :cache => [:title, :full_address]
12
+ act_target :listing, :cache => [:title]
13
+ end
14
+
15
+ assert @definition.is_a?(LiveActivity::Definition)
16
+
17
+ end
18
+
19
+ def test_push_activity_to_receivers
20
+ _user = User.create()
21
+ _user_2 = User.create()
22
+ _article = Article.create()
23
+ _volume = Volume.create()
24
+
25
+ _activity = Activity.publish(:new_enquiry, :actor => _user, :act_object => _article, :act_target => _volume,
26
+ :receivers => [_user_2])
27
+ assert _activity.users.size == 1
28
+
29
+ end
30
+
31
+ def test_publish_new_activity
32
+ _user = User.create()
33
+ _article = Article.create()
34
+ _volume = Volume.create()
35
+
36
+ _activity = Activity.publish(:new_enquiry, :actor => _user, :act_object => _article, :act_target => _volume)
37
+
38
+ assert _activity.persisted?
39
+ #_activity.should be_an_instance_of Activity
40
+
41
+ end
42
+
43
+ def test_description
44
+ _user = User.create()
45
+ _article = Article.create()
46
+ _volume = Volume.create()
47
+
48
+ _description = "this is a test"
49
+ _activity = Activity.publish(:test_description, :actor => _user, :act_object => _article, :act_target => _volume,
50
+ :description => _description )
51
+
52
+ assert _activity.description == _description
53
+
54
+ end
55
+
56
+ def test_options
57
+ _user = User.create()
58
+ _article = Article.create()
59
+ _volume = Volume.create()
60
+
61
+ _country = "denmark"
62
+ _activity = Activity.publish(:test_option, :actor => _user, :act_object => _article, :act_target => _volume,
63
+ :country => _country )
64
+
65
+ assert _activity.options[:country] == _country
66
+
67
+ end
68
+
69
+ def test_bond_type
70
+ _user = User.create()
71
+ _article = Article.create()
72
+ _volume = Volume.create()
73
+
74
+ _activity = Activity.publish(:test_bond_type, :actor => _user, :act_object => _article, :act_target => _volume)
75
+
76
+ assert _activity.bond_type == 'global'
77
+
78
+ end
79
+
80
+
81
+
82
+
83
+
84
+
85
+ end
@@ -0,0 +1,58 @@
1
+ class ActorTest < ActiveSupport::TestCase
2
+
3
+
4
+ def test_publish_activity
5
+
6
+ _user = User.create()
7
+ _article = Article.create()
8
+ _volume = Volume.create()
9
+
10
+ activity = _user.publish_activity(:new_enquiry, :act_object => _article, :act_target => _volume)
11
+
12
+ assert activity.persisted?
13
+
14
+ end
15
+
16
+ def test_pushes_to_a_defined_stream
17
+ _user = User.create()
18
+ _user_2 = User.create()
19
+ _article = Article.create()
20
+ _volume = Volume.create()
21
+
22
+ _activity = _user.publish_activity(:new_enquiry, :act_object => _article, :act_target => _volume,
23
+ :receivers => [_user_2])
24
+ assert _activity.users.size == 1
25
+
26
+ end
27
+
28
+ def test_retrieves_the_stream_for_an_actor
29
+ _user = User.create()
30
+ _article = Article.create()
31
+ _volume = Volume.create()
32
+
33
+ _user.publish_activity(:new_enquiry, :act_object => _article, :act_target => _volume, :receivers => [_user])
34
+ _user.publish_activity(:new_enquiry, :act_object => _article, :act_target => _volume, :receivers => [_user])
35
+
36
+ assert _user.activity_stream.size == 2
37
+
38
+ end
39
+
40
+
41
+ def test_retrieves_the_stream_for_a_particular_activity_type
42
+ _user = User.create()
43
+ _article = Article.create()
44
+ _volume = Volume.create()
45
+
46
+ _user.publish_activity(:new_enquiry, :act_object => _article, :act_target => _volume, :receivers => [_user])
47
+ _user.publish_activity(:new_enquiry, :act_object => _article, :act_target => _volume, :receivers => [_user])
48
+ _user.publish_activity(:test_bond_type, :act_object => _article, :act_target => _volume, :receivers => [_user])
49
+
50
+ assert _user.activity_stream(:verb => 'new_enquiry').size == 2
51
+ assert _user.activity_stream(:bond_type => 'global').size == 1
52
+
53
+ end
54
+
55
+
56
+
57
+
58
+ end
@@ -0,0 +1,29 @@
1
+ class DefinitionDslTest < ActiveSupport::TestCase
2
+
3
+ def definition_dsl
4
+ LiveActivity::DefinitionDSL.new(:new_enquiry)
5
+ end
6
+
7
+ def test_initializes_with_name
8
+ assert definition_dsl.attributes[:name] == :new_enquiry
9
+ end
10
+
11
+ def test_adds_an_actor_to_the_definition
12
+ dsl = definition_dsl
13
+ dsl.actor(:User)
14
+ assert dsl.attributes[:actor] == :User
15
+ end
16
+
17
+ def test_adds_an_act_object_to_the_definition
18
+ dsl = definition_dsl
19
+ dsl.act_object(:Article)
20
+ assert dsl.attributes[:act_object] == :Article
21
+ end
22
+
23
+ def test_adds_a_act_target_to_the_definition
24
+ dsl = definition_dsl
25
+ dsl.act_target(:Volume)
26
+ assert dsl.attributes[:act_target] == :Volume
27
+ end
28
+
29
+ end
@@ -0,0 +1,51 @@
1
+ class DefinitionTest < ActiveSupport::TestCase
2
+
3
+ def definition_dsl
4
+ dsl = LiveActivity::DefinitionDSL.new(:new_enquiry)
5
+ dsl.actor(:User)
6
+ dsl.act_object(:Article)
7
+ dsl.act_target(:Volume)
8
+ dsl
9
+ end
10
+
11
+ def test_initialization
12
+ _definition_dsl = definition_dsl
13
+ _definition = LiveActivity::Definition.new(_definition_dsl)
14
+
15
+ assert _definition.actor == :User
16
+ assert _definition.act_object == :Article
17
+ assert _definition.act_target == :Volume
18
+
19
+ end
20
+
21
+ def test_register_definition_and_return_new_definition
22
+
23
+ assert LiveActivity::Definition.register(definition_dsl).is_a?(LiveActivity::Definition)
24
+
25
+ end
26
+
27
+ def test_register_invalid_definition
28
+
29
+ assert LiveActivity::Definition.register(false) == false
30
+
31
+ end
32
+
33
+ def test_return_registered_definitions
34
+
35
+ LiveActivity::Definition.register(definition_dsl)
36
+ assert LiveActivity::Definition.registered.size > 0
37
+
38
+ end
39
+
40
+ def test_return_definition_by_name
41
+ assert LiveActivity::Definition.find(:new_enquiry).name == :new_enquiry
42
+
43
+ end
44
+
45
+ def test_raise_exception_if_invalid_activity
46
+
47
+ assert_raises(LiveActivity::InvalidActivity){ LiveActivity::Definition.find(:unknown_activity) }
48
+
49
+ end
50
+
51
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: live-activity
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.2
5
+ platform: ruby
6
+ authors:
7
+ - Andreas Saebjoernsen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: actionpack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '3'
55
+ description: LiveActivity is a simple activity stream gem for use with the Mongoid
56
+ ODM framework
57
+ email:
58
+ - andreas.saebjoernsen@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .document
64
+ - .gitignore
65
+ - .rspec
66
+ - .travis.yml
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - lib/generators/live_stream.rb
72
+ - lib/generators/live_stream/activity/activity_generator.rb
73
+ - lib/generators/live_stream/activity/templates/activity.rb
74
+ - lib/generators/live_stream/migration/migration_generator.rb
75
+ - lib/generators/live_stream/migration/templates/migration.rb
76
+ - lib/live_activity.rb
77
+ - lib/live_activity/activity.rb
78
+ - lib/live_activity/actor.rb
79
+ - lib/live_activity/definition.rb
80
+ - lib/live_activity/definition_dsl.rb
81
+ - lib/live_activity/errors.rb
82
+ - lib/live_activity/version.rb
83
+ - live-activity.gemspec
84
+ - test/migrations/001_create_activities.rb
85
+ - test/migrations/002_create_articles.rb
86
+ - test/migrations/003_create_users.rb
87
+ - test/migrations/004_add_nonstandard_to_activities.rb
88
+ - test/migrations/005_create_volumes.rb
89
+ - test/test_helper.rb
90
+ - test/unit/activity_test.rb
91
+ - test/unit/actor_test.rb
92
+ - test/unit/definition_dsl_test.rb
93
+ - test/unit/definition_test.rb
94
+ homepage: ''
95
+ licenses: []
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: 1.9.2
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project: live-activity
113
+ rubygems_version: 2.0.4
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Activity Streams for rails
117
+ test_files:
118
+ - test/migrations/001_create_activities.rb
119
+ - test/migrations/002_create_articles.rb
120
+ - test/migrations/003_create_users.rb
121
+ - test/migrations/004_add_nonstandard_to_activities.rb
122
+ - test/migrations/005_create_volumes.rb
123
+ - test/test_helper.rb
124
+ - test/unit/activity_test.rb
125
+ - test/unit/actor_test.rb
126
+ - test/unit/definition_dsl_test.rb
127
+ - test/unit/definition_test.rb
128
+ has_rdoc: