facteur 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ spec/db/.*
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Rawane ZOSSOU
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.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = facteur
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Rawane ZOSSOU. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "facteur"
8
+ gem.summary = "Messages managment system for Rails 3"
9
+ gem.description = "Facteur allows you add a messages management system in your Rails 3. You can create many mailboxes for your users. They will be able to send and receive messages."
10
+ gem.email = "dev@raw1z.fr"
11
+ gem.homepage = "http://github.com/raw1z/facteur"
12
+ gem.authors = ["Rawane ZOSSOU"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rspec/core'
22
+ require 'rspec/core/rake_task'
23
+ Rspec::Core::RakeTask.new(:spec) do |spec|
24
+ end
25
+
26
+ Rspec::Core::RakeTask.new(:rcov) do |spec|
27
+ end
28
+
29
+ task :spec => :check_dependencies
30
+
31
+ task :default => :spec
32
+
33
+ require 'rake/rdoctask'
34
+ Rake::RDocTask.new do |rdoc|
35
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
36
+
37
+ rdoc.rdoc_dir = 'rdoc'
38
+ rdoc.title = "facteur #{version}"
39
+ rdoc.rdoc_files.include('README*')
40
+ rdoc.rdoc_files.include('lib/**/*.rb')
41
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,122 @@
1
+ module Facteur
2
+ module AddresseeModel
3
+ def self.included(receiver)
4
+ receiver.class_exec do
5
+ include InstanceMethods
6
+
7
+ has_many :mailboxes, :as => :addressee
8
+ has_many :messages_sent, :class_name => "Message", :foreign_key => "author_id"
9
+
10
+ # the addressee's mailboxes are created after its creation
11
+ after_create :create_mailboxes
12
+ end
13
+
14
+ receiver.extend ClassMethods
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ # Define a mailbox. The following options are available:
20
+ # <tt>:default</tt>:: defines the default mailbox. You must choose one default mailbox
21
+ def mailbox(name, options={})
22
+ mailbox = {:name => name}
23
+ mailbox.merge! options
24
+ mailboxes << mailbox
25
+ end
26
+
27
+ # Returns the mailboxes defined for the class
28
+ def mailboxes
29
+ @mailboxes ||= []
30
+ end
31
+ end
32
+
33
+ module InstanceMethods
34
+
35
+ # Sends a message to one or many addressees. The following options are available:
36
+ #
37
+ # <tt>:to</tt>:: the addressee or the list of addressees (mandatory)
38
+ # <tt>:in</tt>:: the name of the mailbox in which the message is posted (mandatory)
39
+ # <tt>:body</tt>:: the message's body (mandatory)
40
+ #
41
+ # Usage :
42
+ #
43
+ # # send a message to one addressee
44
+ # @john.send_message('message contents', :to => @peter, :in => :private_mailbox)
45
+ #
46
+ # # send a message to many addressees
47
+ # @john.send_message('message contents', :to => [@peter, @james], :in => :private_mailbox)
48
+ def send_message(message, options)
49
+ options[:body] = message
50
+ if options[:to].is_a? Array
51
+ options[:to].each do |addressee|
52
+ send_message_to(addressee, options[:in], options[:body])
53
+ end
54
+ else
55
+ send_message_to(options[:to], options[:in], options[:body])
56
+ end
57
+ end
58
+
59
+ # Creates a new mailbox. if a mailbox with the same name already exists, it fails and returns false. If succeeded, it creates an accessor for the new mail box and returns true.
60
+ # Example :
61
+ #
62
+ # class User < ActiveRecord::base
63
+ # include Facteur::AddresseeModel
64
+ #
65
+ # mailbox :private_mailbox
66
+ # end
67
+ #
68
+ # The previous declaration will add : User#private_mailbox
69
+ #
70
+ # # supposing that a name field exists
71
+ # user = User.new(:name => 'John')
72
+ # user.create_mailbox :public_mailbox #=> return true
73
+ # user.create_mailbox :private_mailbox #=> return false
74
+ def create_mailbox(name, options={})
75
+ mailbox = Mailbox.new(:name => name.to_s)
76
+ mailbox.addressee = self
77
+ return false if mailbox.save == false
78
+
79
+ @default_mailbox = name if options[:default]
80
+ self.class.class_eval do
81
+ define_method(name) do
82
+ self.mailboxes.where(:name => name.to_s).first
83
+ end
84
+ end
85
+ true
86
+ end
87
+
88
+ # Creates a new mailbox. if a mailbox with the same name already exists, it raises an exception. If succeeded, it creates an accessor for the new mail box and returns the created mailbox.
89
+ def create_mailbox!(name, options={})
90
+ if create_mailbox(name, options) == false
91
+ raise "Mailboxes names must be unique. Can't create '#{name}'"
92
+ end
93
+ self.send "#{name}"
94
+ end
95
+
96
+ private
97
+
98
+ # creates the mailboxes defined in the configuration
99
+ def create_mailboxes
100
+ self.class.mailboxes.each do |mailbox|
101
+ options = {}.merge(mailbox)
102
+ name = options.delete(:name)
103
+ create_mailbox!(name, options)
104
+ end
105
+ end
106
+
107
+ # send a message to an addressee
108
+ def send_message_to(addressee, mailbox_name, contents)
109
+ return false if addressee.nil? or contents.nil?
110
+
111
+ mailbox_name = @default_mailbox if mailbox_name.nil?
112
+ return false if mailbox_name.nil?
113
+
114
+ message = Message.new
115
+ message.author = self
116
+ message.mailbox = addressee.send(mailbox_name)
117
+ message.body = contents
118
+ message.save
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,12 @@
1
+ module Facteur
2
+ module MailboxModel
3
+ def self.included(receiver)
4
+ receiver.class_exec do
5
+ belongs_to :addressee, :polymorphic => true
6
+ has_many :messages
7
+ validates_presence_of :name
8
+ validates_uniqueness_of :name, :scope => [:addressee_id, :addressee_type]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Facteur
2
+ module MessageModel
3
+ def self.included(receiver)
4
+ receiver.class_exec do
5
+ validates_presence_of :author_id, :mailbox_id, :body
6
+
7
+ belongs_to :mailbox
8
+ belongs_to :author, :class_name => "User", :foreign_key => "author_id"
9
+
10
+ delegate :addressee, :to => :mailbox
11
+ delegate :addressee_type, :to => :mailbox
12
+ end
13
+ end
14
+ end
15
+ end
16
+
data/lib/facteur.rb ADDED
@@ -0,0 +1,3 @@
1
+ require File.join(File.dirname(__FILE__), 'facteur/message_model')
2
+ require File.join(File.dirname(__FILE__), 'facteur/mailbox_model')
3
+ require File.join(File.dirname(__FILE__), 'facteur/addressee_model')
File without changes
Binary file
@@ -0,0 +1,89 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Facteur::AddresseeModel do
4
+ context "when creating mailboxes" do
5
+ before(:each) do
6
+ create_users
7
+ Message.delete_all
8
+ end
9
+
10
+ it "creates a new mailbox" do
11
+ @john.create_mailbox(:news_mailbox).should == true
12
+
13
+ lambda { @peter.create_mailbox! :news_mailbox }.should_not raise_error
14
+
15
+ mailbox = @victoria.create_mailbox! :news_mailbox
16
+ mailbox.addressee.should == @victoria
17
+ end
18
+
19
+ it "could not create a mailbox with the name of an existing mailbox" do
20
+ @john.create_mailbox(:private_mailbox).should == false
21
+ lambda { mailbox = @peter.create_mailbox! :private_mailbox }.should raise_error
22
+ end
23
+ end
24
+
25
+ context "when initialized" do
26
+ before(:each) do
27
+ create_users
28
+ Message.delete_all
29
+ end
30
+
31
+ it "creates the addressee's mailboxes" do
32
+ @john.mailboxes.where(:name => 'private_mailbox').first.should_not be_nil
33
+ @john.mailboxes.where(:name => 'public_mailbox').first.should_not be_nil
34
+ end
35
+
36
+ it "defines the mailboxes accessors" do
37
+ @john.should respond_to :private_mailbox
38
+ @john.should respond_to :public_mailbox
39
+ @john.private_mailbox.should_not be_nil
40
+ @john.public_mailbox.should_not be_nil
41
+ end
42
+ end
43
+
44
+ context "when sending message" do
45
+ before(:each) do
46
+ create_users
47
+ Message.delete_all
48
+ end
49
+
50
+ it "sends a message to another addressee" do
51
+ @john.send_message('message contents', :to => @peter, :in => :private_mailbox).should == true
52
+ message = @peter.private_mailbox.messages.last
53
+ message.author.should == @john
54
+ message.body.should == 'message contents'
55
+ end
56
+
57
+ it "sends the messages in the default mailbox" do
58
+ @john.send_message('message contents', :to => @peter).should == true
59
+ message = @peter.private_mailbox.messages.last
60
+ message.author.should == @john
61
+ message.body.should == 'message contents'
62
+ end
63
+
64
+ it "could not send a message if the addressee is not given" do
65
+ @john.send_message('message contents', :in => :private_mailbox).should == false
66
+ end
67
+
68
+ it "raises an error if the mailbox name given is unknown" do
69
+ lambda{ @john.send_message('message contents', :to => @peter, :in => :unknown_mailbox) }.should raise_error
70
+ end
71
+
72
+ it "sends a message to many addressees" do
73
+ @john.send_message('message contents', :to => [@peter, @james, @jane], :in => :private_mailbox)
74
+
75
+ message = @peter.private_mailbox.messages.last
76
+ message.author.should == @john
77
+ message.body.should == 'message contents'
78
+
79
+ message = @james.private_mailbox.messages.last
80
+ message.author.should == @john
81
+ message.body.should == 'message contents'
82
+
83
+ message = @jane.private_mailbox.messages.last
84
+ message.author.should == @john
85
+ message.body.should == 'message contents'
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,67 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'parchemin'
4
+ require 'rspec/core'
5
+ require 'rspec/autorun'
6
+ require 'active_record'
7
+ require 'logger'
8
+ require 'facteur'
9
+
10
+ SPEC_ROOT = File.dirname(__FILE__)
11
+
12
+ ActiveRecord::Base.establish_connection(
13
+ :adapter => "sqlite3",
14
+ :database => "#{SPEC_ROOT}/db/facteur.sqlite3.db"
15
+ )
16
+
17
+ ActiveRecord::Migration.verbose = false
18
+
19
+ ActiveRecord::Schema.define do
20
+ create_table :users, :force => true do |t|
21
+ t.string :name, :null => false
22
+ end
23
+
24
+ create_table :mailboxes, :force => true do |t|
25
+ t.string :name
26
+ t.text :contents
27
+ t.integer :addressee_id
28
+ t.string :addressee_type
29
+ t.boolean :default
30
+ end
31
+
32
+ create_table :messages, :force => true do |t|
33
+ t.string :subject
34
+ t.text :body
35
+ t.integer :mailbox_id
36
+ t.integer :author_id
37
+ t.boolean :deleted_by_author, :default => false
38
+ t.datetime :deleted_by_author_at
39
+ t.boolean :deleted_by_addressee, :default => false
40
+ t.datetime :deleted_by_addressee_at
41
+ t.boolean :read, :default => false
42
+ end
43
+ end
44
+
45
+ ActiveRecord::Base.logger = Logger.new(File.open("#{SPEC_ROOT}/db/database.log", 'a'))
46
+
47
+ class User < ActiveRecord::Base
48
+ include Facteur::AddresseeModel
49
+
50
+ mailbox :private_mailbox, :default => true
51
+ mailbox :public_mailbox
52
+ end
53
+
54
+ class Mailbox < ActiveRecord::Base
55
+ include Facteur::MailboxModel
56
+ end
57
+
58
+ class Message < ActiveRecord::Base
59
+ include Facteur::MessageModel
60
+ end
61
+
62
+ def create_users
63
+ %w(John Peter James Mary Jane Victoria).each do |name|
64
+ eval "@#{name.downcase} = User.create(:name => '#{name}')"
65
+ end
66
+ end
67
+
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: facteur
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Rawane ZOSSOU
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-06-10 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
34
+ version: 1.2.9
35
+ type: :development
36
+ version_requirements: *id001
37
+ description: Facteur allows you add a messages management system in your Rails 3. You can create many mailboxes for your users. They will be able to send and receive messages.
38
+ email: dev@raw1z.fr
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - LICENSE
45
+ - README.rdoc
46
+ files:
47
+ - .document
48
+ - .gitignore
49
+ - LICENSE
50
+ - README.rdoc
51
+ - Rakefile
52
+ - VERSION
53
+ - lib/facteur.rb
54
+ - lib/facteur/addressee_model.rb
55
+ - lib/facteur/mailbox_model.rb
56
+ - lib/facteur/message_model.rb
57
+ - spec/db/database.log
58
+ - spec/db/facteur.sqlite3.db
59
+ - spec/facteur_spec.rb
60
+ - spec/spec_helper.rb
61
+ has_rdoc: true
62
+ homepage: http://github.com/raw1z/facteur
63
+ licenses: []
64
+
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --charset=UTF-8
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ requirements: []
89
+
90
+ rubyforge_project:
91
+ rubygems_version: 1.3.7
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: Messages managment system for Rails 3
95
+ test_files:
96
+ - spec/facteur_spec.rb
97
+ - spec/spec_helper.rb