publishing_logic 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ pkg
20
20
 
21
21
  ## PROJECT::SPECIFIC
22
22
  publishing_logic.gemspec
23
+ .specification
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: publishing_logic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Unboxed Consulting
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-09 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: cucumber
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: Publishing logic for ActiveRecord models
36
+ email: enquiries@unboxedconsulting.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - .document
46
+ - .gitignore
47
+ - LICENSE
48
+ - README.rdoc
49
+ - Rakefile
50
+ - VERSION
51
+ - features/publishing_logic.feature
52
+ - features/step_definitions/publishing_logic_steps.rb
53
+ - features/support/env.rb
54
+ - lib/model_logic.rb
55
+ - lib/publishing_logic.rb
56
+ - rails_generators/publishing_logic_fields/publishing_logic_fields_generator.rb
57
+ - spec/lib/model_logic_spec.rb
58
+ - spec/publishing_logic_spec.rb
59
+ - spec/spec.opts
60
+ - spec/spec_helper.rb
61
+ has_rdoc: true
62
+ homepage: http://github.com/tomtt/publishing_logic
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
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.3.5
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Publishing logic for ActiveRecord models
89
+ test_files:
90
+ - spec/lib/model_logic_spec.rb
91
+ - spec/publishing_logic_spec.rb
92
+ - spec/spec_helper.rb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.1.0
data/lib/model_logic.rb CHANGED
@@ -1,7 +1,41 @@
1
1
  module PublishingLogic
2
2
  module ModelLogic
3
+ PUBLISHED_CONDITIONS = <<EOT
4
+ publishing_enabled = true AND
5
+ (published_until is null or published_until > ?) AND
6
+ (published_at is null or published_at < ?)
7
+ EOT
8
+
3
9
  def published?
4
- true
10
+ return false if published_at && Time.now < published_at
11
+ return false if published_until && Time.now > published_until
12
+ publishing_enabled?
5
13
  end
14
+
15
+ def self.included(base)
16
+ base.extend(ClassMethods)
17
+ base.instance_eval do
18
+ named_scope :published, lambda {{ :conditions => [PUBLISHED_CONDITIONS, Time.now.utc, Time.now.utc] }} do
19
+ def newest
20
+ find(:first, :order => "published_at DESC")
21
+ end
22
+
23
+ def oldest
24
+ find(:last, :order => "published_at DESC")
25
+ end
26
+ end
27
+
28
+ # If objects have identical published_at values, order by created_at. If these are
29
+ # identical as well, then order by id. This is done to ensure there is a unique
30
+ # ordering of objects, ordering by newest and oldest should result in arrays that are
31
+ # the inverse of the other.
32
+ named_scope :by_date_oldest_first, :order => 'published_at ASC, created_at ASC, id ASC'
33
+ named_scope :by_date_newest_first, :order => 'published_at DESC, created_at DESC, id DESC'
34
+ end
35
+ end
36
+
37
+ module ClassMethods
38
+ end
39
+
6
40
  end
7
41
  end
@@ -0,0 +1,2 @@
1
+ Real usage: ./script/generate publishing_logic_fields model_name [options]
2
+ Note: The generator will fail if the model does not exist
@@ -1,13 +1,14 @@
1
- class PublishingLogicGenerator < Rails::Generator::NamedBase
1
+ class PublishingLogicFieldsGenerator < Rails::Generator::NamedBase
2
2
  def initialize(args, options)
3
3
  super(args, options)
4
4
  end
5
5
 
6
6
  def manifest
7
7
  record do |m|
8
- m.migration_template 'publishing_logic_fields.rb', 'db/migrate', :assigns => {
8
+ class_name.camelize.constantize # Raise an error if model does not yet exist
9
+ m.migration_template 'db/migrate/add_publishing_logic_fields.rb.erb', 'db/migrate', :assigns => {
9
10
  :migration_name => "AddPublishingLogicFieldsTo#{class_name.pluralize.gsub(/::/, '')}"
10
- }, :migration_file_name => "add_publishing_logic_field_to_#{file_path.gsub(/\//, '_').pluralize}"
11
+ }, :migration_file_name => "add_publishing_logic_fields_to_#{file_path.gsub(/\//, '_').pluralize}"
11
12
  end
