Permalink
Browse files

actor can specify the class_name

  • Loading branch information...
1 parent fded79a commit e7777db847bbd64edbfbb73e22dbb2e115ab9a27 @niedhui niedhui committed Nov 2, 2012
@@ -1,9 +1,9 @@
module Streama
module Activity
extend ActiveSupport::Concern
-
+
included do
-
+
include Mongoid::Document
include Mongoid::Timestamps
@@ -21,9 +21,9 @@ module Activity
validates_presence_of :actor, :verb
before_save :assign_data
-
+
end
-
+
module ClassMethods
# Defines a new activity type and registers a definition
@@ -54,7 +54,7 @@ def publish(verb, data)
receivers = data.delete(:receivers)
new({:verb => verb}.merge(data)).publish(:receivers => receivers)
end
-
+
def stream_for(actor, options={})
query = {:receivers => {'$elemMatch' => {:id => actor.id, :type => actor.class.to_s}}}
query.merge!({:verb.in => [*options[:type]]}) if options[:type]
@@ -66,21 +66,21 @@ def stream_of(actor, options={})
query.merge!({:verb.in => [*options[:type]]}) if options[:type]
self.where(query).without(:receivers).desc(:created_at)
end
-
+
end
-
+
# Publishes the activity to the receivers
#
# @param [ Hash ] options The options to publish with.
#
def publish(options = {})
- actor = load_instance(:actor)
+ actor = load_instance(:actor)
self.receivers = (options[:receivers] || actor.followers).map { |r| { :id => r.id, :type => r.class.to_s } }
self.save
self
end
-
+
# Returns an instance of an actor, object or target
#
# @param [ Symbol ] type The data type (actor, object, target) to return an instance for.
@@ -89,38 +89,38 @@ def publish(options = {})
def load_instance(type)
(data = self.read_attribute(type)).is_a?(Hash) ? data['type'].to_s.camelcase.constantize.find(data['id']) : data
end
-
+
def refresh_data
assign_data
save(:validates_presence_of => false)
end
-
+
protected
-
+
def assign_data
-
+
[:actor, :object, :target_object].each do |type|
next unless object = load_instance(type)
class_sym = object.class.name.underscore.to_sym
raise Errors::InvalidData.new(class_sym) unless definition.send(type).has_key?(class_sym)
-
+
hash = {'id' => object.id, 'type' => object.class.name}
-
+
if fields = definition.send(type)[class_sym].try(:[],:cache)
fields.each do |field|
raise Errors::InvalidField.new(field) unless object.respond_to?(field)
hash[field.to_s] = object.send(field)
end
end
- write_attribute(type, hash)
+ write_attribute(type, hash)
end
end
-
+
def definition
@definition ||= Streama::Definition.find(verb)
end
-
+
end
end
@@ -1,29 +1,34 @@
module Streama
-
+
class DefinitionDSL
-
+
attr_reader :attributes
-
+
def initialize(name)
@attributes = {
:name => name.to_sym,
- :actor => {},
- :object => {},
+ :actor => {},
+ :object => {},
:target_object => {}
}
end
-
+
delegate :[], :to => :@attributes
-
+
def self.data_methods(*args)
args.each do |method|
define_method method do |*args|
- @attributes[method].store(args[0].is_a?(Symbol) ? args[0] : args[0].class.to_sym, args[1])
+ class_sym = if class_name = args[1].try(:delete,:class_name)
+ class_name.underscore.to_sym
+ else
+ args[0].is_a?(Symbol) ? args[0] : args[0].class.to_sym
+ end
+ @attributes[method].store(class_sym, args[1])
end
end
end
data_methods :actor, :object, :target_object
end
-
-end
+
+end
@@ -1,26 +1,32 @@
class Activity
include Streama::Activity
-
+
activity :new_photo do
actor :user, :cache => [:full_name]
object :photo, :cache => [:file]
target_object :album, :cache => [:title]
end
-
+
activity :new_photo_without_cache do
actor :user
object :photo
target_object :album
end
-
+
activity :new_comment do
actor :user, :cache => [:full_name]
object :photo
end
-
+
activity :new_tag do
actor :user, :cache => [:full_name]
object :photo
end
-
-end
+
+ activity :new_mars_photo do
+ actor :user, :cache => [:full_name], :class_name => 'Mars::User'
+ object :photo
+ target_object :album, :cache => [:title]
+ end
+
+end
@@ -0,0 +1,15 @@
+# encoding: utf-8
+module Mars
+ class User
+ include Mongoid::Document
+ include Streama::Actor
+
+ field :full_name
+
+ def followers
+ self.class.all
+ end
+
+ end
+
+end
@@ -5,6 +5,7 @@
let(:photo) { Photo.create(:file => "image.jpg") }
let(:album) { Album.create(:title => "A test album") }
let(:user) { User.create(:full_name => "Christos") }
+ let(:mars_user) { Mars::User.create(:full_name => "Mars User") }
describe ".activity" do
it "registers and return a valid definition" do
@@ -13,102 +14,108 @@
object :photo, :cache => [:file]
target_object :album, :cache => [:title]
end
-
+
@definition.is_a?(Streama::Definition).should be true
end
-
+
end
-
+
describe "#publish" do
before :each do
@send_to = []
2.times { |n| @send_to << User.create(:full_name => "Custom Receiver #{n}") }
5.times { |n| User.create(:full_name => "Receiver #{n}") }
end
-
+
it "pushes activity to receivers" do
@activity = Activity.publish(:new_photo, {:actor => user, :object => photo, :target_object => album, :receivers => @send_to})
@activity.receivers.size.should == 2
end
context "when activity not cached" do
-
+
it "pushes activity to receivers" do
@activity = Activity.publish(:new_photo_without_cache, {:actor => user, :object => photo, :target_object => album, :receivers => @send_to})
@activity.receivers.size.should == 2
end
-
+
end
-
+
it "overrides the recievers if option passed" do
@activity = Activity.publish(:new_photo, {:actor => user, :object => photo, :target_object => album, :receivers => @send_to})
@activity.receivers.size.should == 2
end
-
-
+
+
context "when republishing"
before :each do
@actor = user
@activity = Activity.publish(:new_photo, {:actor => @actor, :object => photo, :target_object => album})
@activity.publish
end
-
+
it "updates metadata" do
@actor.full_name = "testing"
@actor.save
@activity.publish
@activity.actor['full_name'].should eq "testing"
end
end
-
+
describe ".publish" do
it "creates a new activity" do
activity = Activity.publish(:new_photo, {:actor => user, :object => photo, :target_object => album})
activity.should be_an_instance_of Activity
end
+
+ it " creates a new activity when actor has namespace" do
+ activity = Activity.publish(:new_mars_photo, {:actor => mars_user, :object => photo, :target_object => album})
+ activity.should be_an_instance_of Activity
+ end
+
end
describe "#refresh" do
-
+
before :each do
@user = user
@activity = Activity.publish(:new_photo, {:actor => @user, :object => photo, :target_object => album})
end
-
+
it "reloads instances and updates activities stored data" do
@activity.save
- @activity = Activity.last
-
+ @activity = Activity.last
+
expect do
@user.update_attribute(:full_name, "Test")
@activity.refresh_data
end.to change{ @activity.load_instance(:actor).full_name}.from("Christos").to("Test")
end
-
+
end
describe "#load_instance" do
-
+
before :each do
@activity = Activity.publish(:new_photo, {:actor => user, :object => photo, :target_object => album})
@activity = Activity.last
end
-
+
it "loads an actor instance" do
@activity.load_instance(:actor).should be_instance_of User
end
-
+
it "loads an object instance" do
@activity.load_instance(:object).should be_instance_of Photo
end
-
+
it "loads a target instance" do
@activity.load_instance(:target_object).should be_instance_of Album
end
-
+
end
-
+
end
Oops, something went wrong.

0 comments on commit e7777db

Please sign in to comment.