Skip to content

Commit

Permalink
Merge pull request #71 from novuhq/69-cannot-set-layout-on-a-step-email
Browse files Browse the repository at this point in the history
feat: add layout to step message templates # 69
  • Loading branch information
toddb committed Sep 14, 2023
2 parents 6646584 + 88419a4 commit 1504222
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/Novu.Tests/IntegrationTests/MessageTemplateFactory.cs
Expand Up @@ -48,14 +48,15 @@ public static DigestMessageTemplate DigestMessageTemplate()
return new DigestMessageTemplate();
}

public static EmailMessageTemplate EmailMessageTemplate()
public static EmailMessageTemplate EmailMessageTemplate(string layoutId = null)
{
return new EmailMessageTemplate
{
// Type = StepTypeEnum.Email,
ContentType = MessageTemplateContentType.Editor,
SenderName = "Hello",
Subject = "{{mail.subject}}",
LayoutId = layoutId,
Content = new List<EmailBlock>
{
new()
Expand Down
4 changes: 2 additions & 2 deletions src/Novu.Tests/IntegrationTests/StepFactory.cs
Expand Up @@ -39,12 +39,12 @@ public static Step InApp(bool active = false)
};
}

public static Step Email(bool active = false)
public static Step Email(bool active = false, string layoutId = null)
{
return new Step
{
Name = $"Email ({StringGenerator.LoremIpsum(2)})",
Template = MessageTemplateFactory.EmailMessageTemplate(),
Template = MessageTemplateFactory.EmailMessageTemplate(layoutId),
Active = active,
};
}
Expand Down
18 changes: 18 additions & 0 deletions src/Novu.Tests/IntegrationTests/WorkflowTests.cs
Expand Up @@ -3,6 +3,8 @@
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using Novu.DTO;
using Novu.DTO.Layouts;
using Novu.DTO.Workflows;
using Novu.Extensions;
using Novu.Models.Workflows;
Expand Down Expand Up @@ -83,6 +85,22 @@ public async Task Should_Create_Steps(string test, Step[] steps, int stepsCount)
workflow.Triggers.Should().HaveCount(1);
}


[Fact]
public async Task Should_Create_Step_With_LayoutSet()
{
// we know there is always a default layout
var layout = (await Layout.Get())
.Data
.Single(x => x.IsDefault);

var steps = new[] { StepFactory.Email(layoutId: layout.Id) };
var workflow = await Make<Workflow>(steps: steps);
workflow.Should().NotBeNull();
workflow.Triggers.Should().HaveCount(1);
workflow.Steps.First().Template.LayoutId.Should().Be(layout.Id);
}

[Fact]
public async Task Should_Get_Workflows()
{
Expand Down
14 changes: 14 additions & 0 deletions src/Novu/Models/Workflows/Step/Message/BaseMessageTemplate.cs
Expand Up @@ -7,4 +7,18 @@ public abstract class BaseMessageTemplate
[JsonProperty("deleted")] public bool Deleted { get; set; }
[JsonProperty("variables")] public TemplateVariable[] Variables { get; set; }
[JsonProperty("actor")] public Actor Actor { get; set; }

/// <summary>
/// All messages CAN have a layout although the general approach is to only provide layouts for
/// an email as a wrapper around the content of the message
/// </summary>
[JsonProperty("layoutId")]
public string? LayoutId
{
get => _layoutId;
set => _layoutId = value;
}

// ReSharper disable once InconsistentNaming
[JsonProperty("_layoutId")] public string? _layoutId { get; set; }
}
28 changes: 19 additions & 9 deletions src/Novu/Models/Workflows/Step/Message/IMessageTemplate.cs
@@ -1,24 +1,34 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Novu.Models.Workflows.Step.Message;

public interface IMessageTemplate
{
[JsonProperty("type")]
[JsonConverter(typeof(StringEnumConverter))]
StepTypeEnum Type { get; set; }

/// <summary>
/// Polymorphic between string (code) and typed EmailBlock[]
/// </summary>
object Content { get; set; }

[JsonProperty("contentType")]
[JsonConverter(typeof(StringEnumConverter))]
MessageTemplateContentType ContentType { get; set; }

[JsonProperty("deleted")] bool Deleted { get; set; }
bool Deleted { get; set; }

TemplateVariable[] Variables { get; set; }

/// <summary>
/// Layout has three lifecycles (create, update and read) and the create and update use the non-underscore
/// whereas the read uses underscore.
///
/// The problems lies that these are nested objects that the API doesn't create as sub-resources to manage.
///
/// Therefore the implementation must deal with READ/WRITE in situ.
/// </summary>
/// <remarks>
/// The same problem for <see cref="FeedId"/>
/// </remarks>
public string? LayoutId { get; set; }
// ReSharper disable once InconsistentNaming
public string? _layoutId { get; set; }

[JsonProperty("variables")] TemplateVariable[] Variables { get; set; }
public Actor Actor { get; set; }
}

0 comments on commit 1504222

Please sign in to comment.