Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metabase channel #43924

Merged
merged 29 commits into from
Jun 19, 2024
Merged

Metabase channel #43924

merged 29 commits into from
Jun 19, 2024

Conversation

qnkhuat
Copy link
Contributor

@qnkhuat qnkhuat commented Jun 10, 2024

Introducing a new module: Channel™.

See the tech doc: https://www.notion.so/metabase/Notification-high-level-design-9620a4a69db0494f806a146cc9174964?pvs=4 for a detailed design.

What this PR does:

  • Create a new channel module with 2 multimethod: render-notification and send!
  • Migrate slack and email to this module

This PR shouldn't generate any behavior changes, though you'll see a bunch of tests got updated because many of our tests were written when we still have: pulse -- which is a notification with one or more cards. So I had to update those tests, some are reworked to alert test, some are removed.

Walk through of this PR and repl demo: loom

Results

Dashboard subscriptions

Screenshot 2024-06-11 at 18 39 06

Email

Before
Screenshot 2024-06-11 at 18 42 49

After
Screenshot 2024-06-11 at 18 40 45

Slack

Before
Screenshot 2024-06-11 at 18 45 29

After
Screenshot 2024-06-11 at 18 44 25

Alert

Screenshot 2024-06-11 at 18 52 20

Email

Before
Screenshot 2024-06-11 at 18 56 37

After
Screenshot 2024-06-11 at 18 52 09

Slack

Before
Screenshot 2024-06-11 at 18 56 54

After
Screenshot 2024-06-11 at 18 55 23

Note on testing update:
you'll see a lot of changes are about adding alert_condition = rows to the Pulse, this is because previously we have the Pulse feature -- which is a notification with one or more cards, it's different from dashboard subscriptions in that it doesn't associate with a dashboard. or you can think of it like : Alert is a special case of Pulse where it has only one card.

Since this feature is deprecated, I've converted most of the pulse tests to alert tests to change from a pulse to an alert; it's simply by adding an alert_condition.

Milestone 1 of: #43822

@qnkhuat qnkhuat requested a review from camsaul as a code owner June 10, 2024 10:37
@metabase-bot metabase-bot bot added the .Team/BackendComponents also known as BEC label Jun 10, 2024
@qnkhuat qnkhuat added the no-backport Do not backport this PR to any branch label Jun 10, 2024
Copy link

replay-io bot commented Jun 10, 2024

Status Complete ↗︎
Commit a2e03a9
Results
⚠️ 2 Flaky
2648 Passed

@qnkhuat qnkhuat changed the title Channel Metabase channel Jun 10, 2024
@qnkhuat
Copy link
Contributor Author

qnkhuat commented Jun 12, 2024

balanced?
Screenshot 2024-06-12 at 12 04 05

@@ -42,7 +42,8 @@
(process-query))
(process-query))]
{:card card
:result result}))
:result result
:type :card}))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding a :type here so execute-card this is considered a part, which is an internal data type that both alert and dashboard subscription usees for rendering.

:bcc? true})
(mt/regex-email-bodies #"Daily Sad Toucans")))))))

(deftest send-placeholder-card-test-pulse-test
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an old use case with pulse, it's no longer needed because this test endpoint only works on dashboard, and on dashboard all cards are saved.

;; This test follows a flow that the user/UI would follow by first creating a pulse, then making a small change to
;; that pulse and testing it. The primary purpose of this test is to ensure tha the pulse/test endpoint accepts data
;; of the same format that the pulse GET returns
(deftest update-flow-test
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with above, it's an use case with the old pulse.

@@ -861,40 +752,6 @@
processed))
(is (= @titles ["a.png"]))))))

(deftest multi-channel-test
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have many tests for alert send to email and slack, this is not needed.


(deftest bcc-enabled-pulse-test
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to metabase.channel.email_test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

99% of the code here and slack are moved from metabase.pulse

{:title card-name
:titleUrl (urls/card-url card-id)
:alertSchedule (alert-schedule-text channel)
:notificationText (if (nil? non-user-email)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was a bug before, alert email for non-user doesn't have the manage subscriptions link.

@@ -293,7 +293,7 @@
"Fetch a single *Pulse*, and hydrate it with a set of 'standard' hydrations; remove Alert columns, since this is a
*Pulse* and they will all be unset."
[pulse-or-id]
(some-> (t2/select-one Pulse :id (u/the-id pulse-or-id), :alert_condition nil)
(some-> (t2/select-one Pulse :id (u/the-id pulse-or-id))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in principle we shouldn't use this function anymore because there is no longer pulse, we should use retrieve-alert instead. But the problem is that alert has :card instead of :cards like pulse does, so lots of rendering code will break if we change to retrieve-alert.

I plan to rework this on the 2nd milestone, where we remove pulse alltogether

@@ -0,0 +1,102 @@
(ns metabase.channel.email
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

99% of the code here and slack are moved from metabase.pulse

@calherries
Copy link
Contributor

This is a fairly big PR. So before I have a look, can you confirm what subset of the tech doc this PR completes? And can I read it as-is to understand the high-level design, or have the plans changed somewhat?

@qnkhuat
Copy link
Contributor Author

qnkhuat commented Jun 13, 2024

@calherries This should partially address the Channel section in that tech doc. Specifically, this PR introduces 2 multimethods, render-notification and send!. Most of the changes are splitting the render + send logic from metabase.pulse and moving it to metabase.channel.*, so you should expect no behavior change.

((if (= :email channel-type)
:channel/email
:channel/slack)
(pulse.test-util/with-captured-channel-send-messages!
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you look at how tests were written before you'll see 2 different approaches with email and slack.

For slack, the assertions are made against the result of (send-pulse!), this is done by having a bunch of redefs to make (send-pulse!) return the rendered-notification for slack only.

But for email, the test ignore the result of (send-pulse!), instead it checks results from the global (mt/inbox) atom.

I also think the recent flakes with pulse is because we were using this global inbox atom, it could be that parallel tests mutate the inbox while a test is running.

So I create a new pulse.test-util/with-captured-channel-send-messages! macro which will capture all calls to (channel/send!), this function should take a message that is already rendered and is ready to send. Which means: for email, it's a html with recipients info, for slack: It contains all the rendered attachments and text.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also believe this will fix our flakes with pulse recently.

:email (thunk)
:slack (pulse.test-util/slack-test-setup! (thunk)))))))))

(defn- tests!
Copy link
Contributor Author

@qnkhuat qnkhuat Jun 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test helper uses redefs so it must end with !

(fn [_ _]
(is (= (rasta-pulse-email)
(mt/summarize-multipart-email #"Pulse Name"))))
(fn [_ [email]]
Copy link
Contributor Author

@qnkhuat qnkhuat Jun 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the result here is a list of emails, since this test only sends one we can take the first.

test/metabase/pulse_test.clj Outdated Show resolved Hide resolved
Copy link
Contributor

@piranha piranha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDK, aside from nitpicks - seems like this is exactly what is planned. :)

dev/src/dev/render_png.clj Outdated Show resolved Hide resolved
src/metabase/channel/core.clj Outdated Show resolved Hide resolved
@qnkhuat qnkhuat enabled auto-merge (squash) June 19, 2024 04:26
@qnkhuat qnkhuat merged commit 613318f into master Jun 19, 2024
110 checks passed
@qnkhuat qnkhuat deleted the channel branch June 19, 2024 09:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-backport Do not backport this PR to any branch .Team/BackendComponents also known as BEC
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants