howitzer 1.1.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +32 -0
- data/.travis.yml +1 -4
- data/.yardopts +1 -2
- data/CHANGELOG.md +28 -1
- data/Gemfile +6 -0
- data/LICENSE +1 -1
- data/README.md +55 -85
- data/Rakefile +7 -7
- data/bin/howitzer +56 -31
- data/features/cli_new.feature +162 -79
- data/features/cli_update.feature +114 -21
- data/features/step_definitions/common_steps.rb +29 -9
- data/features/support/env.rb +1 -1
- data/features/support/transformers.rb +2 -2
- data/generators/base_generator.rb +121 -49
- data/generators/config/config_generator.rb +8 -5
- data/generators/config/templates/boot.rb +14 -0
- data/generators/config/templates/capybara.rb +156 -0
- data/generators/config/templates/custom.yml +2 -3
- data/generators/config/templates/default.yml +50 -82
- data/generators/cucumber/cucumber_generator.rb +9 -9
- data/generators/cucumber/templates/common_steps.rb +4 -4
- data/generators/cucumber/templates/cucumber.rake +63 -54
- data/generators/cucumber/templates/env.rb +24 -23
- data/generators/cucumber/templates/transformers.rb +23 -15
- data/generators/emails/emails_generator.rb +4 -2
- data/generators/emails/templates/example_email.rb +4 -4
- data/generators/prerequisites/prerequisites_generator.rb +24 -0
- data/generators/prerequisites/templates/base.rb +22 -0
- data/generators/prerequisites/templates/factory_girl.rb +30 -0
- data/generators/prerequisites/templates/user.rb +7 -0
- data/generators/prerequisites/templates/users.rb +12 -0
- data/generators/root/root_generator.rb +11 -7
- data/generators/root/templates/.rubocop.yml +32 -0
- data/generators/root/templates/Gemfile.erb +27 -0
- data/generators/root/templates/Rakefile +6 -8
- data/generators/rspec/rspec_generator.rb +7 -7
- data/generators/rspec/templates/example_spec.rb +1 -1
- data/generators/rspec/templates/rspec.rake +48 -29
- data/generators/rspec/templates/spec_helper.rb +33 -32
- data/generators/tasks/tasks_generator.rb +4 -2
- data/generators/tasks/templates/common.rake +1 -16
- data/generators/turnip/templates/.rspec +1 -0
- data/generators/turnip/templates/common_steps.rb +25 -0
- data/generators/turnip/templates/example.feature +8 -0
- data/generators/turnip/templates/spec_helper.rb +56 -0
- data/generators/turnip/templates/turnip.rake +61 -0
- data/generators/turnip/templates/turnip_helper.rb +6 -0
- data/generators/turnip/turnip_generator.rb +26 -0
- data/generators/web/templates/example_page.rb +15 -0
- data/generators/web/templates/menu_section.rb +13 -0
- data/generators/web/web_generator.rb +22 -0
- data/howitzer.gemspec +14 -21
- data/lib/howitzer.rb +47 -7
- data/lib/howitzer/cache.rb +70 -0
- data/lib/howitzer/capybara_helpers.rb +194 -0
- data/lib/howitzer/email.rb +96 -104
- data/lib/howitzer/exceptions.rb +10 -6
- data/lib/howitzer/log.rb +120 -0
- data/lib/howitzer/mail_adapters.rb +7 -0
- data/lib/howitzer/mail_adapters/abstract.rb +84 -0
- data/lib/howitzer/mail_adapters/mailgun.rb +115 -0
- data/lib/howitzer/mailgun_api.rb +9 -0
- data/lib/howitzer/mailgun_api/client.rb +79 -0
- data/lib/howitzer/mailgun_api/connector.rb +37 -0
- data/lib/howitzer/mailgun_api/response.rb +28 -0
- data/lib/howitzer/tasks/framework.rake +2 -2
- data/lib/howitzer/utils.rb +7 -1
- data/lib/howitzer/utils/string_extensions.rb +66 -0
- data/lib/howitzer/version.rb +2 -1
- data/lib/howitzer/web.rb +11 -0
- data/lib/howitzer/web/base_section.rb +27 -0
- data/lib/howitzer/web/blank_page.rb +12 -0
- data/lib/howitzer/web/capybara_methods_proxy.rb +29 -0
- data/lib/howitzer/web/element_dsl.rb +109 -0
- data/lib/howitzer/web/iframe_dsl.rb +93 -0
- data/lib/howitzer/web/page.rb +173 -0
- data/lib/howitzer/web/page_dsl.rb +64 -0
- data/lib/howitzer/web/page_validator.rb +118 -0
- data/lib/howitzer/web/section.rb +27 -0
- data/lib/howitzer/web/section_dsl.rb +154 -0
- data/spec/config/custom.yml +10 -1
- data/spec/spec_helper.rb +37 -19
- data/spec/support/generator_helper.rb +12 -11
- data/spec/support/logger_helper.rb +10 -9
- data/spec/support/mailgun_unit_client.rb +52 -44
- data/spec/support/shared_examples/capybara_context_holder.rb +33 -0
- data/spec/support/shared_examples/capybara_methods_proxy.rb +94 -0
- data/spec/support/shared_examples/dynamic_section_methods.rb +35 -0
- data/spec/support/shared_examples/element_dsl.rb +119 -0
- data/spec/unit/generators/base_generator_spec.rb +64 -33
- data/spec/unit/generators/config_generator_spec.rb +11 -7
- data/spec/unit/generators/cucumber_generator_spec.rb +26 -17
- data/spec/unit/generators/emails_generator_spec.rb +10 -6
- data/spec/unit/generators/prerequisites_generator_spec.rb +53 -0
- data/spec/unit/generators/root_generator_spec.rb +50 -13
- data/spec/unit/generators/rspec_generator_spec.rb +9 -9
- data/spec/unit/generators/tasks_generator_spec.rb +6 -6
- data/spec/unit/generators/turnip_generator_spec.rb +52 -0
- data/spec/unit/generators/web_generator_spec.rb +52 -0
- data/spec/unit/lib/cache_spec.rb +85 -0
- data/spec/unit/lib/capybara_helpers_spec.rb +696 -0
- data/spec/unit/lib/email_spec.rb +104 -91
- data/spec/unit/lib/howitzer.rb +31 -0
- data/spec/unit/lib/init_spec.rb +0 -1
- data/spec/unit/lib/log_spec.rb +122 -0
- data/spec/unit/lib/mail_adapters/abstract_spec.rb +62 -0
- data/spec/unit/lib/mail_adapters/mailgun_spec.rb +163 -0
- data/spec/unit/lib/mailgun_api/client_spec.rb +58 -0
- data/spec/unit/lib/mailgun_api/connector_spec.rb +54 -0
- data/spec/unit/lib/mailgun_api/response_spec.rb +28 -0
- data/spec/unit/lib/utils/string_extensions_spec.rb +77 -0
- data/spec/unit/lib/web/base_section_spec.rb +41 -0
- data/spec/unit/lib/web/element_dsl_spec.rb +17 -0
- data/spec/unit/lib/web/iframe_dsl_spec.rb +99 -0
- data/spec/unit/lib/web/page_dsl_spec.rb +52 -0
- data/spec/unit/lib/web/page_spec.rb +304 -0
- data/spec/unit/lib/web/page_validator_spec.rb +218 -0
- data/spec/unit/lib/web/section_dsl_spec.rb +165 -0
- data/spec/unit/lib/web/section_spec.rb +61 -0
- data/spec/unit/version_spec.rb +1 -1
- metadata +116 -203
- data/GETTING_STARTED.md +0 -774
- data/generators/cucumber/templates/cucumber.yml +0 -10
- data/generators/pages/pages_generator.rb +0 -21
- data/generators/pages/templates/example_menu.rb +0 -15
- data/generators/pages/templates/example_page.rb +0 -15
- data/generators/root/templates/Gemfile +0 -7
- data/generators/root/templates/boot.rb +0 -10
- data/lib/howitzer/blank_page.rb +0 -6
- data/lib/howitzer/capybara/dsl_ex.rb +0 -15
- data/lib/howitzer/capybara/settings.rb +0 -343
- data/lib/howitzer/helpers.rb +0 -230
- data/lib/howitzer/init.rb +0 -1
- data/lib/howitzer/mailgun/client.rb +0 -65
- data/lib/howitzer/mailgun/connector.rb +0 -34
- data/lib/howitzer/mailgun/response.rb +0 -28
- data/lib/howitzer/patches/rawler_patched.rb +0 -86
- data/lib/howitzer/settings.rb +0 -27
- data/lib/howitzer/utils/data_generator/data_storage.rb +0 -88
- data/lib/howitzer/utils/data_generator/gen.rb +0 -135
- data/lib/howitzer/utils/locator_store.rb +0 -217
- data/lib/howitzer/utils/log.rb +0 -139
- data/lib/howitzer/utils/page_validator.rb +0 -133
- data/lib/howitzer/vendor/firebug-1.12.1-fx.xpi +0 -0
- data/lib/howitzer/vendor/firepath-0.9.7-fx.xpi +0 -0
- data/lib/howitzer/web_page.rb +0 -253
- data/spec/active_resource.rb +0 -0
- data/spec/config/default.yml +0 -26
- data/spec/support/boot_helper.rb +0 -15
- data/spec/unit/generators/pages_generator_spec.rb +0 -33
- data/spec/unit/lib/capybara/dsl_ex_spec.rb +0 -60
- data/spec/unit/lib/capybara/settings_spec.rb +0 -441
- data/spec/unit/lib/helpers_spec.rb +0 -1129
- data/spec/unit/lib/mailgun/client_spec.rb +0 -36
- data/spec/unit/lib/mailgun/connector_spec.rb +0 -70
- data/spec/unit/lib/mailgun/response_spec.rb +0 -28
- data/spec/unit/lib/settings_spec.rb +0 -17
- data/spec/unit/lib/utils/data_generator/data_storage_spec.rb +0 -80
- data/spec/unit/lib/utils/data_generator/gen_spec.rb +0 -90
- data/spec/unit/lib/utils/locator_store_spec.rb +0 -157
- data/spec/unit/lib/utils/log_spec.rb +0 -107
- data/spec/unit/lib/utils/page_validator_spec.rb +0 -265
- data/spec/unit/lib/web_page_spec.rb +0 -346
data/lib/howitzer/log.rb
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'active_support/core_ext/module'
|
|
4
|
+
|
|
5
|
+
module Howitzer
|
|
6
|
+
# This class represents logger
|
|
7
|
+
class Log
|
|
8
|
+
include Singleton
|
|
9
|
+
include Log4r
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
# Delegates all public instance methods to the class
|
|
13
|
+
delegate :debug, :info, :warn, :fatal, :error, :print_feature_name,
|
|
14
|
+
:settings_as_formatted_text, :print_scenario_name, to: :instance
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Outputs debug message if Howitzer.debug_mode == true
|
|
18
|
+
# @param msg [String] a message
|
|
19
|
+
|
|
20
|
+
def debug(msg)
|
|
21
|
+
@logger.debug(msg)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Outputs info message
|
|
25
|
+
# @param msg [String] a message
|
|
26
|
+
|
|
27
|
+
def info(msg)
|
|
28
|
+
@logger.info(msg)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Outputs warn message
|
|
32
|
+
# @param msg [String] a message
|
|
33
|
+
|
|
34
|
+
def warn(msg)
|
|
35
|
+
@logger.warn(msg)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Outputs error message
|
|
39
|
+
# @param msg [String] a message
|
|
40
|
+
|
|
41
|
+
def error(msg)
|
|
42
|
+
@logger.error(msg)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Outputs fatal message
|
|
46
|
+
# @param msg [String] a message
|
|
47
|
+
|
|
48
|
+
def fatal(msg)
|
|
49
|
+
@logger.fatal(msg)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Outputs a feature name into the log with INFO severity
|
|
53
|
+
# @param text [String] a feature name
|
|
54
|
+
|
|
55
|
+
def print_feature_name(text)
|
|
56
|
+
log_without_formatting { info "*** Feature: #{text.upcase} ***" }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Outputs formatted howitzer settings
|
|
60
|
+
|
|
61
|
+
def settings_as_formatted_text
|
|
62
|
+
log_without_formatting { info ::SexySettings::Base.instance.as_formatted_text }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Outputs a scenario name into log with INFO severity
|
|
66
|
+
# @param text [String] a scenario name
|
|
67
|
+
|
|
68
|
+
def print_scenario_name(text)
|
|
69
|
+
log_without_formatting { info " => Scenario: #{text}" }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def initialize
|
|
75
|
+
@logger = Logger.new('ruby_log')
|
|
76
|
+
@logger.add(console_log)
|
|
77
|
+
@logger.add(error_log)
|
|
78
|
+
self.base_formatter = default_formatter
|
|
79
|
+
Logger['ruby_log'].level = Howitzer.debug_mode ? ALL : INFO
|
|
80
|
+
Logger['ruby_log'].trace = true
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#:nocov:
|
|
84
|
+
def log_without_formatting
|
|
85
|
+
self.base_formatter = blank_formatter
|
|
86
|
+
yield
|
|
87
|
+
self.base_formatter = default_formatter
|
|
88
|
+
end
|
|
89
|
+
#:nocov:
|
|
90
|
+
|
|
91
|
+
def console_log
|
|
92
|
+
StdoutOutputter.new(:console).tap { |o| o.only_at(INFO, DEBUG, WARN) }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def error_log
|
|
96
|
+
StderrOutputter.new(:error, 'level' => ERROR)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#:nocov:
|
|
100
|
+
def blank_formatter
|
|
101
|
+
PatternFormatter.new(pattern: '%m')
|
|
102
|
+
end
|
|
103
|
+
#:nocov:
|
|
104
|
+
|
|
105
|
+
#:nocov:
|
|
106
|
+
def default_formatter
|
|
107
|
+
params = if Howitzer.hide_datetime_from_log
|
|
108
|
+
{ pattern: '[%l] %m' }
|
|
109
|
+
else
|
|
110
|
+
{ pattern: '%d [%l] :: %m', date_pattern: '%Y/%m/%d %H:%M:%S' }
|
|
111
|
+
end
|
|
112
|
+
PatternFormatter.new(params)
|
|
113
|
+
end
|
|
114
|
+
#:nocov:
|
|
115
|
+
|
|
116
|
+
def base_formatter=(formatter)
|
|
117
|
+
@logger.outputters.each { |outputter| outputter.formatter = formatter }
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Howitzer
|
|
2
|
+
module MailAdapters
|
|
3
|
+
# +Abstract+ is the superclass of all mail adapters.
|
|
4
|
+
#
|
|
5
|
+
# @abstract This class should not be used directly. Instead, create a
|
|
6
|
+
# subclass that implements:
|
|
7
|
+
# {.find}
|
|
8
|
+
# {#plain_text_body}
|
|
9
|
+
# {#html_body}
|
|
10
|
+
# {#text}
|
|
11
|
+
# {#mail_from}
|
|
12
|
+
# {#recipients}
|
|
13
|
+
# {#received_time}
|
|
14
|
+
# {#sender_email}
|
|
15
|
+
# {#mime_part}
|
|
16
|
+
class Abstract
|
|
17
|
+
attr_reader :message
|
|
18
|
+
|
|
19
|
+
# Finds an email in mailbox
|
|
20
|
+
# @param recipient [String] an email
|
|
21
|
+
# @param subject [String]
|
|
22
|
+
|
|
23
|
+
def self.find(_recipient, _subject)
|
|
24
|
+
raise NotImplementedError
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Creates a new instance of email
|
|
28
|
+
|
|
29
|
+
# @param message [Object] original message data
|
|
30
|
+
|
|
31
|
+
def initialize(message)
|
|
32
|
+
@message = message
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns a plain text body of the email message
|
|
36
|
+
|
|
37
|
+
def plain_text_body
|
|
38
|
+
raise NotImplementedError
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns a html body of the email message
|
|
42
|
+
|
|
43
|
+
def html_body
|
|
44
|
+
raise NotImplementedError
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns a mail text
|
|
48
|
+
|
|
49
|
+
def text
|
|
50
|
+
raise NotImplementedError
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Returns who has sent email data in format: User Name <user@email>
|
|
54
|
+
|
|
55
|
+
def mail_from
|
|
56
|
+
raise NotImplementedError
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Returns an array of recipients who has received current email
|
|
60
|
+
|
|
61
|
+
def recipients
|
|
62
|
+
raise NotImplementedError
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Returns email received time
|
|
66
|
+
|
|
67
|
+
def received_time
|
|
68
|
+
raise NotImplementedError
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Returns sender user email
|
|
72
|
+
|
|
73
|
+
def sender_email
|
|
74
|
+
raise NotImplementedError
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Allows to get email MIME attachment
|
|
78
|
+
|
|
79
|
+
def mime_part
|
|
80
|
+
raise NotImplementedError
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
require 'howitzer/mailgun_api/connector'
|
|
2
|
+
require 'howitzer/exceptions'
|
|
3
|
+
require 'howitzer/mail_adapters/abstract'
|
|
4
|
+
|
|
5
|
+
module Howitzer
|
|
6
|
+
module MailAdapters
|
|
7
|
+
# This class represents Mailgun mail adapter
|
|
8
|
+
class Mailgun < Abstract
|
|
9
|
+
# Finds an email in storage
|
|
10
|
+
# @note emails are stored for 3 days only!
|
|
11
|
+
# @param recipient [String] an email
|
|
12
|
+
# @param subject [String]
|
|
13
|
+
# @raise [EmailNotFoundError] if message blank
|
|
14
|
+
|
|
15
|
+
def self.find(recipient, subject)
|
|
16
|
+
message = {}
|
|
17
|
+
retryable(find_retry_params) { message = retrieve_message(recipient, subject) }
|
|
18
|
+
return new(message) if message.present?
|
|
19
|
+
raise Howitzer::EmailNotFoundError,
|
|
20
|
+
"Message with subject '#{subject}' for recipient '#{recipient}' was not found."
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [String] plain text body of the email message
|
|
24
|
+
|
|
25
|
+
def plain_text_body
|
|
26
|
+
message['body-plain']
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [String] html body of the email message
|
|
30
|
+
|
|
31
|
+
def html_body
|
|
32
|
+
message['stripped-html']
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @return [String] stripped text
|
|
36
|
+
|
|
37
|
+
def text
|
|
38
|
+
message['stripped-text']
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [String] an email address specified in `From` field
|
|
42
|
+
|
|
43
|
+
def mail_from
|
|
44
|
+
message['From']
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @return [String] recipient emails separated with `, `
|
|
48
|
+
|
|
49
|
+
def recipients
|
|
50
|
+
message['To'].split ', '
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [String] when email was received
|
|
54
|
+
|
|
55
|
+
def received_time
|
|
56
|
+
message['Received'][/\w+, \d+ \w+ \d+ \d+:\d+:\d+ -\d+ \(\w+\)$/]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @return [String] a real sender email address
|
|
60
|
+
|
|
61
|
+
def sender_email
|
|
62
|
+
message['sender']
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @return [Array] attachments
|
|
66
|
+
|
|
67
|
+
def mime_part
|
|
68
|
+
message['attachments']
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @raise [NoAttachmentsError] if no attachments present
|
|
72
|
+
# @return [Array] attachments
|
|
73
|
+
|
|
74
|
+
def mime_part!
|
|
75
|
+
files = mime_part
|
|
76
|
+
return files if files.present?
|
|
77
|
+
raise Howitzer::NoAttachmentsError, 'No attachments where found.'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def self.events
|
|
81
|
+
MailgunApi::Connector.instance.client.get(
|
|
82
|
+
"#{MailgunApi::Connector.instance.domain}/events", params: { event: 'stored' }
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
private_class_method :events
|
|
86
|
+
|
|
87
|
+
def self.event_by(recipient, subject)
|
|
88
|
+
events.to_h['items'].find do |hash|
|
|
89
|
+
hash['message']['recipients'].first == recipient && hash['message']['headers']['subject'] == subject
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
private_class_method :event_by
|
|
93
|
+
|
|
94
|
+
def self.find_retry_params
|
|
95
|
+
{
|
|
96
|
+
timeout: Howitzer.mailgun_idle_timeout,
|
|
97
|
+
sleep: Howitzer.mailgun_sleep_time,
|
|
98
|
+
silent: true,
|
|
99
|
+
logger: Howitzer::Log,
|
|
100
|
+
on: Howitzer::EmailNotFoundError
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
private_class_method :find_retry_params
|
|
104
|
+
|
|
105
|
+
def self.retrieve_message(recipient, subject)
|
|
106
|
+
event = event_by(recipient, subject)
|
|
107
|
+
raise Howitzer::EmailNotFoundError, 'Message not received yet, retry...' unless event
|
|
108
|
+
|
|
109
|
+
message_url = event['storage']['url']
|
|
110
|
+
MailgunApi::Connector.instance.client.get_url(message_url).to_h
|
|
111
|
+
end
|
|
112
|
+
private_class_method :retrieve_message
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'rest-client'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'howitzer/mailgun_api/response'
|
|
4
|
+
require 'howitzer/exceptions'
|
|
5
|
+
|
|
6
|
+
module Howitzer
|
|
7
|
+
module MailgunApi
|
|
8
|
+
# A Mailgun::Client object is used to communicate with the Mailgun API. It is a
|
|
9
|
+
# wrapper around RestClient so you don't have to worry about the HTTP aspect
|
|
10
|
+
# of communicating with Mailgun API.
|
|
11
|
+
class Client
|
|
12
|
+
USER_AGENT = 'mailgun-sdk-ruby'.freeze
|
|
13
|
+
attr_reader :api_user, :api_key, :api_host, :api_version, :ssl
|
|
14
|
+
def initialize(api_user: 'api', api_key:, api_host: 'api.mailgun.net', api_version: 'v3', ssl: true)
|
|
15
|
+
@api_user = api_user
|
|
16
|
+
@api_key = api_key
|
|
17
|
+
@api_host = api_host
|
|
18
|
+
@api_version = api_version
|
|
19
|
+
@ssl = ssl
|
|
20
|
+
@http_client = ::RestClient::Resource.new(endpoint, user: api_user, password: api_key, user_agent: USER_AGENT)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Generic Mailgun GET Handler
|
|
24
|
+
#
|
|
25
|
+
# @param resource_path [String] this is the API resource you wish to interact
|
|
26
|
+
# with. Be sure to include your domain, where it is necessary.
|
|
27
|
+
# @param params [Hash] this should be a standard Hash for query
|
|
28
|
+
# containing required parameters for the requested resource.
|
|
29
|
+
# @raise [CommunicationError] if something went wrong
|
|
30
|
+
# @return [Mailgun::Response] a Mailgun::Response object.
|
|
31
|
+
|
|
32
|
+
def get(resource_path, params: nil, accept: '*/*')
|
|
33
|
+
http_params = { accept: accept }
|
|
34
|
+
http_params = http_params.merge(params: params) if params
|
|
35
|
+
response = http_client[resource_path].get(http_params)
|
|
36
|
+
Response.new(response)
|
|
37
|
+
rescue => e
|
|
38
|
+
raise Howitzer::CommunicationError, e.message
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Extracts data by url in custom way
|
|
42
|
+
# @note This method was introducted because of saving emails to different nodes.
|
|
43
|
+
# As result we can not use {#get} method, because client holds general api url
|
|
44
|
+
#
|
|
45
|
+
# @param resource_url [String] a full url
|
|
46
|
+
# @param params [Hash] this should be a standard Hash for query
|
|
47
|
+
# containing required parameters for the requested resource.
|
|
48
|
+
# @param accept [String] an accept pattern for headers
|
|
49
|
+
# @raise [CommunicationError] if something went wrong
|
|
50
|
+
# @return [Mailgun::Response] a Mailgun::Response object.
|
|
51
|
+
|
|
52
|
+
def get_url(resource_url, params: nil, accept: '*/*')
|
|
53
|
+
response = ::RestClient::Request.execute(
|
|
54
|
+
method: :get,
|
|
55
|
+
url: resource_url,
|
|
56
|
+
user: api_user,
|
|
57
|
+
password: api_key,
|
|
58
|
+
user_agent: USER_AGENT,
|
|
59
|
+
accept: accept,
|
|
60
|
+
params: params
|
|
61
|
+
)
|
|
62
|
+
Response.new(response)
|
|
63
|
+
rescue => e
|
|
64
|
+
raise Howitzer::CommunicationError, e.message
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
attr_reader :http_client
|
|
70
|
+
|
|
71
|
+
def endpoint
|
|
72
|
+
scheme = "http#{'s' if ssl}"
|
|
73
|
+
res = "#{scheme}://#{api_host}"
|
|
74
|
+
res << "/#{api_version}" if api_version
|
|
75
|
+
res
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'howitzer/mailgun_api/client'
|
|
3
|
+
require 'howitzer/exceptions'
|
|
4
|
+
|
|
5
|
+
module Howitzer
|
|
6
|
+
module MailgunApi
|
|
7
|
+
# This class represent connector to Mailgun service
|
|
8
|
+
class Connector
|
|
9
|
+
include Singleton
|
|
10
|
+
|
|
11
|
+
attr_reader :api_key
|
|
12
|
+
attr_accessor :domain
|
|
13
|
+
|
|
14
|
+
# Assigns default value for a domain
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
self.domain = Howitzer.mailgun_domain
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [Client] a mailgun client
|
|
21
|
+
# @raise [InvalidApiKeyError] if api_key is blank
|
|
22
|
+
|
|
23
|
+
def client(api_key = Howitzer.mailgun_key)
|
|
24
|
+
check_api_key(api_key)
|
|
25
|
+
return @client if @api_key == api_key && @api_key
|
|
26
|
+
@api_key = api_key
|
|
27
|
+
@client = Client.new(api_key: @api_key)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def check_api_key(api_key)
|
|
33
|
+
raise Howitzer::InvalidApiKeyError, 'Api key can not be blank' if api_key.blank?
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|