Skip to content

Commit

Permalink
Add custom templates option (#19)
Browse files Browse the repository at this point in the history
* Add custom template functionality for formatter

* Update and add test for the formatter custom template
  • Loading branch information
FelipeGuzmanSierra authored Feb 7, 2024
1 parent 2e14bed commit d910690
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 33 deletions.
2 changes: 2 additions & 0 deletions lib/bns/domain/birthday.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module Domain
class Birthday
attr_reader :individual_name, :birth_date

ATTRIBUTES = %w[individual_name birth_date].freeze

# Initializes a Domain::Birthday instance with the specified individual name, and date of birth.
#
# <br>
Expand Down
2 changes: 2 additions & 0 deletions lib/bns/domain/pto.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ module Domain
class Pto
attr_reader :individual_name, :start_date, :end_date

ATTRIBUTES = %w[individual_name start_date end_date].freeze

# Initializes a Domain::Pto instance with the specified individual name, start date, and end date.
#
# <br>
Expand Down
23 changes: 22 additions & 1 deletion lib/bns/formatter/base.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# frozen_string_literal: true

require_relative "../domain/exceptions/function_not_implemented"
require "erb"

module Formatter
##
# The Formatter::Base module serves as the foundation for implementing specific data presentation logic
# within the Formatter module. Defines essential methods, that provide a blueprint for creating custom
# formatters tailored to different use cases.
#
module Base
class Base
# A method meant to give an specified format depending on the implementation to the data coming from an
# implementation of the Mapper::Base interface.
# Must be overridden by subclasses, with specific logic based on the use case.
Expand All @@ -22,8 +23,28 @@ module Base
#
# <b>returns</b> <tt>String</tt> Formatted payload suitable for a Dispatcher::Base implementation.
#
attr_reader :template

def initialize(config = {})
@template = config[:template]
end

def format(_domain_data)
raise Domain::Exceptions::FunctionNotImplemented
end

protected

def build_template(attributes, instance)
formated_template = format_template(attributes, instance)

"#{ERB.new(formated_template).result(binding)}\n"
end

def format_template(attributes, _instance)
attributes.reduce(template) do |formated_template, attribute|
formated_template.gsub(attribute, "<%= instance.#{attribute} %>")
end
end
end
end
13 changes: 3 additions & 10 deletions lib/bns/formatter/discord/birthday.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ module Discord
##
# This class implementats the methods of the Formatter::Base module, specifically designed for formatting birthday
# data in a way suitable for Discord messages.
class Birthday
include Base

class Birthday < Base
# Implements the logic for building a formatted payload with the given template for birthdays.
#
# <br>
Expand All @@ -29,14 +27,9 @@ def format(birthdays_list)
brithday.is_a?(Domain::Birthday)
end

template = "NAME, Wishing you a very happy birthday! Enjoy your special day! :birthday: :gift:"
payload = ""

birthdays_list.each do |birthday|
payload += "#{template.gsub("NAME", birthday.individual_name)}\n"
birthdays_list.reduce("") do |payload, birthday|
payload + build_template(Domain::Birthday::ATTRIBUTES, birthday)
end

payload
end
end
end
Expand Down
14 changes: 4 additions & 10 deletions lib/bns/formatter/discord/pto.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ module Discord
##
# This class is an implementation of the Formatter::Base interface, specifically designed for formatting PTO
# data in a way suitable for Discord messages.
class Pto
include Base

class Pto < Base
# Implements the logic for building a formatted payload with the given template for PTO's.
#
# <br>
Expand All @@ -23,17 +21,13 @@ class Pto
# <br>
# <b>returns</b> <tt>String</tt> payload, formatted payload suitable for a Discord message.
#

def format(ptos_list)
raise Formatter::Discord::Exceptions::InvalidData unless ptos_list.all? { |pto| pto.is_a?(Domain::Pto) }

template = ":beach: NAME is on PTO"
payload = ""

ptos_list.each do |pto|
payload += "#{template.gsub("NAME", pto.individual_name)} #{build_pto_message(pto)}\n"
ptos_list.reduce("") do |payload, pto|
payload + build_template(Domain::Pto::ATTRIBUTES, pto)
end

payload
end

private
Expand Down
4 changes: 2 additions & 2 deletions lib/bns/use_cases/use_cases.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ module UseCases
def self.notify_birthday_from_notion_to_discord(options)
fetcher = Fetcher::Notion::Birthday.new(options[:fetch_options])
mapper = Mapper::Notion::Birthday.new
formatter = Formatter::Discord::Birthday.new
formatter = Formatter::Discord::Birthday.new(options[:format_options])
dispatcher = Dispatcher::Discord::Implementation.new(options[:dispatch_options])
use_case_cofig = UseCases::Types::Config.new(fetcher, mapper, formatter, dispatcher)

Expand Down Expand Up @@ -141,7 +141,7 @@ def self.notify_birthday_from_notion_to_discord(options)
def self.notify_pto_from_notion_to_discord(options)
fetcher = Fetcher::Notion::Pto.new(options[:fetch_options])
mapper = Mapper::Notion::Pto.new
formatter = Formatter::Discord::Pto.new
formatter = Formatter::Discord::Pto.new(options[:format_options])
dispatcher = Dispatcher::Discord::Implementation.new(options[:dispatch_options])
use_case_cofig = UseCases::Types::Config.new(fetcher, mapper, formatter, dispatcher)

Expand Down
10 changes: 6 additions & 4 deletions spec/bns/formatter/base_spec.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# frozen_string_literal: true

RSpec.describe Formatter::Base do
describe ".format" do
let(:testing_class) { Class.new { include Formatter::Base } }
before do
config = {}
@formatter = described_class.new(config)
end

describe ".format" do
it "provides no implementation for the method" do
instace = testing_class.new
data = []
expect { instace.format(data) }.to raise_exception(Domain::Exceptions::FunctionNotImplemented)
expect { @formatter.format(data) }.to raise_exception(Domain::Exceptions::FunctionNotImplemented)
end
end
end
11 changes: 8 additions & 3 deletions spec/bns/formatter/discord/birthday_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
it { expect(@formatter).to respond_to(:format).with(1).arguments }
end

describe ".format" do
describe ".format with a custom template" do
before do
config = { template: "individual_name, Wishing you a very happy birthday! :birthday: :gift:" }
@formatter = described_class.new(config)
end

it "format the given data into a specific message" do
formatted_message = @formatter.format(@data)
expectation = "Jane Doe, Wishing you a very happy birthday! Enjoy your special day! :birthday: :gift:\n" \
"John Doe, Wishing you a very happy birthday! Enjoy your special day! :birthday: :gift:\n"
expectation = "Jane Doe, Wishing you a very happy birthday! :birthday: :gift:\n" \
"John Doe, Wishing you a very happy birthday! :birthday: :gift:\n"

expect(formatted_message).to be_an_instance_of(String)
expect(formatted_message).to eq(expectation)
Expand Down
11 changes: 8 additions & 3 deletions spec/bns/formatter/discord/pto_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@
Domain::Pto.new("Time PTO", "2024-01-20T00:00:00.000-05:00", "2024-01-20T15:00:00.000-05:00"),
Domain::Pto.new("Day PTO", "2024-01-11", "")
]

@formatter = described_class.new
end

describe "attributes and arguments" do
before { @formatter = described_class.new }

it { expect(described_class).to respond_to(:new).with(0).arguments }
it { expect(@formatter).to respond_to(:format).with(1).arguments }
end

describe ".format" do
describe ".format with custom template" do
before do
config = { template: ":beach: individual_name is on PTO <%= build_pto_message(instance) %>" }
@formatter = described_class.new(config)
end

it "format the given data into a specific message" do
formatted_message = @formatter.format(@data)
expectation = ":beach: Range PTO is on PTO all day\n" \
Expand Down

0 comments on commit d910690

Please sign in to comment.