feat: add subject to email template

This commit is contained in:
Lakhan Samani 2022-07-29 16:15:57 +05:30
parent 9ba1239c11
commit db4d711cba
10 changed files with 117 additions and 8 deletions

View File

@ -12,6 +12,7 @@ type EmailTemplate struct {
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty"` // for arangodb
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name"`
Subject string `gorm:"type:text" json:"subject" bson:"subject" cql:"subject"`
Template string `gorm:"type:text" json:"template" bson:"template" cql:"template"`
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
@ -26,6 +27,7 @@ func (e *EmailTemplate) AsAPIEmailTemplate() *model.EmailTemplate {
return &model.EmailTemplate{
ID: id,
EventName: e.EventName,
Subject: e.Subject,
Template: e.Template,
CreatedAt: refs.NewInt64Ref(e.CreatedAt),
UpdatedAt: refs.NewInt64Ref(e.UpdatedAt),

View File

@ -29,7 +29,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
return nil, fmt.Errorf("Email template with %s event_name already exists", emailTemplate.EventName)
}
insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, template, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.EmailTemplate, emailTemplate.ID, emailTemplate.EventName, emailTemplate.Template, emailTemplate.CreatedAt, emailTemplate.UpdatedAt)
insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, subject, template, created_at, updated_at) VALUES ('%s', '%s', '%s','%s', %d, %d)", KeySpace+"."+models.Collections.EmailTemplate, emailTemplate.ID, emailTemplate.EventName, emailTemplate.Subject, emailTemplate.Template, emailTemplate.CreatedAt, emailTemplate.UpdatedAt)
err := p.db.Query(insertQuery).Exec()
if err != nil {
return nil, err
@ -103,14 +103,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
query := fmt.Sprintf("SELECT id, event_name, template, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.EmailTemplate, pagination.Limit+pagination.Offset)
query := fmt.Sprintf("SELECT id, event_name, subject, template, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.EmailTemplate, pagination.Limit+pagination.Offset)
scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0)
for scanner.Next() {
if counter >= pagination.Offset {
var emailTemplate models.EmailTemplate
err := scanner.Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
err := scanner.Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
return nil, err
}
@ -128,8 +128,8 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
// GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
query := fmt.Sprintf(`SELECT id, event_name, template, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.EmailTemplate, emailTemplateID)
err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
query := fmt.Sprintf(`SELECT id, event_name, subject, template, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.EmailTemplate, emailTemplateID)
err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
return nil, err
}
@ -139,8 +139,8 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
// GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
query := fmt.Sprintf(`SELECT id, event_name, template, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.EmailTemplate, eventName)
err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
query := fmt.Sprintf(`SELECT id, event_name, subject, template, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.EmailTemplate, eventName)
err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
return nil, err
}

View File

@ -214,6 +214,12 @@ func NewProvider() (*provider, error) {
if err != nil {
return nil, err
}
// add subject on email_templates table
emailTemplateAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD subject text;`, KeySpace, models.Collections.EmailTemplate)
err = session.Query(emailTemplateAlterQuery).Exec()
if err != nil {
return nil, err
}
return &provider{
db: session,

View File

@ -56,6 +56,7 @@ type ComplexityRoot struct {
CreatedAt func(childComplexity int) int
EventName func(childComplexity int) int
ID func(childComplexity int) int
Subject func(childComplexity int) int
Template func(childComplexity int) int
UpdatedAt func(childComplexity int) int
}
@ -403,6 +404,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.EmailTemplate.ID(childComplexity), true
case "EmailTemplate.subject":
if e.complexity.EmailTemplate.Subject == nil {
break
}
return e.complexity.EmailTemplate.Subject(childComplexity), true
case "EmailTemplate.template":
if e.complexity.EmailTemplate.Template == nil {
break
@ -1978,6 +1986,7 @@ type EmailTemplate {
id: ID!
event_name: String!
template: String!
subject: String!
created_at: Int64
updated_at: Int64
}
@ -2193,6 +2202,7 @@ input TestEndpointRequest {
input AddEmailTemplateRequest {
event_name: String!
subject: String!
template: String!
}
@ -2200,6 +2210,7 @@ input UpdateEmailTemplateRequest {
id: ID!
event_name: String
template: String
subject: String
}
input DeleteEmailTemplateRequest {
@ -3108,6 +3119,41 @@ func (ec *executionContext) _EmailTemplate_template(ctx context.Context, field g
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _EmailTemplate_subject(ctx context.Context, field graphql.CollectedField, obj *model.EmailTemplate) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "EmailTemplate",
Field: field,
Args: nil,
IsMethod: false,
IsResolver: false,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.Subject, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _EmailTemplate_created_at(ctx context.Context, field graphql.CollectedField, obj *model.EmailTemplate) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -10087,6 +10133,14 @@ func (ec *executionContext) unmarshalInputAddEmailTemplateRequest(ctx context.Co
if err != nil {
return it, err
}
case "subject":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("subject"))
it.Subject, err = ec.unmarshalNString2string(ctx, v)
if err != nil {
return it, err
}
case "template":
var err error
@ -10866,6 +10920,14 @@ func (ec *executionContext) unmarshalInputUpdateEmailTemplateRequest(ctx context
if err != nil {
return it, err
}
case "subject":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("subject"))
it.Subject, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
}
}
@ -11632,6 +11694,11 @@ func (ec *executionContext) _EmailTemplate(ctx context.Context, sel ast.Selectio
if out.Values[i] == graphql.Null {
invalids++
}
case "subject":
out.Values[i] = ec._EmailTemplate_subject(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "created_at":
out.Values[i] = ec._EmailTemplate_created_at(ctx, field, obj)
case "updated_at":

View File

@ -4,6 +4,7 @@ package model
type AddEmailTemplateRequest struct {
EventName string `json:"event_name"`
Subject string `json:"subject"`
Template string `json:"template"`
}
@ -43,6 +44,7 @@ type EmailTemplate struct {
ID string `json:"id"`
EventName string `json:"event_name"`
Template string `json:"template"`
Subject string `json:"subject"`
CreatedAt *int64 `json:"created_at"`
UpdatedAt *int64 `json:"updated_at"`
}
@ -240,6 +242,7 @@ type UpdateEmailTemplateRequest struct {
ID string `json:"id"`
EventName *string `json:"event_name"`
Template *string `json:"template"`
Subject *string `json:"subject"`
}
type UpdateEnvInput struct {

View File

@ -189,6 +189,7 @@ type EmailTemplate {
id: ID!
event_name: String!
template: String!
subject: String!
created_at: Int64
updated_at: Int64
}
@ -404,6 +405,7 @@ input TestEndpointRequest {
input AddEmailTemplateRequest {
event_name: String!
subject: String!
template: String!
}
@ -411,6 +413,7 @@ input UpdateEmailTemplateRequest {
id: ID!
event_name: String
template: String
subject: String
}
input DeleteEmailTemplateRequest {

View File

@ -34,6 +34,10 @@ func AddEmailTemplateResolver(ctx context.Context, params model.AddEmailTemplate
return nil, fmt.Errorf("invalid event name %s", params.EventName)
}
if strings.TrimSpace(params.Subject) == "" {
return nil, fmt.Errorf("empty subject not allowed")
}
if strings.TrimSpace(params.Template) == "" {
return nil, fmt.Errorf("empty template not allowed")
}
@ -41,6 +45,7 @@ func AddEmailTemplateResolver(ctx context.Context, params model.AddEmailTemplate
_, err = db.Provider.AddEmailTemplate(ctx, models.EmailTemplate{
EventName: params.EventName,
Template: params.Template,
Subject: params.Subject,
})
if err != nil {
log.Debug("Failed to add email template: ", err)

View File

@ -51,6 +51,14 @@ func UpdateEmailTemplateResolver(ctx context.Context, params model.UpdateEmailTe
emailTemplateDetails.EventName = refs.StringValue(params.EventName)
}
if params.Subject != nil && emailTemplateDetails.Subject != refs.StringValue(params.Subject) {
if strings.TrimSpace(refs.StringValue(params.Subject)) == "" {
log.Debug("empty subject not allowed")
return nil, fmt.Errorf("empty subject not allowed")
}
emailTemplateDetails.Subject = refs.StringValue(params.Subject)
}
if params.Template != nil && emailTemplateDetails.Template != refs.StringValue(params.Template) {
if strings.TrimSpace(refs.StringValue(params.Template)) == "" {
log.Debug("empty template not allowed")

View File

@ -31,10 +31,21 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
assert.Nil(t, emailTemplate)
})
t.Run("should not add email template for empty template", func(t *testing.T) {
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
EventName: s.TestInfo.TestEmailTemplateEventTypes[0],
Template: " test ",
Subject: " ",
})
assert.Error(t, err)
assert.Nil(t, emailTemplate)
})
t.Run("should not add email template for empty template", func(t *testing.T) {
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
EventName: s.TestInfo.TestEmailTemplateEventTypes[0],
Template: " ",
Subject: "test",
})
assert.Error(t, err)
assert.Nil(t, emailTemplate)
@ -43,7 +54,8 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
t.Run("should add email template for "+eventType, func(t *testing.T) {
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
EventName: eventType,
Template: `Test email`,
Template: "Test email",
Subject: "Test email",
})
assert.NoError(t, err)
assert.NotNil(t, emailTemplate)
@ -52,6 +64,7 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
et, err := db.Provider.GetEmailTemplateByEventName(ctx, eventType)
assert.NoError(t, err)
assert.Equal(t, et.EventName, eventType)
assert.Equal(t, "Test email", et.Subject)
})
}
})

View File

@ -31,6 +31,7 @@ func updateEmailTemplateTest(t *testing.T, s TestSetup) {
res, err := resolvers.UpdateEmailTemplateResolver(ctx, model.UpdateEmailTemplateRequest{
ID: emailTemplate.ID,
Template: refs.NewStringRef("Updated test template"),
Subject: refs.NewStringRef("Updated subject"),
})
assert.NoError(t, err)
@ -42,5 +43,6 @@ func updateEmailTemplateTest(t *testing.T, s TestSetup) {
assert.NotNil(t, updatedEmailTemplate)
assert.Equal(t, emailTemplate.ID, updatedEmailTemplate.ID)
assert.Equal(t, updatedEmailTemplate.Template, "Updated test template")
assert.Equal(t, updatedEmailTemplate.Subject, "Updated subject")
})
}