12
13
  end
13
14
  end
@@ -0,0 +1,13 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :<%= class_name.underscore.camelize.tableize %>, :publishing_enabled, :boolean
4
+ add_column :<%= class_name.underscore.camelize.tableize %>, :published_at, :datetime
5
+ add_column :<%= class_name.underscore.camelize.tableize %>, :published_until, :datetime
6
+ end
7
+
8
+ def self.down
9
+ remove_column :<%= class_name.underscore.camelize.tableize %>, :publishing_enabled
10
+ remove_column :<%= class_name.underscore.camelize.tableize %>, :published_at
11
+ remove_column :<%= class_name.underscore.camelize.tableize %>, :published_until
12
+ end
13
+ end
@@ -9,8 +9,156 @@ Factory.define :fun_item do |c|
9
9
  end
10
10
 
11
11
  describe PublishingLogic::ModelLogic do
12
- it "should be published by default" do
13
- # Factory.create(:fun_item, :publishing_enabled => true).should be_published
14
- Factory.create(:fun_item).should be_published
12
+ def create_objects_with_different_published_at_dates
13
+ @object2 = Factory.create(:fun_item, :publishing_enabled => true, :published_at => 2.days.ago)
14
+ @object1 = Factory.create(:fun_item, :publishing_enabled => true, :published_at => 1.days.ago)
15
+ @object3 = Factory.create(:fun_item, :publishing_enabled => true, :published_at => 3.days.ago)
16
+ end
17
+
18
+ describe "published?" do
19
+ describe "with publishing enabled" do
20
+ it "should be published by default" do
21
+ Factory.create(:fun_item,
22
+ :publishing_enabled => true,
23
+ :published_at => nil,
24
+ :published_until => nil).should be_published
25
+ end
26
+
27
+ it "should not be published if the published_at datetime is in the future" do
28
+ Factory.create(:fun_item,
29
+ :publishing_enabled => true,
30
+ :published_at => 5.seconds.from_now,
31
+ :published_until => nil).should_not be_published
32
+ end
33
+
34
+ it "should not be published if the published_until datetime is in the past" do
35
+ Factory.create(:fun_item,
36
+ :publishing_enabled => true,
37
+ :published_at => nil,
38
+ :published_until => 5.seconds.ago).should_not be_published
39
+ end
40
+ end
41
+ describe "with publishing disabled" do
42
+ it "should not be published" do
43
+ Factory.create(:fun_item,
44
+ :publishing_enabled => false,
45
+ :published_at => 1.days.ago,
46
+ :published_until => 10.days.from_now).should_not be_published
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "published named scope" do
52
+ it "should include published objects" do
53
+ fun_item = Factory.create(:fun_item, :publishing_enabled => true)
54
+ FunItem.published.should == [fun_item]
55
+ end
56
+
57
+ it "should not include any unpublished objects" do
58
+ fun_item = Factory.create(:fun_item, :publishing_enabled => false)
59
+ FunItem.published.should be_empty
60
+ end
61
+
62
+ # it "should not expose a published episode published an hour ago" do
63
+ # article = Factory.create(:episode, :is_hidden => false, :published_at => 1.hour.from_now, :published_until => nil)
64
+ # Episode.published.should == []
65
+ # end
66
+
67
+ it "should not include objects with a published_until in the past" do
68
+ Factory.create(:fun_item,
69
+ :publishing_enabled => true,
70
+ :published_until => 5.seconds.ago)
71
+ FunItem.published.should be_empty
72
+ end
73
+
74
+ it "should not include objects with a published_at in the future" do
75
+ Factory.create(:fun_item,
76
+ :publishing_enabled => true,
77
+ :published_at => 5.seconds.from_now)
78
+ FunItem.published.should be_empty
79
+ end
80
+
81
+ it "should get a new Time.now for each invocation of the named scope" do
82
+ item = Factory.create(:fun_item,
83
+ :publishing_enabled => true,
84
+ :published_until => 10.days.from_now)
85
+ mock_now = mock('now', :utc => 20.days.from_now, :to_f => 0)
86
+ Time.stub(:now).and_return mock_now
87
+ FunItem.published.should be_empty
88
+ end
89
+
90
+ it "should use the utc of the current time" do
91
+ # Make sure utc is used, which is hard to test as a behaviour
92
+ mock_now = mock('now')
93
+ Time.stub(:now).and_return mock_now
94
+ mock_now.should_receive(:utc).twice
95
+ FunItem.published
96
+ end
97
+
98
+ describe "newest" do
99
+ before do
100
+ create_objects_with_different_published_at_dates
101
+ end
102
+
103
+ it "should be the most recently published object" do
104
+ FunItem.published.newest.should == @object1
105
+ end
106
+ end
107
+ describe "oldest" do
108
+ it "should be the object published the longest ago" do
109
+ FunItem.published.oldest.should == @object3
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "ordering by published_at" do
115
+ describe "by date oldest first" do
116
+ it "should return the items, oldest first" do
117
+ create_objects_with_different_published_at_dates
118
+ FunItem.by_date_oldest_first.map(&:id).should == [@object3,
119
+ @object2,
120
+ @object1].map(&:id)
121
+ end
122
+
123
+ it "should order by created_at date if published_ats are equal" do
124
+ create_objects_with_different_published_at_dates
125
+ @object2b = Factory.create(:fun_item,
126
+ :publishing_enabled => true,
127
+ :published_at => @object2.published_at,
128
+ :created_at => 3.days.ago)
129
+ FunItem.by_date_oldest_first.map(&:id).should == [@object3,
130
+ @object2b,
131
+ @object2,
132
+ @object1].map(&:id)
133
+ end
134
+ end
135
+
136
+ describe "by date newest first" do
137
+ it "should return the items, oldest first" do
138
+ create_objects_with_different_published_at_dates
139
+ FunItem.by_date_newest_first.map(&:id).should == [@object1,
140
+ @object2,
141
+ @object3].map(&:id)
142
+ end
143
+
144
+ it "should order by created_at date if published_ats are equal" do
145
+ create_objects_with_different_published_at_dates
146
+ @object2b = Factory.create(:fun_item,
147
+ :publishing_enabled => true,
148
+ :published_at => @object2.published_at,
149
+ :created_at => 3.days.from_now)
150
+ FunItem.by_date_newest_first.map(&:id).should == [@object1,
151
+ @object2b,
152
+ @object2,
153
+ @object3].map(&:id)
154
+ end
155
+ end
156
+
157
+ it "should have a newest first ordering that is the reverse of the oldest first ordering for identical objects" do
158
+ creation_time = 2.days.ago
159
+ publish_time = 1.days.ago
160
+ 5.times { Factory.create(:fun_item, :created_at => creation_time, :published_at => publish_time) }
161
+ FunItem.by_date_newest_first.map(&:id).should == FunItem.by_date_oldest_first.map(&:id).reverse
162
+ end
15
163
  end
16
164
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: publishing_logic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Unboxed Consulting
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-09 00:00:00 +00:00
12
+ date: 2009-12-10 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -44,6 +44,7 @@ extra_rdoc_files:
44
44
  files:
45
45
  - .document
46
46
  - .gitignore
47
+ - .specification.example
47
48
  - LICENSE
48
49
  - README.rdoc
49
50
  - Rakefile
@@ -53,7 +54,9 @@ files:
53
54
  - features/support/env.rb
54
55
  - lib/model_logic.rb
55
56
  - lib/publishing_logic.rb
57
+ - rails_generators/publishing_logic_fields/USAGE
56
58
  - rails_generators/publishing_logic_fields/publishing_logic_fields_generator.rb
59
+ - rails_generators/publishing_logic_fields/templates/db/migrate/add_publishing_logic_fields.rb.erb
57
60
  - spec/lib/model_logic_spec.rb
58
61
  - spec/publishing_logic_spec.rb
59
62
  - spec/spec.opts