digestifier 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 27be6b151cd80d803e6c983feb87ea0e352bb61e
4
- data.tar.gz: 7260331532953aaffeaa84f8d72ca492938aeb74
3
+ metadata.gz: 39498bf10b95798271d89f3db5eb5b871afe556e
4
+ data.tar.gz: 0d72ce2b9e333cde60c0c70bb172fecd17309f25
5
5
  SHA512:
6
- metadata.gz: 98e6c3b0b4f8ba45f75dd767ffc4de7a8bdb78bf61381e301b41c56d3f0fba7786fbeb7dacfeea761bc2dce191cde02b197a34cb9a24918506da026845ec4faf
7
- data.tar.gz: c504707b89804f761a826ae669e2ccf1f606183867b4be7e4ce4bbba6b78399fcd4904e02abb4f18ef6656a9df6227d58b00256926476f4347cf3d2f8f08d9e5
6
+ metadata.gz: b7fa6833c029c04c3e3ca31603058cbbad44422daebbb8d0dc7f6c0cb7a2070726c5d5ef703142ad8142134c390b182ebb533ca974c4bb662a1772b44822eb4b
7
+ data.tar.gz: 0f7693a1e3b202bbfc4e37ff82b6de376cc543dd9959acb6a0db163d9e1960d3de90ba165e13e683b6809a161a97e48ad372fdc03508cae31894639e44e2c610
data/README.md CHANGED
@@ -6,7 +6,7 @@ A simple Rails engine for sending out email digests of activity.
6
6
 
7
7
  Add this line to your application's Gemfile:
8
8
 
9
- gem 'digestifier', '0.1.0'
9
+ gem 'digestifier', '0.2.0'
10
10
 
11
11
  Don't forget to bundle:
12
12
 
@@ -28,11 +28,10 @@ Digestifier.sender = 'Hello <hello@inspire9.com>'
28
28
 
29
29
  # Set the digest object to a constant so it can be referred to elsewhere.
30
30
  DIGEST = Digestifier::Digest.new
