-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add attachments to kannon (#211)
- Loading branch information
1 parent
185d91e
commit 78a1e5c
Showing
15 changed files
with
408 additions
and
111 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 |
---|---|---|
@@ -0,0 +1,6 @@ | ||
-- migrate:up | ||
ALTER TABLE messages ADD COLUMN attachments JSONB; | ||
|
||
-- migrate:down | ||
|
||
ALTER TABLE messages DROP COLUMN attachments; |
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,45 @@ | ||
package sqlc | ||
|
||
import ( | ||
"database/sql/driver" | ||
"encoding/json" | ||
"fmt" | ||
) | ||
|
||
var ErrInvalidAttachment = fmt.Errorf("invalid attachment") | ||
|
||
type Attachments map[string][]byte | ||
|
||
// implement Vauler interface | ||
func (a Attachments) Value() (driver.Value, error) { | ||
return json.Marshal(a) | ||
} | ||
|
||
// implement Scanner interface | ||
func (a *Attachments) Scan(src interface{}) (err error) { | ||
defer func() { | ||
if err != nil { | ||
err = fmt.Errorf("%w: %w", ErrInvalidAttachment, err) | ||
} | ||
}() | ||
|
||
if src == nil { | ||
*a = nil | ||
return nil | ||
} | ||
|
||
var byteSrc []byte | ||
|
||
switch s := src.(type) { | ||
case []byte: | ||
byteSrc = s | ||
case string: | ||
byteSrc = []byte(s) | ||
default: | ||
return fmt.Errorf("unsupported scan type for TemplateType: %T", src) | ||
} | ||
|
||
err = json.Unmarshal(byteSrc, a) | ||
|
||
return | ||
} |
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,52 @@ | ||
package sqlc_test | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
sqlc "github.com/ludusrusso/kannon/internal/db" | ||
) | ||
|
||
func TestReadWriteAttachment(t *testing.T) { | ||
var testData = []struct { | ||
name string | ||
data sqlc.Attachments | ||
}{ | ||
{ | ||
name: "empty attachment", | ||
data: sqlc.Attachments{}, | ||
}, | ||
{ | ||
name: "single file attachment", | ||
data: sqlc.Attachments{ | ||
"file1.txt": []byte("this is a file"), | ||
}, | ||
}, | ||
{ | ||
name: "nil attachment", | ||
data: nil, | ||
}, | ||
} | ||
|
||
for _, tt := range testData { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// Marshal the attachment | ||
value, err := tt.data.Value() | ||
if err != nil { | ||
t.Fatalf("error marshaling attachment: %v", err) | ||
} | ||
|
||
// Unmarshal the attachment | ||
var att sqlc.Attachments | ||
err = att.Scan(value) | ||
if err != nil { | ||
t.Fatalf("error unmarshaling attachment: %v", err) | ||
} | ||
|
||
// Check if the attachments are the same | ||
if !reflect.DeepEqual(tt.data, att) { | ||
t.Fatalf("attachments are not equal: %v != %v", tt.data, att) | ||
} | ||
}) | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,5 @@ | ||
package mailbuilder | ||
|
||
import "io" | ||
|
||
type Attachments map[string]io.Reader |
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 |
---|---|---|
|
@@ -8,6 +8,7 @@ import ( | |
"io" | ||
"net/mail" | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
schema "github.com/ludusrusso/kannon/db" | ||
|
@@ -115,3 +116,55 @@ func TestPrepareMail(t *testing.T) { | |
|
||
assert.Equal(t, "test Test", string(html)) | ||
} | ||
|
||
func TestPrepareMailWithAttachments(t *testing.T) { | ||
d, err := adminAPI.CreateDomain(context.Background(), &adminapiv1.CreateDomainRequest{ | ||
Domain: "test2.com", | ||
}) | ||
assert.Nil(t, err) | ||
|
||
token := base64.StdEncoding.EncodeToString([]byte(d.Domain + ":" + d.Key)) | ||
ctx := metadata.NewIncomingContext(context.Background(), metadata.Pairs("authorization", "Basic "+token)) | ||
|
||
res, err := ma.SendHTML(ctx, &mailerapiv1.SendHTMLReq{ | ||
Sender: &pb.Sender{ | ||
Email: "[email protected]", | ||
Alias: "Test", | ||
}, | ||
Subject: "Test {{ name }}", | ||
Html: "test {{name }}", | ||
ScheduledTime: timestamppb.Now(), | ||
Recipients: []*pb.Recipient{ | ||
{ | ||
Email: "[email protected]", | ||
Fields: map[string]string{ | ||
"name": "Test", | ||
}, | ||
}, | ||
}, | ||
Attachments: []*mailerapiv1.Attachment{ | ||
{ | ||
Filename: "test.txt", | ||
Content: []byte("test"), | ||
}, | ||
}, | ||
}) | ||
assert.Nil(t, err) | ||
|
||
err = pm.SetScheduled(ctx, res.MessageId, "[email protected]") | ||
assert.Nil(t, err) | ||
|
||
emails, err := pm.PrepareForSend(context.Background(), 1) | ||
assert.Nil(t, err) | ||
assert.Equal(t, 1, len(emails)) | ||
|
||
m, err := mb.BuildEmail(context.Background(), emails[0]) | ||
assert.Nil(t, err) | ||
parsed, err := mail.ReadMessage(bytes.NewReader(m.Body)) | ||
assert.Nil(t, err) | ||
|
||
assert.Nil(t, err) | ||
assert.Equal(t, "[email protected]", parsed.Header.Get("To")) | ||
assert.Equal(t, "Test <[email protected]>", parsed.Header.Get("From")) | ||
assert.Equal(t, "multipart/mixed", strings.Split(parsed.Header.Get("Content-Type"), ";")[0]) | ||
} |
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.