facteur 0.1.0

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.
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