Chime.Test (Chime v0.1.0-dev)

Copy Markdown View Source

Helpers for the app's tests of its notifications, with no Oban to run and no clock to wait for.

import Chime.Test

test "a comment notifies the story's followers", %{story: story} do
  follower = user_fixture()
  story |> follow(follower)

  {:ok, comment} = Stories.comment(story, author, "Lovely.")

  notification = assert_notified(MyApp.Notifications.NewComment, to: follower)
  assert %{title: "Ana commented on Tokyo"} = feed(follower) |> hd()

  # The email waits ten minutes, unless the follower reads it first.
  deliver(at: DateTime.add(DateTime.utc_now(), 11, :minute))
  assert_email_sent(subject: "Ana commented on Tokyo")
end

Run the app's Oban in the tests with testing: :manual, so that the deliveries wait for deliver/1 (with :inline, Oban would send them at once, before their time), and start Chime with scheduler: false. The helpers run in the test's process, inside its sandbox: the emails of Swoosh's test adapter come to it, for Swoosh.TestAssertions.

A person is given as the app gives them to Chime.notify/3: the app's user (through the resolver's recipient/1), a Chime.Recipient or an id.

Summary

Functions

Asserts that a notifier notified a person, and returns their notification (with its event). Options

Runs the deliveries whose time came, in the test's process, as their jobs would, and returns them as they are after. Options

A person's deliveries, the latest first: [%Chime.Delivery{}]. Option :channel.

The events a notifier made, the latest first.

The log of a notification, as text (Chime.Explain.format/1).

A person's feed as the JSON API gives it: a map for each notification, with its :title, :body, :url, :count, :actors, :read... The options of Chime.feed/2.

Asserts that a notifier did not notify a person (same options).

Goes through the audiences being sent (Chime.Notifier.audience/1), every page, as their jobs would.

Sends the digests due at a time (now), as the hourly job would: for a daily digest at 9:00, a time after 9:00 the day after the notification.

Sends the scheduled notifications (Chime.notify/3 with :at) whose time came by at (now), as their jobs would.

Functions

assert_notified(notifier, opts)

@spec assert_notified(module(), keyword()) :: Chime.Notification.t()

Asserts that a notifier notified a person, and returns their notification (with its event). Options:

  • :to - the person (required).
  • :data - a map the event's data must contain: %{"story" => "Tokyo"}.

deliver(opts \\ [])

@spec deliver(keyword()) :: [Chime.Delivery.t()]

Runs the deliveries whose time came, in the test's process, as their jobs would, and returns them as they are after. Options:

  • :at - the time (now): deliver(at: DateTime.add(DateTime.utc_now(), 11, :minute)) runs those of the next ten minutes too.
  • :to - only a person's.
  • :channel - only a channel's ("email").
  • :last_attempt - whether a channel's error fails the delivery (true), as on its last attempt, or leaves it for another (false).

deliveries(recipient, opts \\ [])

@spec deliveries(term(), keyword()) :: [Chime.Delivery.t()]

A person's deliveries, the latest first: [%Chime.Delivery{}]. Option :channel.

events(notifier)

@spec events(module()) :: [Chime.Event.t()]

The events a notifier made, the latest first.

explain(notification)

@spec explain(Chime.Notification.t() | Ecto.UUID.t()) :: String.t()

The log of a notification, as text (Chime.Explain.format/1).

feed(recipient, opts \\ [])

@spec feed(term(), keyword()) :: [map()]

A person's feed as the JSON API gives it: a map for each notification, with its :title, :body, :url, :count, :actors, :read... The options of Chime.feed/2.

refute_notified(notifier, opts)

@spec refute_notified(module(), keyword()) :: :ok

Asserts that a notifier did not notify a person (same options).

run_audiences()

@spec run_audiences() :: :ok

Goes through the audiences being sent (Chime.Notifier.audience/1), every page, as their jobs would.

run_digests(at \\ DateTime.utc_now())

@spec run_digests(DateTime.t()) :: :ok

Sends the digests due at a time (now), as the hourly job would: for a daily digest at 9:00, a time after 9:00 the day after the notification.

run_scheduled(at \\ DateTime.utc_now())

@spec run_scheduled(DateTime.t()) :: :ok

Sends the scheduled notifications (Chime.notify/3 with :at) whose time came by at (now), as their jobs would.