31
- # Set the lambda that returns objects for the digest. This takes a single
32
- # argument - the time range - and should return a collection of objects. How
33
- # you get this collection is up to you, but the example below is a decent
34
- # starting point.
35
- DIGEST.contents = lambda { |range|
31
+ # Set the lambda that returns objects for the digest. This takes two arguments # - the recipient in question, and the time range - and should return a
32
+ # collection of objects. How you get this collection is up to you, but the
33
+ # example below is a decent starting point.
34
+ DIGEST.contents = lambda { |recipient, range|
36
35
  Article.where(created_at: range).order(:created_at)
37
36
  }
38
37
  # The digest recipients defaults to all User objects in your system. If you
@@ -118,6 +117,8 @@ Don't forget to include an unsubscribe link:
118
117
 
119
118
  ```erb
120
119
  <%= link_to 'Unsubscribe', unsubscribe_url_for(@recipient) %>
120
+ <!-- Or, if you've given your digest a label: -->
121
+ <%= link_to 'Unsubscribe', unsubscribe_url_for(@recipient, :news) %>
121
122
  ```
122
123
 
123
124
  Also: you'll very likely want to customise the email's subject - this is done via Rails' internationalisation:
@@ -151,6 +152,8 @@ class CustomMailer < ActionMailer::Base
151
152
 
152
153
  ### Contributing
153
154
 
155
+ Please note that this project is released with [a Contributor Code of Conduct](http://contributor-covenant.org/version/1/2/0/). By participating in this project you agree to abide by its terms.
156
+
154
157
  1. Fork this repository.
155
158
  2. Install [git-flow](https://github.com/nvie/gitflow/wiki/Installation) if you don't have it already, then initialise it within your local copy of this repository (`git flow init` - we stick with the defaults).
156
159
  3. Create your feature branch (`git flow feature start my-new-feature`)
@@ -160,4 +163,4 @@ class CustomMailer < ActionMailer::Base
160
163
 
161
164
  ## Licence
162
165
 
163
- Copyright (c) 2013-2014, Digestifier is developed and maintained by [Inspire9](http://inspire9.com), and is released under the open MIT Licence.
166
+ Copyright (c) 2013-2015, Digestifier is developed and maintained by [Inspire9](http://inspire9.com), and is released under the open MIT Licence.
@@ -1,11 +1,11 @@
1
1
  module Digestifier::UnsubscribesHelper
2
- def unsubscribe_path_for(user)
3
- setting = Digestifier::Setting.for(user)
2
+ def unsubscribe_path_for(user, digest = :digest)
3
+ setting = Digestifier::Setting.for(user, digest)
4
4
  digestifier.unsubscribe_path(setting.identifier)
5
5
  end
6
6
 
7
- def unsubscribe_url_for(user)
8
- setting = Digestifier::Setting.for(user)
7
+ def unsubscribe_url_for(user, digest = :digest)
8
+ setting = Digestifier::Setting.for(user, digest)
9
9
  digestifier.unsubscribe_url(setting.identifier)
10
10
  end
11
11
  end
@@ -12,11 +12,18 @@ class Digestifier::Setting < ActiveRecord::Base
12
12
  before_validation :set_identifier, on: :create
13
13
 
14
14
  def self.for(recipient, digest = :digest)
15
- where(
16
- digest: digest,
17
- recipient_type: recipient.class.name,
18
- recipient_id: recipient.id
19
- ).first || create(digest: digest, recipient: recipient)
15
+ attempts = 0
16
+ begin
17
+ where(
18
+ digest: digest,
19
+ recipient_type: recipient.class.name,
20
+ recipient_id: recipient.id
21
+ ).first || create(digest: digest, recipient: recipient)
22
+ rescue ActiveRecord::RecordNotUnique
23
+ attempts += 1
24
+ retry if attempts < 2
25
+ raise
26
+ end
20
27
  end
21
28
 
22
29
  def set_identifier!
@@ -4,7 +4,7 @@ class CreateSettings < ActiveRecord::Migration
4
4
  t.string :recipient_type, null: false
5
5
  t.integer :recipient_id, null: false
6
6
  t.text :preferences, null: false, default: '{}'
7
- t.timestamps
7
+ t.timestamps null: false
8
8
  end
9
9
 
10
10
  add_index :digestifier_settings, [:recipient_type, :recipient_id],
@@ -2,5 +2,6 @@ class AddEnabledToSettings < ActiveRecord::Migration
2
2
  def change
3
3
  add_column :digestifier_settings, :enabled, :boolean, default: true,
4
4
  null: false
5
+ Digestifier::Setting.reset_column_information
5
6
  end
6
7
  end
@@ -1,6 +1,7 @@
1
1
  class AddIdentifierToSettings < ActiveRecord::Migration
2
2
  def up
3
3
  add_column :digestifier_settings, :identifier, :string
4
+ Digestifier::Setting.reset_column_information
4
5
 
5
6
  Digestifier::Setting.find_each do |setting|
6
7
  setting.set_identifier!
@@ -12,5 +13,6 @@ class AddIdentifierToSettings < ActiveRecord::Migration
12
13
 
13
14
  def down
14
15
  remove_column :digestifier_settings, :identifier
16
+ Digestifier::Setting.reset_column_information
15
17
  end
16
18
  end
@@ -2,6 +2,7 @@ class AddDigestToSettings < ActiveRecord::Migration
2
2
  def up
3
3
  add_column :digestifier_settings, :digest, :string
4
4
  execute "UPDATE digestifier_settings SET digest = 'digest'"
5
+ Digestifier::Setting.reset_column_information
5
6
 
6
7
  change_column :digestifier_settings, :digest, :string, null: false
7
8
  add_index :digestifier_settings, :digest
@@ -14,6 +15,7 @@ class AddDigestToSettings < ActiveRecord::Migration
14
15
  def down
15
16
  remove_index :digestifier_settings, name: 'unique_recipients'
16
17
  remove_column :digestifier_settings, :digest
18
+ Digestifier::Setting.reset_column_information
17
19
 
18
20
  add_index :digestifier_settings, [:recipient_type, :recipient_id],
19
21
  unique: true
@@ -2,6 +2,7 @@ class AddDigestToReceipts < ActiveRecord::Migration
2
2
  def up
3
3
  add_column :digestifier_receipts, :digest, :string
4
4
  execute "UPDATE digestifier_receipts SET digest = 'digest'"
5
+ Digestifier::Receipt.reset_column_information
5
6
 
6
7
  change_column :digestifier_receipts, :digest, :string, null: false
7
8
  add_index :digestifier_receipts, :digest
@@ -14,6 +15,7 @@ class AddDigestToReceipts < ActiveRecord::Migration
14
15
  def down
15
16
  remove_index :digestifier_receipts, name: 'unique_digest_receipts'
16
17
  remove_column :digestifier_receipts, :digest
18
+ Digestifier::Receipt.reset_column_information
17
19
 
18
20
  add_index :digestifier_receipts, [:recipient_type, :recipient_id],
19
21
  unique: true
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  Gem::Specification.new do |spec|
3
3
  spec.name = 'digestifier'
4
- spec.version = '0.1.0'
4
+ spec.version = '0.2.0'
5
5
  spec.authors = ['Pat Allan']
6
6
  spec.email = ['pat@freelancing-gods.com']
7
7
  spec.summary = 'Digests as a Rails Engine'
@@ -17,6 +17,6 @@ Gem::Specification.new do |spec|
17
17
  spec.add_runtime_dependency 'rails', '>= 3.2'
18
18
 
19
19
  spec.add_development_dependency 'combustion', '~> 0.5.1'
20
- spec.add_development_dependency 'rspec-rails', '~> 2.14.0'
21
- spec.add_development_dependency 'sqlite3', '~> 1.3.8'
20
+ spec.add_development_dependency 'rspec-rails', '~> 3.3.3'
21
+ spec.add_development_dependency 'sqlite3', '~> 1.3.10'
22
22
  end
@@ -1,7 +1,7 @@
1
1
  class Digestifier::Delivery
2
2
  def self.deliver(digest)
3
3
  digest.recipients.call.find_each do |recipient|
4
- new(digest, recipient).deliver_and_capture
4
+ Digestifier::Delivery.new(digest, recipient).deliver_and_capture
5
5
  end
6
6
  end
7
7
 
@@ -31,7 +31,7 @@ class Digestifier::Delivery
31
31
  delegate :default_frequency, to: :digest
32
32
 
33
33
  def contents
34
- digest.contents.call(last_sent..Time.zone.now)
34
+ digest.contents.call(recipient, last_sent..Time.zone.now)
35
35
  end
36
36
 
37
37
  def frequency
@@ -42,7 +42,7 @@ class Digestifier::Delivery
42
42
 
43
43
  def last_sent
44
44
  receipt = Digestifier::Receipt.last_for(recipient, digest.identifier)
45
- receipt.nil? ? frequency.ago : receipt.captured_at
45
+ receipt.nil? ? frequency.to_i.seconds.ago : receipt.captured_at
46
46
  end
47
47
 
48
48
  def settings
@@ -1,13 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Custom digest partials' do
3
+ RSpec.describe 'Custom digest partials' do
4
4
  let(:digest) { Digestifier::Digest.new }
5
5
  let(:user) { User.create! email: 'me@somewhere.com' }
6
6
 
7
7
  before :each do
8
8
  ActionMailer::Base.deliveries.clear
9
9
 
10
- digest.contents = lambda { |range|
10
+ digest.contents = lambda { |user, range|
11
11
  Book.where(created_at: range).order(:created_at)
12
12
  }
13
13
 
@@ -1,13 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Delivering digests' do
3
+ RSpec.describe 'Delivering digests' do
4
4
  let(:digest) { Digestifier::Digest.new }
5
5
  let(:user) { User.create! email: 'me@somewhere.com' }
6
6
 
7
7
  before :each do
8
8
  ActionMailer::Base.deliveries.clear
9
9
 
10
- digest.contents = lambda { |range|
10
+ digest.contents = lambda { |user, range|
11
11
  Article.where(created_at: range).order(:created_at)
12
12
  }
13
13
 
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Multiple Digests' do
3
+ RSpec.describe 'Multiple Digests' do
4
4
  let(:food_digest) { Digestifier::Digest.new :food }
5
5
  let(:tech_digest) { Digestifier::Digest.new :tech }
6
6
  let(:user) { User.create! email: 'me@somewhere.com' }
@@ -8,10 +8,10 @@ describe 'Multiple Digests' do
8
8
  before :each do
9
9
  ActionMailer::Base.deliveries.clear
10
10
 
11
- food_digest.contents = lambda { |range|
11
+ food_digest.contents = lambda { |user, range|
12
12
  Article.category('food').where(created_at: range).order(:created_at)
13
13
  }
14
- tech_digest.contents = lambda { |range|
14
+ tech_digest.contents = lambda { |user, range|
15
15
  Article.category('tech').where(created_at: range).order(:created_at)
16
16
  }
17
17
 
@@ -85,16 +85,16 @@ describe 'Multiple Digests' do
85
85
 
86
86
  Digestifier::Delivery.deliver food_digest
87
87
 
88
- ActionMailer::Base.deliveries.detect { |mail|
88
+ expect(ActionMailer::Base.deliveries.detect { |mail|
89
89
  mail.to.include?('me@somewhere.com')
90
- }.should_not be_nil
90
+ }).not_to be_nil
91
91
 
92
92
  ActionMailer::Base.deliveries.clear
93
93
 
94
94
  Digestifier::Delivery.deliver tech_digest
95
95
 
96
- ActionMailer::Base.deliveries.detect { |mail|
96
+ expect(ActionMailer::Base.deliveries.detect { |mail|
97
97
  mail.to.include?('me@somewhere.com')
98
- }.should be_nil
98
+ }).to be_nil
99
99
  end
100
100
  end
@@ -1,13 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Custom digest frequency' do
3
+ RSpec.describe 'Custom digest frequency' do
4
4
  let(:digest) { Digestifier::Digest.new }
5
5
  let(:user) { User.create! email: 'me@somewhere.com' }
6
6
 
7
7
  before :each do
8
8
  ActionMailer::Base.deliveries.clear
9
9
 
10
- digest.contents = lambda { |range|
10
+ digest.contents = lambda { |user, range|
11
11
  Article.where(created_at: range).order(:created_at)
12
12
  }
13
13
  end
@@ -39,8 +39,8 @@ describe 'Custom digest frequency' do
39
39
 
40
40
  Digestifier::Delivery.deliver digest
41
41
 
42
- ActionMailer::Base.deliveries.detect { |mail|
42
+ expect(ActionMailer::Base.deliveries.detect { |mail|
43
43
  mail.to.include?('me@somewhere.com')
44
- }.should be_nil
44
+ }).to be_nil
45
45
  end
46
46
  end
@@ -1,15 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Unsubscribing' do
3
+ RSpec.describe 'Unsubscribing', type: :request do
4
4
  let(:user) { User.create! email: 'me@somewhere.com' }
5
5
 
6
6
  it "marks a user as unsubscribed" do
7
7
  setting = Digestifier::Setting.for(user)
8
- expect(setting.enabled).to be_true
8
+ expect(setting.enabled).to eq(true)
9
9
 
10
10
  get "/digests/unsubscribe/#{setting.identifier}"
11
11
 
12
12
  setting.reload
13
- expect(setting.enabled).to be_false
13
+ expect(setting.enabled).to eq(false)
14
14
  end
15
15
  end
@@ -2,16 +2,16 @@ ActiveRecord::Schema.define do
2
2
  create_table :articles, :force => true do |table|
3
3
  table.string :name
4
4
  table.string :category
5
- table.timestamps
5
+ table.timestamps null: false
6
6
  end
7
7
 
8
8
  create_table :books, :force => true do |table|
9
9
  table.string :title
10
- table.timestamps
10
+ table.timestamps null: false
11
11
  end
12
12
 
13
13
  create_table :users, :force => true do |table|
14
14
  table.string :email
15
- table.timestamps
15
+ table.timestamps null: false
16
16
  end
17
17
  end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Digestifier::Setting, type: :model do
4
+ describe '.for' do
5
+ let(:setting) { double 'Setting' }
6
+ let(:recipient) { double 'Recipient', id: 389 }
7
+
8
+ it 'returns an existing setting' do
9
+ allow(Digestifier::Setting).to receive(:where).and_return([setting])
10
+
11
+ expect(Digestifier::Setting.for(recipient)).to eq(setting)
12
+ end
13
+
14
+ it 'creates a new setting if it does not exist' do
15
+ allow(Digestifier::Setting).to receive(:where).and_return([])
16
+ allow(Digestifier::Setting).to receive(:create).and_return(setting)
17
+
18
+ expect(Digestifier::Setting.for(recipient)).to eq(setting)
19
+ end
20
+
21
+ it 'retries find if create raises an exception' do
22
+ attempts = 0
23
+ allow(Digestifier::Setting).to receive(:where).and_return([])
24
+ allow(Digestifier::Setting).to receive(:create) do |attributes|
25
+ attempts += 1
26
+ raise ActiveRecord::RecordNotUnique, 'fail' if attempts <= 1
27
+ setting
28
+ end
29
+
30
+ expect(Digestifier::Setting.for(recipient)).to eq(setting)
31
+ end
32
+
33
+ it 'raises an error if create fails twice' do
34
+ attempts = 0
35
+ allow(Digestifier::Setting).to receive(:where).and_return([])
36
+ allow(Digestifier::Setting).to receive(:create) do |attributes|
37
+ attempts += 1
38
+ raise ActiveRecord::RecordNotUnique, 'fail' if attempts <= 2
39
+ setting
40
+ end
41
+
42
+ expect { Digestifier::Setting.for(recipient) }.
43
+ to raise_error(ActiveRecord::RecordNotUnique)
44
+ end
45
+ end
46
+ end
@@ -13,7 +13,4 @@ Dir["./spec/support/**/*.rb"].each { |file| require file }
13
13
 
14
14
  RSpec.configure do |config|
15
15
  config.use_transactional_fixtures = true
16
-
17
- config.include RSpec::Rails::RequestExampleGroup, type: :request,
18
- example_group: {file_path: /spec\/acceptance/}
19
16
  end
metadata CHANGED
@@ -1,71 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: digestifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Allan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-28 00:00:00.000000000 Z
11
+ date: 2015-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: combustion
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.5.1
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.5.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec-rails
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.14.0
47
+ version: 3.3.3
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 2.14.0
54
+ version: 3.3.3
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sqlite3
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.3.8
61
+ version: 1.3.10
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.3.8
68
+ version: 1.3.10
69
69
  description: A Rails engine that lets you define and customise digest emails
70
70
  email:
71
71
  - pat@freelancing-gods.com
@@ -73,8 +73,8 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
- - .gitignore
77
- - .travis.yml
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
78
  - Gemfile
79
79
  - LICENSE.txt
80
80
  - README.md
@@ -117,6 +117,7 @@ files:
117
117
  - spec/internal/db/schema.rb
118
118
  - spec/internal/log/.gitignore
119
119
  - spec/internal/public/favicon.ico
120
+ - spec/models/digestifier/setting_spec.rb
120
121
  - spec/spec_helper.rb
121
122
  homepage: https://github.com/inspire9/digestifier
122
123
  licenses:
@@ -128,17 +129,17 @@ require_paths:
128
129
  - lib
129
130
  required_ruby_version: !ruby/object:Gem::Requirement
130
131
  requirements:
131
- - - '>='
132
+ - - ">="
132
133
  - !ruby/object:Gem::Version
133
134
  version: '0'
134
135
  required_rubygems_version: !ruby/object:Gem::Requirement
135
136
  requirements:
136
- - - '>='
137
+ - - ">="
137
138
  - !ruby/object:Gem::Version
138
139
  version: '0'
139
140
  requirements: []
140
141
  rubyforge_project:
141
- rubygems_version: 2.2.2
142
+ rubygems_version: 2.4.8
142
143
  signing_key:
143
144
  specification_version: 4
144
145
  summary: Digests as a Rails Engine
@@ -159,4 +160,5 @@ test_files:
159
160
  - spec/internal/db/schema.rb
160
161
  - spec/internal/log/.gitignore
161
162
  - spec/internal/public/favicon.ico
163
+ - spec/models/digestifier/setting_spec.rb
162
164
  - spec/spec_helper.rb