Skip to content

Commit

Permalink
Add format emails bot
Browse files Browse the repository at this point in the history
  • Loading branch information
FelipeGuzmanSierra committed May 10, 2024
1 parent 77412a2 commit 029944a
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 0 deletions.
90 changes: 90 additions & 0 deletions lib/v2/bot/format_emails.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# frozen_string_literal: true

require_relative "./base"
require_relative "../read/postgres"
require_relative "../write/postgres"

module Bot
##
# The Bot::FormatEmails class serves as a bot implementation to read emails from a
# PostgresDB database, format them with a specific template, and write them on a PostgresDB
# table with a specific format.
#
# <br>
# <b>Example</b>
#
# options = {
# read_options: {
# connection: {
# host: "localhost",
# port: 5432,
# dbname: "bas",
# user: "postgres",
# password: "postgres"
# },
# db_table: "use_cases",
# bot_name: "FetchEmailsFromImap"
# },
# process_options: {
# template: "emails template message"
# },
# write_options: {
# connection: {
# host: "localhost",
# port: 5432,
# dbname: "bas",
# user: "postgres",
# password: "postgres"
# },
# db_table: "use_cases",
# bot_name: "FormatEmails"
# }
# }
#
# bot = Bot::FormatEmails.new(options)
# bot.execute
#
class FormatEmails < Bot::Base
EMAIL_ATTRIBUTES = %w[subject sender date].freeze

# read function to execute the PostgresDB Read component
#
def read
reader = Read::Postgres.new(read_options)

reader.execute
end

# Process function to format the notification using a template
#
def process(read_response)
return { success: { notification: "" } } if read_response.data.nil? || read_response.data["emails"] == []

emails_list = read_response.data["emails"]

notification = emails_list.reduce("") do |payload, email|
"#{payload} #{build_template(EMAIL_ATTRIBUTES, email)} \n"
end

{ success: { notification: } }
end

# Write function to execute the PostgresDB write component
#
def write(process_response)
write = Write::Postgres.new(write_options, process_response)

write.execute
end

private

def build_template(attributes, instance)
template = process_options[:template]

attributes.reduce(template) do |formated_template, attribute|
formated_template.gsub("<#{attribute}>", instance[attribute].to_s)
end
end
end
end
122 changes: 122 additions & 0 deletions spec/v2/bot/format_emails_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# frozen_string_literal: true

require "v2/bot/format_emails"

RSpec.describe Bot::FormatEmails do
before do
connection = {
host: "localhost",
port: 5432,
dbname: "bas",
user: "postgres",
password: "postgres"
}

config = {
read_options: {
connection:,
db_table: "use_cases",
bot_name: "FetchEmailsFromImap"
},
process_options: {
template: "The <sender> has requested support the <date>"
},
write_options: {
connection:,
db_table: "use_cases",
bot_name: "FormatEmails"
}
}

@bot = described_class.new(config)
end

describe "attributes and arguments" do
it { expect(described_class).to respond_to(:new).with(1).arguments }

it { expect(@bot).to respond_to(:execute).with(0).arguments }
it { expect(@bot).to respond_to(:read).with(0).arguments }
it { expect(@bot).to respond_to(:process).with(1).arguments }
it { expect(@bot).to respond_to(:write).with(1).arguments }

it { expect(@bot).to respond_to(:read_options) }
it { expect(@bot).to respond_to(:process_options) }
it { expect(@bot).to respond_to(:write_options) }
end

describe ".read" do
let(:pg_conn) { instance_double(PG::Connection) }
let(:emails_results) do
"{\"emails\": [{\"date\": \"Thu, 09 May\", \"sender\": \"user@mail.com\"}]}"
end

let(:formatted_emails) do
{ "emails" => [{ "date" => "Thu, 09 May", "sender" => "user@mail.com" }] }
end

before do
@pg_result = double

allow(PG::Connection).to receive(:new).and_return(pg_conn)
allow(pg_conn).to receive(:exec_params).and_return(@pg_result)
allow(@pg_result).to receive(:values).and_return([[emails_results]])
end

it "read the notification from the postgres database" do
read = @bot.read

expect(read).to be_a Read::Types::Response
expect(read.data).to be_a Hash
expect(read.data).to_not be_nil
expect(read.data).to eq(formatted_emails)
end
end

describe ".process" do
let(:emails) { [{ "date" => "Thu, 09 May", "sender" => "user@mail.com" }] }

let(:formatted_emails) do
" The user@mail.com has requested support the Thu, 09 May \n"
end

it "returns an empty success hash when the birthdays list is empty" do
read_response = Read::Types::Response.new({ "emails" => [] })

expect(@bot.process(read_response)).to eq({ success: { notification: "" } })
end

it "returns an empty success hash when the record was not found" do
read_response = Read::Types::Response.new(nil)

expect(@bot.process(read_response)).to eq({ success: { notification: "" } })
end

it "returns a success hash with the list of formatted birthdays" do
read_response = Read::Types::Response.new({ "emails" => emails })
processed = @bot.process(read_response)

expect(processed).to eq({ success: { notification: formatted_emails } })
end
end

describe ".write" do
let(:pg_conn) { instance_double(PG::Connection) }

let(:formatted_emails) do
" The user@mail.com has requested support the Thu, 09 May \n"
end

before do
pg_result = instance_double(PG::Result)

allow(PG::Connection).to receive(:new).and_return(pg_conn)
allow(pg_conn).to receive(:exec_params).and_return(pg_result)
end

it "save the process success response in a postgres table" do
process_response = { success: { notification: formatted_emails } }

expect(@bot.write(process_response)).to_not be_nil
end
end
end

0 comments on commit 029944a

Please sign in to comment.