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 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"` 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"` 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"` Template string `gorm:"type:text" json:"template" bson:"template" cql:"template"`
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_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{ return &model.EmailTemplate{
ID: id, ID: id,
EventName: e.EventName, EventName: e.EventName,
Subject: e.Subject,
Template: e.Template, Template: e.Template,
CreatedAt: refs.NewInt64Ref(e.CreatedAt), CreatedAt: refs.NewInt64Ref(e.CreatedAt),
UpdatedAt: refs.NewInt64Ref(e.UpdatedAt), 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) 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() err := p.db.Query(insertQuery).Exec()
if err != nil { if err != nil {
return nil, err return nil, err
@ -103,14 +103,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
// there is no offset in cassandra // there is no offset in cassandra
// so we fetch till limit + offset // so we fetch till limit + offset
// and return the results from offset to limit // 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() scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0) counter := int64(0)
for scanner.Next() { for scanner.Next() {
if counter >= pagination.Offset { if counter >= pagination.Offset {
var emailTemplate models.EmailTemplate 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 { if err != nil {
return nil, err return nil, err
} }
@ -128,8 +128,8 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
// GetEmailTemplateByID to get EmailTemplate by id // GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate 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) 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.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt) err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -139,8 +139,8 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
// GetEmailTemplateByEventName to get EmailTemplate by event_name // GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate 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) 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.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt) err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -214,6 +214,12 @@ func NewProvider() (*provider, error) {
if err != nil { if err != nil {
return nil, err 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{ return &provider{
db: session, db: session,

View File

@ -56,6 +56,7 @@ type ComplexityRoot struct {
CreatedAt func(childComplexity int) int CreatedAt func(childComplexity int) int
EventName func(childComplexity int) int EventName func(childComplexity int) int
ID func(childComplexity int) int ID func(childComplexity int) int
Subject func(childComplexity int) int
Template func(childComplexity int) int Template func(childComplexity int) int
UpdatedAt 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 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": case "EmailTemplate.template":
if e.complexity.EmailTemplate.Template == nil { if e.complexity.EmailTemplate.Template == nil {
break break
@ -1978,6 +1986,7 @@ type EmailTemplate {
id: ID! id: ID!
event_name: String! event_name: String!
template: String! template: String!
subject: String!
created_at: Int64 created_at: Int64
updated_at: Int64 updated_at: Int64
} }
@ -2193,6 +2202,7 @@ input TestEndpointRequest {
input AddEmailTemplateRequest { input AddEmailTemplateRequest {
event_name: String! event_name: String!
subject: String!
template: String! template: String!
} }
@ -2200,6 +2210,7 @@ input UpdateEmailTemplateRequest {
id: ID! id: ID!
event_name: String event_name: String
template: String template: String
subject: String
} }
input DeleteEmailTemplateRequest { input DeleteEmailTemplateRequest {
@ -3108,6 +3119,41 @@ func (ec *executionContext) _EmailTemplate_template(ctx context.Context, field g
return ec.marshalNString2string(ctx, field.Selections, res) 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) { func (ec *executionContext) _EmailTemplate_created_at(ctx context.Context, field graphql.CollectedField, obj *model.EmailTemplate) (ret graphql.Marshaler) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -10087,6 +10133,14 @@ func (ec *executionContext) unmarshalInputAddEmailTemplateRequest(ctx context.Co
if err != nil { if err != nil {
return it, err 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": case "template":
var err error var err error
@ -10866,6 +10920,14 @@ func (ec *executionContext) unmarshalInputUpdateEmailTemplateRequest(ctx context
if err != nil { if err != nil {
return it, err 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 { if out.Values[i] == graphql.Null {
invalids++ invalids++
} }
case "subject":
out.Values[i] = ec._EmailTemplate_subject(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "created_at": case "created_at":
out.Values[i] = ec._EmailTemplate_created_at(ctx, field, obj) out.Values[i] = ec._EmailTemplate_created_at(ctx, field, obj)
case "updated_at": case "updated_at":

View File

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

View File

@ -189,6 +189,7 @@ type EmailTemplate {
id: ID! id: ID!
event_name: String! event_name: String!
template: String! template: String!
subject: String!
created_at: Int64 created_at: Int64
updated_at: Int64 updated_at: Int64
} }
@ -404,6 +405,7 @@ input TestEndpointRequest {
input AddEmailTemplateRequest { input AddEmailTemplateRequest {
event_name: String! event_name: String!
subject: String!
template: String! template: String!
} }
@ -411,6 +413,7 @@ input UpdateEmailTemplateRequest {
id: ID! id: ID!
event_name: String event_name: String
template: String template: String
subject: String
} }
input DeleteEmailTemplateRequest { 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) 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) == "" { if strings.TrimSpace(params.Template) == "" {
return nil, fmt.Errorf("empty template not allowed") 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{ _, err = db.Provider.AddEmailTemplate(ctx, models.EmailTemplate{
EventName: params.EventName, EventName: params.EventName,
Template: params.Template, Template: params.Template,
Subject: params.Subject,
}) })
if err != nil { if err != nil {
log.Debug("Failed to add email template: ", err) 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) 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 params.Template != nil && emailTemplateDetails.Template != refs.StringValue(params.Template) {
if strings.TrimSpace(refs.StringValue(params.Template)) == "" { if strings.TrimSpace(refs.StringValue(params.Template)) == "" {
log.Debug("empty template not allowed") log.Debug("empty template not allowed")

View File

@ -31,10 +31,21 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
assert.Nil(t, emailTemplate) 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) { t.Run("should not add email template for empty template", func(t *testing.T) {
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{ emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
EventName: s.TestInfo.TestEmailTemplateEventTypes[0], EventName: s.TestInfo.TestEmailTemplateEventTypes[0],
Template: " ", Template: " ",
Subject: "test",
}) })
assert.Error(t, err) assert.Error(t, err)
assert.Nil(t, emailTemplate) 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) { t.Run("should add email template for "+eventType, func(t *testing.T) {
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{ emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
EventName: eventType, EventName: eventType,
Template: `Test email`, Template: "Test email",
Subject: "Test email",
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, emailTemplate) assert.NotNil(t, emailTemplate)
@ -52,6 +64,7 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
et, err := db.Provider.GetEmailTemplateByEventName(ctx, eventType) et, err := db.Provider.GetEmailTemplateByEventName(ctx, eventType)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, et.EventName, eventType) 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{ res, err := resolvers.UpdateEmailTemplateResolver(ctx, model.UpdateEmailTemplateRequest{
ID: emailTemplate.ID, ID: emailTemplate.ID,
Template: refs.NewStringRef("Updated test template"), Template: refs.NewStringRef("Updated test template"),
Subject: refs.NewStringRef("Updated subject"),
}) })
assert.NoError(t, err) assert.NoError(t, err)
@ -42,5 +43,6 @@ func updateEmailTemplateTest(t *testing.T, s TestSetup) {
assert.NotNil(t, updatedEmailTemplate) assert.NotNil(t, updatedEmailTemplate)
assert.Equal(t, emailTemplate.ID, updatedEmailTemplate.ID) assert.Equal(t, emailTemplate.ID, updatedEmailTemplate.ID)
assert.Equal(t, updatedEmailTemplate.Template, "Updated test template") assert.Equal(t, updatedEmailTemplate.Template, "Updated test template")
assert.Equal(t, updatedEmailTemplate.Subject, "Updated subject")
}) })
} }