-
Notifications
You must be signed in to change notification settings - Fork 354
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #115 from evgenyneu/feature/107-unsubscribe-from-e…
…mails Feature/107 Unsubscribe from emails
- Loading branch information
Showing
17 changed files
with
459 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,13 @@ | ||
{ | ||
"editor.formatOnSave": true, | ||
"editor.defaultFormatter": "svelte.svelte-vscode", | ||
"eslint.validate": ["javascript", "javascriptreact", "svelte"] | ||
"[svelte]": { | ||
"editor.defaultFormatter": "svelte.svelte-vscode" | ||
}, | ||
"[typescript]": { | ||
"editor.defaultFormatter": "esbenp.prettier-vscode" | ||
}, | ||
"[javascript]": { | ||
"editor.defaultFormatter": "esbenp.prettier-vscode" | ||
}, | ||
"eslint.validate": ["javascript", "javascriptreact", "typescript", "svelte"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
vi.mock("@supabase/supabase-js") | ||
vi.mock("$env/dynamic/private") | ||
vi.mock("resend") | ||
|
||
import { createClient, type User } from "@supabase/supabase-js" | ||
import { Resend } from "resend" | ||
import * as mailer from "./mailer" | ||
|
||
describe("mailer", () => { | ||
const mockSend = vi.fn().mockResolvedValue({ id: "mock-email-id" }) | ||
|
||
const mockSupabaseClient = { | ||
auth: { | ||
admin: { | ||
getUserById: vi.fn(), | ||
}, | ||
}, | ||
from: vi.fn().mockReturnThis(), | ||
select: vi.fn().mockReturnThis(), | ||
eq: vi.fn().mockReturnThis(), | ||
single: vi.fn(), | ||
} | ||
|
||
beforeEach(async () => { | ||
vi.clearAllMocks() | ||
const { env } = await import("$env/dynamic/private") | ||
env.PRIVATE_RESEND_API_KEY = "mock_resend_api_key" | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
;(createClient as any).mockReturnValue(mockSupabaseClient) | ||
|
||
vi.mocked(Resend).mockImplementation( | ||
() => | ||
({ | ||
emails: { | ||
send: mockSend, | ||
}, | ||
}) as unknown as Resend, | ||
) | ||
}) | ||
|
||
describe("sendUserEmail", () => { | ||
const mockUser = { id: "user123", email: "[email protected]" } | ||
|
||
it("sends welcome email", async () => { | ||
mockSupabaseClient.auth.admin.getUserById.mockResolvedValue({ | ||
data: { user: { email_confirmed_at: new Date().toISOString() } }, | ||
error: null, | ||
}) | ||
|
||
mockSupabaseClient.single.mockResolvedValue({ | ||
data: { unsubscribed: false }, | ||
error: null, | ||
}) | ||
|
||
await mailer.sendUserEmail({ | ||
user: mockUser as User, | ||
subject: "Test", | ||
from_email: "[email protected]", | ||
template_name: "welcome_email", | ||
template_properties: {}, | ||
}) | ||
|
||
expect(mockSend).toHaveBeenCalled() | ||
const email = mockSend.mock.calls[0][0] | ||
expect(email.to).toEqual(["[email protected]"]) | ||
}) | ||
|
||
it("should not send email if user is unsubscribed", async () => { | ||
const originalConsoleLog = console.log | ||
console.log = vi.fn() | ||
|
||
mockSupabaseClient.auth.admin.getUserById.mockResolvedValue({ | ||
data: { user: { email_confirmed_at: new Date().toISOString() } }, | ||
error: null, | ||
}) | ||
|
||
mockSupabaseClient.single.mockResolvedValue({ | ||
data: { unsubscribed: true }, | ||
error: null, | ||
}) | ||
|
||
await mailer.sendUserEmail({ | ||
user: mockUser as User, | ||
subject: "Test", | ||
from_email: "[email protected]", | ||
template_name: "welcome_email", | ||
template_properties: {}, | ||
}) | ||
|
||
expect(mockSend).not.toHaveBeenCalled() | ||
|
||
expect(console.log).toHaveBeenCalledWith( | ||
"User unsubscribed. Aborting email. ", | ||
mockUser.id, | ||
mockUser.email, | ||
) | ||
|
||
console.log = originalConsoleLog | ||
}) | ||
}) | ||
|
||
describe("sendTemplatedEmail", () => { | ||
it("sends templated email", async () => { | ||
await mailer.sendTemplatedEmail({ | ||
subject: "Test subject", | ||
from_email: "[email protected]", | ||
to_emails: ["[email protected]"], | ||
template_name: "welcome_email", | ||
template_properties: {}, | ||
}) | ||
|
||
expect(mockSend).toHaveBeenCalled() | ||
const email = mockSend.mock.calls[0][0] | ||
expect(email.from).toEqual("[email protected]") | ||
expect(email.to).toEqual(["[email protected]"]) | ||
expect(email.subject).toEqual("Test subject") | ||
expect(email.text).toContain("This is a quick sample of a welcome email") | ||
expect(email.html).toContain(">This is a quick sample of a welcome email") | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
src/routes/(admin)/account/(menu)/settings/change_email_subscription/+page.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<script lang="ts"> | ||
import SettingsModule from "../settings_module.svelte" | ||
export let data | ||
let { profile } = data | ||
let unsubscribed = profile?.unsubscribed | ||
</script> | ||
|
||
<svelte:head> | ||
<title>Change Email Subscription</title> | ||
</svelte:head> | ||
|
||
<h1 class="text-2xl font-bold mb-6"> | ||
{unsubscribed ? "Re-subscribe to Emails" : "Unsubscribe from Emails"} | ||
</h1> | ||
|
||
<SettingsModule | ||
editable={true} | ||
saveButtonTitle={unsubscribed | ||
? "Re-subscribe" | ||
: "Unsubscribe from all emails"} | ||
successBody={unsubscribed | ||
? "You have been re-subscribed to emails" | ||
: "You have been unsubscribed from all emails"} | ||
formTarget="/account/api?/toggleEmailSubscription" | ||
fields={[]} | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.