README.md in active_delivery-0.0.1 vs README.md in active_delivery-0.1.0
- old
+ new
@@ -1,9 +1,51 @@
+[![Gem Version](https://badge.fury.io/rb/active_delivery.svg)](https://badge.fury.io/rb/active_delivery)
+[![Build Status](https://travis-ci.org/palkan/active_delivery.svg?branch=master)](https://travis-ci.org/palkan/active_delivery)
+
# Active Delivery
Framework providing an entrypoint (single _interface_) for all types of notifications: mailers, push notifications, whatever you want.
+<a href="https://evilmartians.com/?utm_source=action_policy">
+<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
+
+Requirements:
+- Ruby ~> 2.3
+
+**NOTE**: although most of the examples in this readme are Rails-specific, this gem could be used without Rails/ActiveSupport.
+
+## The problem
+
+We need a way to handle different notifications _channel_ (mail, push) in one place.
+
+From the business-logic point of view we want to _notify_ a user, hence we need a _separate abstraction layer_ as an entrypoint to different types of notifications.
+
+## The solution
+
+Here comes the _Active Delivery_.
+
+In the simplest case when we have only mailers Active Delivery is just a wrapper for Mailer with (possibly) some additional logic provided (e.g. preventing emails to unsubscribed users).
+
+Motivations behind Active Delivery:
+- organize notifications related logic:
+
+```ruby
+# Before
+def after_some_action
+ MyMailer.with(user: user).some_action.deliver_later if user.receive_emails?
+ NotifyService.send_notification(user, "action") if whatever_else?
+end
+
+# After
+def after_some_action
+ MyDelivery.with(user: user).notify(:some_action)
+end
+```
+
+- better testability (see [Testing](#testing)).
+
+
## Usage
_Delivery_ class is used to trigger notifications. It describes how to notify a user (e.g. via email or via push notification or both):
```ruby
@@ -40,9 +82,62 @@
```ruby
PostsMailer.with(user: user).published(post)
```
See [Rails docs](https://api.rubyonrails.org/classes/ActionMailer/Parameterized.html) for more information on parameterized mailers.
+
+## Callbacks support
+
+**NOTE:** callbacks are only available if ActiveSupport is present in the app's env.
+
+```ruby
+# Run method before delivering notification
+# NOTE: when `false` is returned the executation is halted
+before_notify :do_something
+
+# You can specify a notification method (to run callback only for that method)
+before_notify :do_mail_something, on: :mailer
+
+# after_ and around_ callbacks are also supported
+after_notify :cleanup
+
+around_notify :set_context
+```
+
+## Testing
+
+**NOTE:** RSpec only for the time being.
+
+Active Delivery provides an elegant way to test deliveries in your code (i.e. when you want to test whether a notification has been sent) through a `have_delivered_to` matcher:
+
+```ruby
+it "delivers notification" do
+ expect { subject }.to have_delivered_to(Community::EventsDelivery, :modified, event)
+ .with(profile: profile)
+```
+
+You can also use such RSpec features as [compound expectations](https://relishapp.com/rspec/rspec-expectations/docs/compound-expectations) and [composed matchers](https://relishapp.com/rspec/rspec-expectations/v/3-8/docs/composing-matchers):
+
+```ruby
+it "delivers to rsvped members via .notify" do
+ expect { subject }.
+ to have_delivered_to(Community::EventsDelivery, :canceled, an_instance_of(event)).with(
+ a_hash_including(profile: another_profile)
+ ).and have_delivered_to(Community::EventsDelivery, :canceled, event).with(
+ profile: profile
+ )
+end
+```
+
+If you want to test that no notification is deliver you can use negation:
+
+```ruby
+specify "when event is not found" do
+ expect do
+ described_class.perform_now(profile.id, "123", "one_hour_before")
+ end.not_to have_delivered_to(Community::EventsDelivery)
+end
+```
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/palkan/active_delivery.