test(dolist): add some specs and remove unsupported email sent with attachments
This commit is contained in:
parent
3c3bc4a657
commit
2b9fe12079
2 changed files with 186 additions and 38 deletions
|
@ -61,61 +61,57 @@ module Dolist
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_email(mail)
|
def send_email(mail)
|
||||||
if mail.attachments.any? { !_1.inline? }
|
|
||||||
return send_email_with_attachment(mail)
|
|
||||||
end
|
|
||||||
|
|
||||||
body = { "TransactionalSending": prepare_mail_body(mail) }
|
body = { "TransactionalSending": prepare_mail_body(mail) }
|
||||||
|
|
||||||
url = format_url(EMAIL_SENDING_TRANSACTIONAL)
|
url = format_url(EMAIL_SENDING_TRANSACTIONAL)
|
||||||
post(url, body.to_json)
|
post(url, body.to_json)
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_email_with_attachment(mail)
|
# def send_email_with_attachment(mail)
|
||||||
uri = URI(format_url(EMAIL_SENDING_TRANSACTIONAL_ATTACHMENT))
|
# uri = URI(format_url(EMAIL_SENDING_TRANSACTIONAL_ATTACHMENT))
|
||||||
|
|
||||||
request = Net::HTTP::Post.new(uri)
|
# request = Net::HTTP::Post.new(uri)
|
||||||
|
|
||||||
default_headers.each do |key, value|
|
# default_headers.each do |key, value|
|
||||||
next if key.to_s == "Content-Type"
|
# next if key.to_s == "Content-Type"
|
||||||
request[key] = value
|
# request[key] = value
|
||||||
end
|
# end
|
||||||
|
|
||||||
boundary = "---011000010111000001101001" # any random string not present in the body
|
# boundary = "---011000010111000001101001" # any random string not present in the body
|
||||||
request.content_type = "multipart/form-data; boundary=#{boundary}"
|
# request.content_type = "multipart/form-data; boundary=#{boundary}"
|
||||||
|
|
||||||
body = "--#{boundary}\r\n"
|
# body = "--#{boundary}\r\n"
|
||||||
|
|
||||||
base64_files(mail.attachments).each do |file|
|
# base64_files(mail.attachments).each do |file|
|
||||||
body << "Content-Disposition: form-data; name=\"#{file.field_name}\"; filename=\"#{file.filename}\"\r\n"
|
# body << "Content-Disposition: form-data; name=\"#{file.field_name}\"; filename=\"#{file.filename}\"\r\n"
|
||||||
body << "Content-Type: #{file.mime_type}\r\n"
|
# body << "Content-Type: #{file.mime_type}\r\n"
|
||||||
body << "\r\n"
|
# body << "\r\n"
|
||||||
body << file.content
|
# body << file.content
|
||||||
body << "\r\n"
|
# body << "\r\n"
|
||||||
end
|
# end
|
||||||
|
|
||||||
body << "\r\n--#{boundary}\r\n"
|
# body << "\r\n--#{boundary}\r\n"
|
||||||
body << "Content-Disposition: form-data; name=\"TransactionalSending\"\r\n"
|
# body << "Content-Disposition: form-data; name=\"TransactionalSending\"\r\n"
|
||||||
body << "Content-Type: text/plain; charset=utf-8\r\n"
|
# body << "Content-Type: text/plain; charset=utf-8\r\n"
|
||||||
body << "\r\n"
|
# body << "\r\n"
|
||||||
body << prepare_mail_body(mail).to_jsv
|
# body << prepare_mail_body(mail).to_jsv
|
||||||
|
|
||||||
body << "\r\n--#{boundary}--\r\n"
|
# body << "\r\n--#{boundary}--\r\n"
|
||||||
body << "\r\n"
|
# body << "\r\n"
|
||||||
|
|
||||||
request.body = body
|
# request.body = body
|
||||||
|
|
||||||
http = Net::HTTP.new(uri.host, uri.port)
|
# http = Net::HTTP.new(uri.host, uri.port)
|
||||||
http.use_ssl = true
|
# http.use_ssl = true
|
||||||
|
|
||||||
response = http.request(request)
|
# response = http.request(request)
|
||||||
|
|
||||||
if response.body.empty?
|
# if response.body.empty?
|
||||||
fail "Dolist API returned an empty response"
|
# fail "Dolist API returned an empty response"
|
||||||
else
|
# else
|
||||||
JSON.parse(response.body)
|
# JSON.parse(response.body)
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
def sent_mails(email_address)
|
def sent_mails(email_address)
|
||||||
contact_id = fetch_contact_id(email_address)
|
contact_id = fetch_contact_id(email_address)
|
||||||
|
|
152
spec/lib/dolist/api_spec.rb
Normal file
152
spec/lib/dolist/api_spec.rb
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
describe Dolist::API do
|
||||||
|
let(:headers) { { "X-Rate-Limit-Remaining" => "15", "X-Rate-Limit-Reset" => (Time.current + 3600).to_i.to_s } }
|
||||||
|
|
||||||
|
let(:mail) do
|
||||||
|
Mail.new do
|
||||||
|
to 'test@example.com'
|
||||||
|
from 'sender@example.com'
|
||||||
|
subject 'Test'
|
||||||
|
body 'Test body'
|
||||||
|
header['X-Dolist-Message-Name'] = 'Test Message'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".save_rate_limit_headers" do
|
||||||
|
it "saves the rate limit headers" do
|
||||||
|
Dolist::API.save_rate_limit_headers(headers)
|
||||||
|
expect(Dolist::API.limit_remaining).to eq(15)
|
||||||
|
expect(Dolist::API.limit_reset_at).to be_within(1.second).of(Time.zone.at(headers["X-Rate-Limit-Reset"].to_i / 1_000))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".near_rate_limit?" do
|
||||||
|
context "when limit_remaining is nil" do
|
||||||
|
it "returns nil" do
|
||||||
|
Dolist::API.limit_remaining = nil
|
||||||
|
expect(Dolist::API.near_rate_limit?).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when limit_remaining is less than 20" do
|
||||||
|
it "returns true" do
|
||||||
|
Dolist::API.limit_remaining = 15
|
||||||
|
expect(Dolist::API.near_rate_limit?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when limit_remaining is 20 or more" do
|
||||||
|
it "returns false" do
|
||||||
|
Dolist::API.limit_remaining = 25
|
||||||
|
expect(Dolist::API.near_rate_limit?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".sendable?" do
|
||||||
|
context "when mail has no recipient" do
|
||||||
|
it "returns false" do
|
||||||
|
allow(mail).to receive(:to).and_return([])
|
||||||
|
expect(Dolist::API.sendable?(mail)).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when mail has bcc" do
|
||||||
|
it "returns false" do
|
||||||
|
allow(mail).to receive(:bcc).and_return(["bcc@example.com"])
|
||||||
|
expect(Dolist::API.sendable?(mail)).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when mail has attachments that are not inline" do
|
||||||
|
it "returns false" do
|
||||||
|
attachment = double("Attachment", inline?: false)
|
||||||
|
allow(mail).to receive(:attachments).and_return([attachment])
|
||||||
|
expect(Dolist::API.sendable?(mail)).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when mail is valid" do
|
||||||
|
it "returns true" do
|
||||||
|
expect(Dolist::API.sendable?(mail)).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#send_email" do
|
||||||
|
let(:api) { Dolist::API.new }
|
||||||
|
let(:url) { "https://api.dolist.com/email/send" }
|
||||||
|
let(:mail_body) do
|
||||||
|
{
|
||||||
|
"Type": "TransactionalService",
|
||||||
|
"Contact": {
|
||||||
|
"FieldList": [
|
||||||
|
{
|
||||||
|
"ID" => Dolist::API::EMAIL_KEY,
|
||||||
|
"Value" => mail.to.first
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Message": {
|
||||||
|
"Name": mail['X-Dolist-Message-Name'].value,
|
||||||
|
"Subject": mail.subject,
|
||||||
|
"SenderID": api.send(:sender_id, mail.from_address.domain),
|
||||||
|
"ForceHttp": false,
|
||||||
|
"Format": "html",
|
||||||
|
"DisableOpenTracking": true,
|
||||||
|
"IsTrackingValidated": true
|
||||||
|
},
|
||||||
|
"MessageContent": {
|
||||||
|
"SourceCode": mail.decoded,
|
||||||
|
"EncodingType": "UTF8",
|
||||||
|
"EnableTrackingDetection": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:expected_body) { { "TransactionalSending": mail_body }.to_json }
|
||||||
|
|
||||||
|
it "sends an email using the API" do
|
||||||
|
stub_request(:post, "https://apiv9.dolist.net/v1/email/sendings/transactional?AccountID=#{ENV["DOLIST_ACCOUNT_ID"]}")
|
||||||
|
.with(body: expected_body)
|
||||||
|
.to_return(body: { "Result" => "success" }.to_json, headers: { "X-Rate-Limit-Remaining" => "15", "X-Rate-Limit-Reset" => "1234" })
|
||||||
|
|
||||||
|
result = api.send_email(mail)
|
||||||
|
expect(result).to eq({ "Result" => "success" })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#sent_mails" do
|
||||||
|
let(:api) { Dolist::API.new }
|
||||||
|
let(:email_address) { "test@example.com" }
|
||||||
|
let(:contact_id) { "12345" }
|
||||||
|
let(:dolist_messages) { [{ "SendingName" => "Test Message", "SendDate" => Time.zone.now.to_s, "Status" => "Sent", "IsDelivered" => true }] }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(api).to receive(:fetch_contact_id).with(email_address).and_return(contact_id)
|
||||||
|
allow(api).to receive(:fetch_dolist_messages).with(contact_id).and_return(dolist_messages)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns a list of sent mails" do
|
||||||
|
sent_mails = api.sent_mails(email_address)
|
||||||
|
expect(sent_mails).not_to be_empty
|
||||||
|
expect(sent_mails.first.subject).to eq("Test Message")
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when contact_id is nil" do
|
||||||
|
it "returns an empty list" do
|
||||||
|
allow(api).to receive(:fetch_contact_id).with(email_address).and_return(nil)
|
||||||
|
expect(api.sent_mails(email_address)).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when an error occurs" do
|
||||||
|
it "returns an empty list and logs the error" do
|
||||||
|
allow(api).to receive(:fetch_contact_id).and_raise(StandardError.new("Test Error"))
|
||||||
|
expect(Rails.logger).to receive(:error).with("Test Error")
|
||||||
|
expect(api.sent_mails(email_address)).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue