Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat(coderd): add company logo when available for email notifications#14935

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
defelmnq merged 27 commits intomainfromfeat/notif-custom-logo
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
27 commits
Select commitHold shift + click to select a range
a42f108
feat(notifications): add company logo url when available for email no…
defelmnqOct 2, 2024
1fa1271
feat(notifications): adapt tests with new labels
defelmnqOct 3, 2024
2def52e
fix: revert changes on generated code version
defelmnqOct 3, 2024
1b1a4c4
feat(notification): move logo_url and app_name logic to helpers funct…
defelmnqOct 3, 2024
779260e
chore: remove unused GetLogoURL method from notifications store inter…
defelmnqOct 3, 2024
1e6899f
fix: add better context and timeout for db related queries
defelmnqOct 4, 2024
b552267
chore: lint
defelmnqOct 4, 2024
73e07e9
feat(notifications): improve logo_url and app_name fetching moving it…
defelmnqOct 16, 2024
70e23ae
feat(notifications): improve logo_url and app_name fetching moving it…
defelmnqOct 16, 2024
2f620c9
feat(notifications): improve logo_url and app_name fetching moving it…
defelmnqOct 16, 2024
fdcdf7b
feat(notifications): improve logo_url and app_name fetching moving it…
defelmnqOct 16, 2024
9c6c105
feat(coderd): regenerate golden files
Oct 16, 2024
0c131a5
feat(notifications): working on tests for logo and app_name
defelmnqOct 17, 2024
34d6611
feat(notifications): change helpers logic to be defined in the Dispat…
Oct 17, 2024
0a9a66a
feat(notifications): add golden file for custom appearance
Oct 17, 2024
bf558cb
feat(notifications): add golden file for custom appearance
Oct 17, 2024
a420f37
feat(notifications): work on tests
defelmnqOct 18, 2024
51d8d33
feat(notifications): add golden file for custom appearance
defelmnqOct 18, 2024
d492d09
feat(notifications): add golden file for custom appearance
defelmnqOct 18, 2024
0c9c485
feat(notifications): add comment ent in tests for enterprise feature
defelmnqOct 18, 2024
a6d4a0c
feat(coderd): remove unused call
defelmnqOct 18, 2024
4c5cb3d
fix(notifications): improve tests and some nit fixes
defelmnqOct 18, 2024
e419431
chore(retry): improve retry policy on fetcher
defelmnqOct 18, 2024
a7fec66
Merge remote-tracking branch 'origin/main' into feat/notif-custom-logo
defelmnqOct 21, 2024
8b766f6
improve errors handling
defelmnqOct 22, 2024
157e086
improve errors handling
defelmnqOct 22, 2024
790ff33
improve errors handling
defelmnqOct 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
feat(notifications): add golden file for custom appearance
  • Loading branch information
defelmnq committedOct 17, 2024
commit0a9a66a23e7db2201bdc220d1f4edc4b844cd8bd
308 changes: 135 additions & 173 deletionscoderd/notifications/notifications_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1414,7 +1414,7 @@

// GIVEN: a notification template which has a method explicitly set
var (
template = notifications.TemplateWorkspaceDormant

Check failure on line 1417 in coderd/notifications/notifications_test.go

View workflow job for this annotation

GitHub Actions/ lint

import-shadowing: The name 'template' shadows an import name (revive)
defaultMethod = database.NotificationMethodSmtp
customMethod = database.NotificationMethodWebhook
)
Expand DownExpand Up@@ -1562,7 +1562,7 @@
succeeded, failed []string
}

