pubsub_notifier 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.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +174 -0
  3. data/Rakefile +6 -0
  4. data/lib/generators/pubsub_notifier/install/USAGE +2 -0
  5. data/lib/generators/pubsub_notifier/install/install_generator.rb +13 -0
  6. data/lib/generators/pubsub_notifier/install/templates/application_notifier.rb +2 -0
  7. data/lib/generators/pubsub_notifier/install/templates/initializer.rb +10 -0
  8. data/lib/generators/rails/USAGE +8 -0
  9. data/lib/generators/rails/notifier_generator.rb +13 -0
  10. data/lib/generators/rails/templates/notifier.rb +15 -0
  11. data/lib/generators/rspec/notifier_generator.rb +9 -0
  12. data/lib/generators/rspec/templates/notifier_spec.rb +5 -0
  13. data/lib/generators/test_unit/notifier_generator.rb +9 -0
  14. data/lib/generators/test_unit/templates/notifier_test.rb +11 -0
  15. data/lib/pubsub_notifier.rb +35 -0
  16. data/lib/pubsub_notifier/acts_as_notifier.rb +26 -0
  17. data/lib/pubsub_notifier/base.rb +43 -0
  18. data/lib/pubsub_notifier/broadcasters.rb +31 -0
  19. data/lib/pubsub_notifier/broadcasters/active_job_broadcaster.rb +32 -0
  20. data/lib/pubsub_notifier/client.rb +43 -0
  21. data/lib/pubsub_notifier/config.rb +13 -0
  22. data/lib/pubsub_notifier/proxy.rb +38 -0
  23. data/lib/pubsub_notifier/pubsub.rb +9 -0
  24. data/lib/pubsub_notifier/railtie.rb +18 -0
  25. data/lib/pubsub_notifier/slack_client.rb +86 -0
  26. data/lib/pubsub_notifier/version.rb +3 -0
  27. data/spec/pubsub_notifier_spec.rb +32 -0
  28. data/spec/spec_helper.rb +10 -0
  29. data/spec/support/models/member.rb +6 -0
  30. data/spec/support/models/user.rb +6 -0
  31. data/spec/support/notifiers/admin_notifier.rb +13 -0
  32. data/spec/support/notifiers/application_notifier.rb +2 -0
  33. data/spec/support/notifiers/user_notifier.rb +13 -0
  34. metadata +125 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7afc8a84729f47928bca7b4b3b432ceba1d98458
4
+ data.tar.gz: 10c9907f794ebd014e0dbe372b386ca6008f08e6
5
+ SHA512:
6
+ metadata.gz: 4e770a775b9e7f04cb9f59cefb02e845f06dbd2018f199841a35bdb43dd55f11bd2c08c30129a80fe351ac04c7e8c4d754d3e924780999cbd427fc912066b077
7
+ data.tar.gz: '03547309641d77529300b6b9d3116ba7b924beef44fd9457de49ff50234452fa235f4e6e36005cf4aaab11ab498c14a095b37edb019d63903e2a39c9fc809de2'
@@ -0,0 +1,174 @@
1
+ # PubsubNotifier
2
+
3
+ Publish-Subscribe Notifier for Ruby on Rails.
4
+
5
+ This gem relies on [krisleech/wisper](https://github.com/krisleech/wisper/) provides Pub/Sub capabilities.
6
+
7
+ ## Installation
8
+
9
+ ```ruby
10
+ gem 'pubsub_notifier'
11
+ ```
12
+
13
+ And you can run the generator, which will set up an application notifier with some useful defaults for you:
14
+
15
+ ```bash
16
+ rails g pubsub_notifier:install
17
+ ```
18
+
19
+ After generating your application notifier, restart the Rails server so that Rails can pick up any classes in the new `app/notifiers/` directory.
20
+
21
+ Optionally, you need to perform asynchronously. Add `sidekiq` or `resuque` to your Gemfile:
22
+
23
+ ```ruby
24
+ gem 'sidekiq'
25
+ ```
26
+
27
+ Then set your queue adapter of active_job:
28
+
29
+ ```ruby
30
+ Rails.application.config.active_job.queue_adapter = :sidekiq
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ### ActiveRecord
36
+
37
+ ```ruby
38
+ class User < ApplicationRecord
39
+ subscribe :UserMailer
40
+ subscribe :UserNotifier, async: true, queue: :high
41
+ end
42
+
43
+ class UserMailer < ApplicationMailer
44
+ acts_as_notifier
45
+
46
+ default from: 'admin@example.com'
47
+
48
+ def welcome(user)
49
+ @user = user
50
+ mail(to: @user.email, subject: 'Welcome to My Awesome Site')
51
+ end
52
+ end
53
+
54
+ class UserNotifier < ApplicationNotifier
55
+ use :slack, channel: '#general', username: 'angel', icon_emoji: ':innocent:'
56
+
57
+ def welcome(user)
58
+ notify_success("#{user.name} has joined.")
59
+ end
60
+ end
61
+
62
+ user = User.first
63
+ user.broadcast(:welcome) # or user.publish(:welcome)
64
+ ```
65
+
66
+ ### Pure Ruby Object
67
+
68
+ ```ruby
69
+ class Register
70
+ include PubsubNotifier::Proxy
71
+
72
+ subscribe :UserRegisterNotifier
73
+
74
+ attr_accessor :name
75
+
76
+ validates :name, presence: true
77
+
78
+ def execute
79
+ if valid?
80
+ broadcast(:success)
81
+ else
82
+ broadcast(:failure)
83
+ end
84
+ end
85
+ end
86
+
87
+ class UserRegisterNotifier < ApplicationNotifier
88
+ use :slack, channel: '#random', username: 'noreply', icon_emoji: ':grinning:'
89
+
90
+ def success(context)
91
+ notify_success('succeed')
92
+ end
93
+
94
+ def failure(context)
95
+ notify_failure('failure')
96
+ end
97
+ end
98
+
99
+ register = Register.new(name: 'hello')
100
+ register.execute
101
+ ```
102
+
103
+ ### Configuration
104
+
105
+ ```ruby
106
+ # config/initializers/pubsub_notifier.rb
107
+ PubsubNotifier.config.logger = Rails.logger
108
+
109
+ require "pubsub_notifier/slack_client"
110
+
111
+ PubsubNotifier::SlackClient.configure do |config|
112
+ config.default_channel = ENV['SLACK_DEFAULT_CHANNEL']
113
+ config.default_username = ENV['SLACK_DEFAULT_USERNAME']
114
+ config.default_icon_emoji = ENV['SLACK_DEFAULT_ICON_EMOJI']
115
+ config.webhook_url = ENV['SLACK_WEBHOOK_URL']
116
+ end
117
+ ```
118
+
119
+ ### Generate a Notifier class
120
+
121
+ You can generate a notifier class by generate command:
122
+
123
+ ```bash
124
+ rails g notifier user
125
+ create app/notifiers/user_notifier.rb
126
+ invoke test_unit
127
+ create test/notifiers/user_notifier_test.rb
128
+ ```
129
+
130
+ ### Implement Notification Client
131
+
132
+ You can easily implement Client for Notification like plugin:
133
+
134
+ ```ruby
135
+ module PubsubNotifier
136
+ class SomethingClient < ::PubsubNotifier::Client::Base
137
+ def initialize(options = {})
138
+ # implement this
139
+ end
140
+
141
+ def notify_success(message)
142
+ # implement this
143
+ end
144
+
145
+ def notify_failure(message)
146
+ # implement this
147
+ end
148
+
149
+ def something_special(*args)
150
+ # implement if you need
151
+ end
152
+ end
153
+ end
154
+
155
+ PubsubNotifier.clients :something, PubsubNotifier::SomethingClient
156
+ ```
157
+
158
+ Then you can use on a notifier class:
159
+
160
+ ```ruby
161
+ class SomeNotifier < ApplicationNotifier
162
+ use :something
163
+
164
+ def welcome(recipient)
165
+ notify_success(recipient.name)
166
+ end
167
+ end
168
+ ```
169
+
170
+ If you want to know more information to implement notification client, please check `lib/pubsub_notifier/slack_client.rb`.
171
+
172
+ ## License
173
+
174
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,2 @@
1
+ Description:
2
+ Generates an application notifier as a starting point for your application
@@ -0,0 +1,13 @@
1
+ module PubsubNotifier
2
+ class InstallGenerator < ::Rails::Generators::Base
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ def create_initializer_file
6
+ template "initializer.rb", "config/initializers/pubsub_notifier.rb"
7
+ end
8
+
9
+ def create_application_notifier_file
10
+ template "application_notifier.rb", "app/notifiers/application_notifier.rb"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationNotifier < PubsubNotifier::Base
2
+ end
@@ -0,0 +1,10 @@
1
+ PubsubNotifier.config.logger = Rails.logger
2
+
3
+ require "pubsub_notifier/slack_client"
4
+
5
+ PubsubNotifier::SlackClient.configure do |config|
6
+ config.default_channel = ENV['SLACK_DEFAULT_CHANNEL']
7
+ config.default_username = ENV['SLACK_DEFAULT_USERNAME']
8
+ config.default_icon_emoji = ENV['SLACK_DEFAULT_ICON_EMOJI']
9
+ config.webhook_url = ENV['SLACK_WEBHOOK_URL']
10
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Generates a notifier with the given name.
3
+
4
+ Example:
5
+ rails g notifier user
6
+
7
+ This will create:
8
+ app/notifiers/user_notifier.rb
@@ -0,0 +1,13 @@
1
+ module Rails
2
+ module Generators
3
+ class NotifierGenerator < ::Rails::Generators::NamedBase
4
+ source_root File.expand_path("../templates", __FILE__)
5
+
6
+ def create_notifier_file
7
+ template 'notifier.rb', File.join('app/notifiers', class_path, "#{file_name}_notifier.rb")
8
+ end
9
+
10
+ hook_for :test_framework
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %>Notifier < ApplicationNotifier
3
+ use :slack
4
+
5
+ def success(recipient)
6
+ record = recipient
7
+ notify_success("#{record} has successfully created.")
8
+ end
9
+
10
+ def failure(recipient)
11
+ record = recipient
12
+ notify_failure("#{record} cannot created.")
13
+ end
14
+ end
15
+ <% end -%>
@@ -0,0 +1,9 @@
1
+ module RSpec
2
+ class NotifierGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ def create_spec_file
6
+ template 'notifier_spec.rb', File.join('spec/notifiers', class_path, "#{file_name}_notifier_spec.rb")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ require '<%= File.exists?('spec/rails_helper.rb') ? 'rails_helper' : 'spec_helper' %>'
2
+
3
+ describe <%= class_name %>Notifier do
4
+ subject { <%= class_name %>Notifier.new }
5
+ end
@@ -0,0 +1,9 @@
1
+ module TestUnit
2
+ class NotifierGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path("../templates", __FILE__)
4
+
5
+ def create_spec_file
6
+ template 'notifier_test.rb', File.join('test/notifiers', class_path, "#{file_name}_notifier_test.rb")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class <%= singular_name.camelize %>NotifierTest < ActiveSupport::TestCase
4
+ def setup
5
+ @<%= singular_name %> = <%= class_name %>Notifier.new
6
+ end
7
+
8
+ # test "the truth" do
9
+ # assert true
10
+ # end
11
+ end
@@ -0,0 +1,35 @@
1
+ require "active_support/core_ext/string/inflections"
2
+ require "wisper"
3
+
4
+ module PubsubNotifier
5
+ def self.configure
6
+ yield config
7
+ end
8
+
9
+ def self.config
10
+ @_config ||= Config.new
11
+ end
12
+
13
+ def self.register_client(name, klass)
14
+ config.clients[name.to_sym] = klass
15
+ end
16
+
17
+ def self.register_broadcaster(name, klass)
18
+ Wisper.configuration.broadcaster(name.to_sym, klass.new)
19
+ end
20
+
21
+ def self.init!
22
+ register_client :logger, PubsubNotifier::Client::LoggerClient
23
+ end
24
+ end
25
+
26
+ require "pubsub_notifier/base"
27
+ require "pubsub_notifier/broadcasters"
28
+ require "pubsub_notifier/client"
29
+ require "pubsub_notifier/config"
30
+ require "pubsub_notifier/proxy"
31
+ require "pubsub_notifier/pubsub"
32
+ require "pubsub_notifier/railtie" if defined?(Rails)
33
+ require "pubsub_notifier/version"
34
+
35
+ PubsubNotifier.init!
@@ -0,0 +1,26 @@
1
+ module PubsubNotifier
2
+ module ActsAsNotifier
3
+ def self.included(klass)
4
+ klass.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def acts_as_notifier
9
+ class_eval do
10
+ class << self
11
+ private
12
+ # Override ActionMailer::Base#method_missing
13
+ # https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb#L576
14
+ def method_missing(method_name, *args)
15
+ if action_methods.include?(method_name.to_s)
16
+ ::ActionMailer::MessageDelivery.new(self, method_name, *args).tap(&:deliver)
17
+ else
18
+ super
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ module PubsubNotifier
2
+ class Base
3
+ class << self
4
+ def use(name, options = {})
5
+ @_client = ( clients[name.to_sym] || clients[:logger] ).new(options)
6
+ end
7
+
8
+ def client
9
+ @_client ||= clients[:logger].new
10
+ end
11
+
12
+ private
13
+
14
+ def clients
15
+ PubsubNotifier.config.clients
16
+ end
17
+
18
+ def method_missing(method_name, *args, &block)
19
+ super unless public_instance_methods.include?(method_name.to_sym)
20
+ new.public_send(method_name, *args, &block)
21
+ end
22
+
23
+ def respond_to_missing?(method_name, include_private = false)
24
+ public_instance_methods.include?(method_name.to_sym) || super
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def client
31
+ self.class.client
32
+ end
33
+
34
+ def method_missing(method_name, *args, &block)
35
+ super unless client.respond_to?(method_name.to_sym)
36
+ client.public_send(method_name, *args, &block)
37
+ end
38
+
39
+ def respond_to_missing?(method_name, include_private = false)
40
+ client.respond_to?(method_name.to_sym) || super
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ module PubsubNotifier
2
+ module Broadcasters
3
+ class Base
4
+ attr_accessor :options
5
+
6
+ def initialize
7
+ @options = {}
8
+ end
9
+
10
+ def configure(opts = {})
11
+ self.options = default_options.merge(opts).reject { |_, v| v.nil? }.each_with_object({}) do |(key, proc_or_value), result|
12
+ result[key] = proc_or_value.is_a?(Proc) ? proc_or_value.call : proc_or_value
13
+ end
14
+ end
15
+
16
+ def broadcast(subscriber, publisher, event, *args)
17
+ raise NotImplementedError
18
+ end
19
+
20
+ private
21
+
22
+ def logger
23
+ PubsubNotifier.config.logger
24
+ end
25
+
26
+ def default_options
27
+ {}
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ module PubsubNotifier
2
+ module Broadcasters
3
+ class ActiveJobBroadcaster < Base
4
+ def broadcast(subscriber, publisher, event, args)
5
+ configured_job.perform_later(subscriber.name, event, args)
6
+ rescue ActiveJob::SerializationError => e
7
+ # NOTE: Fallback if global_id is blank
8
+ logger.warn { e.inspect }
9
+ configured_job.perform_now(subscriber.name, event, *args)
10
+ end
11
+
12
+ private
13
+
14
+ def configured_job
15
+ BroadcastJob.set(options)
16
+ end
17
+
18
+ def default_options
19
+ { wait: nil, wait_until: nil, queue: :default }
20
+ end
21
+
22
+ class BroadcastJob < ::ActiveJob::Base
23
+ def perform(subscriber_name, event, args)
24
+ subscriber = subscriber_name.constantize
25
+ subscriber.public_send(event, *args)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ PubsubNotifier.register_broadcaster :async, PubsubNotifier::Broadcasters::ActiveJobBroadcaster
@@ -0,0 +1,43 @@
1
+ module PubsubNotifier
2
+ module Client
3
+ class Base
4
+ def self.configure
5
+ yield config
6
+ end
7
+
8
+ def self.config
9
+ @_config ||= self::Config.new
10
+ end
11
+
12
+ def initialize(options = {}); end
13
+
14
+ def notify_success(message)
15
+ raise NotImplementedError, "#{self.class}##{__method__} is not implemented"
16
+ end
17
+
18
+ def notify_failure(message)
19
+ raise NotImplementedError, "#{self.class}##{__method__} is not implemented"
20
+ end
21
+
22
+ private
23
+
24
+ def logger
25
+ PubsubNotifier.config.logger
26
+ end
27
+
28
+ def config
29
+ self.class.config
30
+ end
31
+ end
32
+
33
+ class LoggerClient < Base
34
+ def notify_success(message)
35
+ logger.debug { "[#{self.class}##{__method__}] #{message}" }
36
+ end
37
+
38
+ def notify_failure(message)
39
+ logger.debug { "[#{self.class}##{__method__}] #{message}" }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ require "logger"
2
+
3
+ module PubsubNotifier
4
+ class Config
5
+ attr_accessor :logger
6
+ attr_reader :clients
7
+
8
+ def initialize
9
+ @logger = Logger.new(STDOUT)
10
+ @clients = {}
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ module PubsubNotifier
2
+ module Proxy
3
+ def self.included(klass)
4
+ klass.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def subscribe(subscriber_name, options = {})
9
+ subscriber = subscriber_name.to_s.constantize
10
+ broadcaster = ( options.delete(:async) ? broadcasters[:async] : nil ) || broadcasters[:default]
11
+ broadcaster.configure(options) if broadcaster.respond_to?(:configure)
12
+ pubsub.subscribe(subscriber, broadcaster: broadcaster)
13
+ end
14
+
15
+ def pubsub
16
+ @_pubsub ||= ::PubsubNotifier::Pubsub.new
17
+ end
18
+
19
+ private
20
+
21
+ def broadcasters
22
+ Wisper.configuration.broadcasters
23
+ end
24
+ end
25
+
26
+ def broadcast(event)
27
+ pubsub.call(event, self)
28
+ end
29
+
30
+ alias pubilish broadcast
31
+
32
+ private
33
+
34
+ def pubsub
35
+ self.class.pubsub
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,9 @@
1
+ module PubsubNotifier
2
+ class Pubsub
3
+ include Wisper::Publisher
4
+
5
+ def call(event, *args)
6
+ broadcast(event, *args)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module PubsubNotifier
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "pubsub_notifier" do
4
+ ActiveSupport.on_load :active_record do
5
+ ActiveRecord::Base.send :include, ::PubsubNotifier::Proxy
6
+ end
7
+
8
+ ActiveSupport.on_load :active_job do
9
+ require "pubsub_notifier/broadcasters/active_job_broadcaster"
10
+ end
11
+
12
+ ActiveSupport.on_load :action_mailer do
13
+ require "pubsub_notifier/acts_as_notifier"
14
+ ActionMailer::Base.send :include, PubsubNotifier::ActsAsNotifier
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,86 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ module PubsubNotifier
6
+ class SlackClient < ::PubsubNotifier::Client::Base
7
+ attr_reader :channel, :username, :icon_emoji
8
+
9
+ def initialize(options = {})
10
+ @channel = options.delete(:channel) || default_channel
11
+ @username = options.delete(:username) || default_username
12
+ @icon_emoji = options.delete(:icon_emoji) || default_icon_emoji
13
+ end
14
+
15
+ def notify_success(message)
16
+ post_slack(
17
+ attachments: [{
18
+ text: message,
19
+ color: 'good',
20
+ mrkdwn_in: ['text'],
21
+ }],
22
+ )
23
+ end
24
+
25
+ def notify_failure(message)
26
+ post_slack(
27
+ attachments: [{
28
+ text: message,
29
+ color: 'danger',
30
+ mrkdwn_in: ['text'],
31
+ }],
32
+ )
33
+ end
34
+
35
+ private
36
+
37
+ def post_slack(payload)
38
+ Net::HTTP.post_form(
39
+ end_point_uri,
40
+ payload: default_payload.merge(payload).to_json,
41
+ )
42
+ end
43
+
44
+ def end_point_uri
45
+ @end_point_uri ||= URI.parse(webhook_url)
46
+ end
47
+
48
+ def default_payload
49
+ {
50
+ channel: channel,
51
+ link_names: 1,
52
+ username: username,
53
+ icon_emoji: icon_emoji,
54
+ }
55
+ end
56
+
57
+ def default_channel
58
+ config.default_channel
59
+ end
60
+
61
+ def default_username
62
+ config.default_username
63
+ end
64
+
65
+ def default_icon_emoji
66
+ config.default_icon_emoji
67
+ end
68
+
69
+ def webhook_url
70
+ config.webhook_url
71
+ end
72
+
73
+ class Config
74
+ attr_accessor :default_channel, :default_username, :default_icon_emoji, :webhook_url
75
+
76
+ def initialize
77
+ @default_channel = ENV['SLACK_DEFAULT_CHANNEL']
78
+ @default_username = ENV['SLACK_DEFAULT_USERNAME']
79
+ @default_icon_emoji = ENV['SLACK_DEFAULT_ICON_EMOJI']
80
+ @webhook_url = ENV['SLACK_WEBHOOK_URL']
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ PubsubNotifier.register_client :slack, PubsubNotifier::SlackClient
@@ -0,0 +1,3 @@
1
+ module PubsubNotifier
2
+ VERSION = "0.1.0".freeze
3
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe PubsubNotifier do
4
+ let(:user) { User.new }
5
+ let(:member) { Member.new }
6
+
7
+ describe "#publish_notifier" do
8
+ it "calls success method on subscribed classes" do
9
+ expect_any_instance_of(AdminNotifier).to receive(:success).once
10
+ expect_any_instance_of(UserNotifier).to receive(:success).once
11
+ user.broadcast(:success)
12
+ end
13
+
14
+ it "calls logger methods on subscribed classes" do
15
+ expect_any_instance_of(Logger).to receive(:debug).exactly(4).times
16
+ member.broadcast(:success)
17
+ member.broadcast(:failure)
18
+ end
19
+
20
+ it "calls only_admin methods on subscribed classes" do
21
+ expect_any_instance_of(AdminNotifier).to receive(:only_admin).once
22
+ expect_any_instance_of(UserNotifier).not_to receive(:only_admin).once
23
+ member.broadcast(:only_admin)
24
+ end
25
+
26
+ it "calls only_user methods on subscribed classes" do
27
+ expect_any_instance_of(UserNotifier).to receive(:only_user).once
28
+ expect_any_instance_of(AdminNotifier).not_to receive(:only_user).once
29
+ member.broadcast(:only_user)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,10 @@
1
+ require "bundler/setup"
2
+ require "pubsub_notifier"
3
+
4
+ require "pry"
5
+
6
+ require_relative "support/notifiers/application_notifier"
7
+ require_relative "support/notifiers/admin_notifier"
8
+ require_relative "support/notifiers/user_notifier"
9
+ require_relative "support/models/member"
10
+ require_relative "support/models/user"
@@ -0,0 +1,6 @@
1
+ class Member
2
+ include PubsubNotifier::Proxy
3
+
4
+ subscribe :AdminNotifier
5
+ subscribe :UserNotifier
6
+ end
@@ -0,0 +1,6 @@
1
+ class User
2
+ include PubsubNotifier::Proxy
3
+
4
+ subscribe :AdminNotifier
5
+ subscribe :UserNotifier
6
+ end
@@ -0,0 +1,13 @@
1
+ class AdminNotifier < ApplicationNotifier
2
+ def success(recipient)
3
+ notify_success("#{recipient.class}##{__method__}")
4
+ end
5
+
6
+ def failure(recipient)
7
+ notify_failure("#{recipient.class}##{__method__}")
8
+ end
9
+
10
+ def only_admin(recipient)
11
+ notify_success("#{recipient.class}##{__method__}")
12
+ end
13
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationNotifier < PubsubNotifier::Base
2
+ end
@@ -0,0 +1,13 @@
1
+ class UserNotifier < ApplicationNotifier
2
+ def success(recipient)
3
+ notify_success("#{recipient.class}##{__method__}")
4
+ end
5
+
6
+ def failure(recipient)
7
+ notify_failure("#{recipient.class}##{__method__}")
8
+ end
9
+
10
+ def only_user(recipient)
11
+ notify_success("#{recipient.class}##{__method__}")
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pubsub_notifier
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yoshiyuki Hirano
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: wisper
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.15'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.15'
55
+ description: Pub/Sub Notifier for Ruby on Rails
56
+ email:
57
+ - yhirano@me.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - README.md
63
+ - Rakefile
64
+ - lib/generators/pubsub_notifier/install/USAGE
65
+ - lib/generators/pubsub_notifier/install/install_generator.rb
66
+ - lib/generators/pubsub_notifier/install/templates/application_notifier.rb
67
+ - lib/generators/pubsub_notifier/install/templates/initializer.rb
68
+ - lib/generators/rails/USAGE
69
+ - lib/generators/rails/notifier_generator.rb
70
+ - lib/generators/rails/templates/notifier.rb
71
+ - lib/generators/rspec/notifier_generator.rb
72
+ - lib/generators/rspec/templates/notifier_spec.rb
73
+ - lib/generators/test_unit/notifier_generator.rb
74
+ - lib/generators/test_unit/templates/notifier_test.rb
75
+ - lib/pubsub_notifier.rb
76
+ - lib/pubsub_notifier/acts_as_notifier.rb
77
+ - lib/pubsub_notifier/base.rb
78
+ - lib/pubsub_notifier/broadcasters.rb
79
+ - lib/pubsub_notifier/broadcasters/active_job_broadcaster.rb
80
+ - lib/pubsub_notifier/client.rb
81
+ - lib/pubsub_notifier/config.rb
82
+ - lib/pubsub_notifier/proxy.rb
83
+ - lib/pubsub_notifier/pubsub.rb
84
+ - lib/pubsub_notifier/railtie.rb
85
+ - lib/pubsub_notifier/slack_client.rb
86
+ - lib/pubsub_notifier/version.rb
87
+ - spec/pubsub_notifier_spec.rb
88
+ - spec/spec_helper.rb
89
+ - spec/support/models/member.rb
90
+ - spec/support/models/user.rb
91
+ - spec/support/notifiers/admin_notifier.rb
92
+ - spec/support/notifiers/application_notifier.rb
93
+ - spec/support/notifiers/user_notifier.rb
94
+ homepage: https://github.com/yhirano55/pubsub_notifier
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 2.2.0
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.6.10
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Pub/Sub Notifier for Ruby on Rails
118
+ test_files:
119
+ - spec/pubsub_notifier_spec.rb
120
+ - spec/spec_helper.rb
121
+ - spec/support/models/member.rb
122
+ - spec/support/models/user.rb
123
+ - spec/support/notifiers/admin_notifier.rb
124
+ - spec/support/notifiers/application_notifier.rb
125
+ - spec/support/notifiers/user_notifier.rb