func (f *fakeHandler) Dispatcher(helpers template.FuncMap, payload types.MessagePayload, _, _ string) (dispatch.DeliveryFunc, error) {

Check failure on line 1565 in coderd/notifications/notifications_test.go

View workflow job for this annotation

GitHub Actions/ lint

unused-parameter: parameter 'helpers' seems to be unused, consider removing or renaming it as _ (revive)
return func(_ context.Context, msgID uuid.UUID) (retryable bool, err error) {
f.mu.Lock()
defer f.mu.Unlock()
Expand DownExpand Up@@ -1612,7 +1612,7 @@
return messages, err
}

funcTestNotificationTemplates_GoldenWithCustomLogoURL(t *testing.T) {
funcTestNotificationTemplates_GoldenWithCustomAppearance(t *testing.T) {
t.Parallel()

if !dbtestutil.WillUsePostgres() {
Expand All@@ -1629,205 +1629,167 @@
hint = "run \"DB=ci make update-golden-files\" and commit the changes"
)

tests := []struct {
name string
id uuid.UUID
payload types.MessagePayload
}{
{
name: "TemplateWorkspaceDeleted",
id: notifications.TemplateWorkspaceDeleted,
payload: types.MessagePayload{
UserName: "Bobby",
UserEmail: "bobby@coder.com",
UserUsername: "bobby",
Labels: map[string]string{
"name": "bobby-workspace",
"reason": "autodeleted due to dormancy",
"initiator": "autobuild",
},
var (
payload = types.MessagePayload{
Labels: map[string]string{
"name": "bobby-workspace",
"reason": "autodeleted due to dormancy",
"initiator": "autobuild",
},
},
}

// We must have a test case for every notification_template. This is enforced below:
allTemplates, err := enumerateAllTemplates(t)
require.NoError(t, err)
for _, name := range allTemplates {
var found bool
for _, tc := range tests {
if tc.name == name {
found = true
}
}
)

require.Truef(t, found, "could not find test case for %q", name)
}

for _, tc:=range tests {
tc := tc

t.Run(tc.name, func(t *testing.T) {
t.Parallel()

t.Run("smtp", func(t *testing.T) {
t.Parallel()

// Spin up the DB
db, logger, user := func() (*database.Store, *slog.Logger, *codersdk.User) {
adminClient, _, api := coderdtest.NewWithAPI(t, nil)
db := api.Database
db.UpsertApplicationName(context.Background(), "myNewValue")
firstUser := coderdtest.CreateFirstUser(t, adminClient)
// Spin up the DB
db, logger, user := func() (database.Store, *slog.Logger, *codersdk.User) {
adminClient, _, api := coderdtest.NewWithAPI(t, nil)
firstUser:=coderdtest.CreateFirstUser(t, adminClient)

_, user := coderdtest.CreateAnotherUserMutators(
t,
adminClient,
firstUser.OrganizationID,
[]rbac.RoleIdentifier{rbac.RoleUserAdmin()},
func(r *codersdk.CreateUserRequestWithOrgs) {
r.Username = "bobby"
r.Email = "bobby@coder.com"
r.Name = "Bobby"
},
)
return api.Database, &api.Logger, &user
}()

_, user := coderdtest.CreateAnotherUserMutators(
t,
adminClient,
firstUser.OrganizationID,
[]rbac.RoleIdentifier{rbac.RoleUserAdmin()},
func(r *codersdk.CreateUserRequestWithOrgs) {
r.Username = tc.payload.UserUsername
r.Email = tc.payload.UserEmail
r.Name = tc.payload.UserName
},
)
return &db, &api.Logger, &user
}()
// nolint:gocritic // Unit test.
ctx := dbauthz.AsSystemRestricted(testutil.Context(t, testutil.WaitSuperLong))

// nolint:gocritic // Unit test.
ctx := dbauthz.AsSystemRestricted(testutil.Context(t,testutil.WaitSuperLong))
err := db.UpsertApplicationName(ctx, "CustomApplication")
require.NoError(t,err)

ddb := *db
err := ddb.UpsertLogoURL(ctx, "newURL")
require.NoError(t, err)
err = db.UpsertLogoURL(ctx, "https://custom.application")
require.NoError(t, err)

// smtp config shared between client and server
smtpConfig := codersdk.NotificationsEmailConfig{
Hello: hello,
From: from,
// smtp config shared between client and server
smtpConfig := codersdk.NotificationsEmailConfig{
Hello: hello,
From: from,

Auth: codersdk.NotificationsEmailAuthConfig{
Username: username,
Password: password,
},
}
Auth: codersdk.NotificationsEmailAuthConfig{
Username: username,
Password: password,
},
}

// Spin up the mock SMTP server
backend := smtptest.NewBackend(smtptest.Config{
AuthMechanisms: []string{sasl.Login},
// Spin up the mock SMTP server
backend := smtptest.NewBackend(smtptest.Config{
AuthMechanisms: []string{sasl.Login},

AcceptedIdentity: smtpConfig.Auth.Identity.String(),
AcceptedUsername: username,
AcceptedPassword: password,
})
AcceptedIdentity: smtpConfig.Auth.Identity.String(),
AcceptedUsername: username,
AcceptedPassword: password,
})

// Create a mock SMTP server which conditionally listens for plain or TLS connections.
srv, listen, err := smtptest.CreateMockSMTPServer(backend, false)
require.NoError(t, err)
t.Cleanup(func() {
err := srv.Shutdown(ctx)
require.NoError(t, err)
})
// Create a mock SMTP server which conditionally listens for plain or TLS connections.
srv, listen, err := smtptest.CreateMockSMTPServer(backend, false)
require.NoError(t, err)
t.Cleanup(func() {
err := srv.Shutdown(ctx)
require.NoError(t, err)
})

var hp serpent.HostPort
require.NoError(t, hp.Set(listen.Addr().String()))
smtpConfig.Smarthost = hp
var hp serpent.HostPort
require.NoError(t, hp.Set(listen.Addr().String()))
smtpConfig.Smarthost = hp

// Start mock SMTP server in the background.
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
assert.NoError(t, srv.Serve(listen))
}()
// Start mock SMTP server in the background.
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
assert.NoError(t, srv.Serve(listen))
}()

// Wait for the server to become pingable.
require.Eventually(t, func() bool {
cl, err := smtptest.PingClient(listen, false, smtpConfig.TLS.StartTLS.Value())
if err != nil {
t.Logf("smtp not yet dialable: %s", err)
return false
}
// Wait for the server to become pingable.
require.Eventually(t, func() bool {
cl, err := smtptest.PingClient(listen, false, smtpConfig.TLS.StartTLS.Value())
if err != nil {
t.Logf("smtp not yet dialable: %s", err)
return false
}

if err = cl.Noop(); err != nil {
t.Logf("smtp not yet noopable: %s", err)
return false
}
if err = cl.Noop(); err != nil {
t.Logf("smtp not yet noopable: %s", err)
return false
}

if err = cl.Close(); err != nil {
t.Logf("smtp didn't close properly: %s", err)
return false
}
if err = cl.Close(); err != nil {
t.Logf("smtp didn't close properly: %s", err)
return false
}

return true
}, testutil.WaitShort, testutil.IntervalFast)
return true
}, testutil.WaitShort, testutil.IntervalFast)

smtpCfg := defaultNotificationsConfig(database.NotificationMethodSmtp)
smtpCfg.SMTP = smtpConfig
smtpCfg := defaultNotificationsConfig(database.NotificationMethodSmtp)
smtpCfg.SMTP = smtpConfig

smtpManager, err := notifications.NewManager(
smtpCfg,
*db,
defaultHelpers(),
createMetrics(),
logger.Named("manager"),
)
require.NoError(t, err)
smtpManager, err := notifications.NewManager(
smtpCfg,
db,
defaultHelpers(),
createMetrics(),
logger.Named("manager"),
)
require.NoError(t, err)

smtpManager.Run(ctx)
smtpManager.Run(ctx)

notificationCfg := defaultNotificationsConfig(database.NotificationMethodSmtp)
notificationCfg := defaultNotificationsConfig(database.NotificationMethodSmtp)

smtpEnqueuer, err := notifications.NewStoreEnqueuer(
notificationCfg,
*db,
defaultHelpers(),
logger.Named("enqueuer"),
quartz.NewReal(),
)
require.NoError(t, err)
smtpEnqueuer, err := notifications.NewStoreEnqueuer(
notificationCfg,
db,
defaultHelpers(),
logger.Named("enqueuer"),
quartz.NewReal(),
)
require.NoError(t, err)

_, err = smtpEnqueuer.EnqueueWithData(
ctx,
user.ID,
tc.id,
tc.payload.Labels,
tc.payload.Data,
user.Username,
user.ID,
)
require.NoError(t, err)
_, err = smtpEnqueuer.EnqueueWithData(
ctx,
user.ID,
notifications.TemplateWorkspaceDeleted,
payload.Labels,
payload.Data,
user.Username,
user.ID,
)
require.NoError(t, err)

// Wait for the message to be fetched
var msg *smtptest.Message
require.Eventually(t, func() bool {
msg = backend.LastMessage()
return msg != nil && len(msg.Contents) > 0
}, testutil.WaitShort, testutil.IntervalFast)
// Wait for the message to be fetched
var msg *smtptest.Message
require.Eventually(t, func() bool {
msg = backend.LastMessage()
return msg != nil && len(msg.Contents) > 0
}, testutil.WaitShort, testutil.IntervalFast)

body := normalizeGoldenEmail([]byte(msg.Contents))
body := normalizeGoldenEmail([]byte(msg.Contents))

err = smtpManager.Stop(ctx)
require.NoError(t, err)
err = smtpManager.Stop(ctx)
require.NoError(t, err)

partialName := strings.Split(t.Name(), "/")[1]
goldenFile := filepath.Join("testdata", "rendered-templates", "smtp", partialName+".html.golden")
if *updateGoldenFiles {
err = os.MkdirAll(filepath.Dir(goldenFile), 0o755)
require.NoError(t, err, "want no error creating golden file directory")
err = os.WriteFile(goldenFile, body, 0o600)
require.NoError(t, err, "want no error writing body golden file")
return
}
goldenFile := filepath.Join("testdata", "rendered-templates", "smtp", "TemplateWorkspaceDeleted_WithCustomAppearance.html.golden")

wantBody, err := os.ReadFile(goldenFile)
require.NoError(t, err, fmt.Sprintf("missing golden notification body file. %s", hint))
require.Empty(
t,
cmp.Diff(wantBody, body),
fmt.Sprintf("golden file mismatch: %s. If this is expected, %s. (-want +got). ", goldenFile, hint),
)
})
})
if *updateGoldenFiles {
err = os.MkdirAll(filepath.Dir(goldenFile), 0o755)
require.NoError(t, err, "want no error creating golden file directory")
err = os.WriteFile(goldenFile, body, 0o600)
require.NoError(t, err, "want no error writing body golden file")
}

wantBody, err := os.ReadFile(goldenFile)
require.NoError(t, err, fmt.Sprintf("missing golden notification body file. %s", hint))
require.Empty(
t,
cmp.Diff(wantBody, body),
fmt.Sprintf("golden file mismatch: %s. If this is expected, %s. (-want +got). ", goldenFile, hint),
)
}
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp