howitzer 1.0.1 → 1.0.2

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.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -1
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +25 -5
  5. data/GETTING_STARTED.md +158 -13
  6. data/README.md +49 -32
  7. data/Rakefile +10 -1
  8. data/bin/howitzer +49 -78
  9. data/features/cli_help.feature +30 -0
  10. data/features/cli_new.feature +263 -0
  11. data/features/cli_unknown.feature +17 -0
  12. data/features/cli_version.feature +14 -0
  13. data/features/step_definitions/common_steps.rb +1 -0
  14. data/features/support/env.rb +1 -0
  15. data/features/support/transformers.rb +3 -0
  16. data/generators/base_generator.rb +2 -0
  17. data/generators/config/config_generator.rb +1 -1
  18. data/generators/config/templates/default.yml +4 -14
  19. data/generators/cucumber/cucumber_generator.rb +1 -1
  20. data/generators/cucumber/templates/cucumber.yml +1 -2
  21. data/generators/cucumber/templates/env.rb +8 -7
  22. data/generators/emails/emails_generator.rb +1 -1
  23. data/generators/pages/pages_generator.rb +1 -1
  24. data/generators/pages/templates/example_page.rb +2 -2
  25. data/generators/root/root_generator.rb +1 -1
  26. data/generators/root/templates/Gemfile +1 -1
  27. data/generators/rspec/rspec_generator.rb +1 -1
  28. data/generators/rspec/templates/example_spec.rb +2 -2
  29. data/generators/rspec/templates/rspec.rake +1 -1
  30. data/generators/rspec/templates/spec_helper.rb +6 -5
  31. data/generators/tasks/tasks_generator.rb +1 -1
  32. data/generators/tasks/templates/common.rake +1 -0
  33. data/howitzer.gemspec +8 -8
  34. data/lib/howitzer.rb +4 -1
  35. data/lib/howitzer/blank_page.rb +6 -0
  36. data/lib/howitzer/capybara/dsl_ex.rb +15 -0
  37. data/lib/howitzer/capybara/settings.rb +267 -0
  38. data/lib/howitzer/email.rb +134 -0
  39. data/lib/howitzer/exceptions.rb +18 -0
  40. data/lib/howitzer/helpers.rb +34 -23
  41. data/lib/howitzer/init.rb +1 -4
  42. data/lib/howitzer/mailgun/client.rb +48 -0
  43. data/lib/howitzer/mailgun/connector.rb +34 -0
  44. data/lib/howitzer/mailgun/response.rb +28 -0
  45. data/lib/howitzer/utils.rb +2 -2
  46. data/lib/howitzer/utils/data_generator/data_storage.rb +15 -2
  47. data/lib/howitzer/utils/data_generator/gen.rb +14 -10
  48. data/lib/howitzer/utils/locator_store.rb +14 -7
  49. data/lib/howitzer/utils/log.rb +2 -0
  50. data/lib/howitzer/utils/page_validator.rb +74 -27
  51. data/lib/howitzer/version.rb +1 -1
  52. data/lib/howitzer/web_page.rb +83 -32
  53. data/spec/config/default.yml +10 -12
  54. data/spec/spec_helper.rb +12 -0
  55. data/spec/support/mailgun_unit_client.rb +60 -0
  56. data/spec/unit/generators/generators_spec.rb +7 -7
  57. data/spec/unit/lib/capybara/dsl_ex_spec.rb +60 -0
  58. data/spec/unit/lib/{capybara_settings_spec.rb → capybara/settings_spec.rb} +16 -10
  59. data/spec/unit/lib/email_spec.rb +129 -0
  60. data/spec/unit/lib/helpers_spec.rb +160 -34
  61. data/spec/unit/lib/init_spec.rb +1 -12
  62. data/spec/unit/lib/mailgun/client_spec.rb +36 -0
  63. data/spec/unit/lib/mailgun/connector_spec.rb +70 -0
  64. data/spec/unit/lib/mailgun/response_spec.rb +29 -0
  65. data/spec/unit/lib/utils/data_generator/data_storage_spec.rb +23 -5
  66. data/spec/unit/lib/utils/data_generator/gen_spec.rb +2 -63
  67. data/spec/unit/lib/utils/locator_store_spec.rb +41 -6
  68. data/spec/unit/lib/utils/log_spec.rb +1 -1
  69. data/spec/unit/lib/utils/page_validator_spec.rb +149 -25
  70. data/spec/unit/lib/web_page_spec.rb +127 -53
  71. metadata +102 -142
  72. data/lib/howitzer/utils/capybara_patched.rb +0 -23
  73. data/lib/howitzer/utils/capybara_settings.rb +0 -247
  74. data/lib/howitzer/utils/email/email.rb +0 -85
  75. data/lib/howitzer/utils/email/mail_client.rb +0 -132
  76. data/lib/howitzer/utils/email/mailgun.rb +0 -175
  77. data/lib/howitzer/utils/email/mailgun_helper.rb +0 -61
  78. data/spec/unit/bin/howitzer_spec.rb +0 -175
  79. data/spec/unit/lib/utils/email/email_spec.rb +0 -75
  80. data/spec/unit/lib/utils/email/mail_client_spec.rb +0 -115
  81. data/spec/unit/lib/utils/email/mailgun_helper_spec.rb +0 -95
@@ -1,175 +0,0 @@
1
- #For details, please see https://github.com/mailgun/mailgun.rb or https://github.com/hardikshah/mailgun.rb
2
- #Modified from original adding rest-client 'remove'
3
- require 'active_resource'
4
- require 'rest-client'
5
-
6
- class Mailgun
7
-
8
- # Initializes Mailgun API
9
- # Must be called before any other method
10
- #
11
- # Parameters:
12
- # api_key - Your API key
13
- # api_url - API base URL
14
- #
15
- def self.init(api_key, api_url = "https://mailgun.net/api/")
16
- MailgunResource.password = api_key
17
- api_url = api_url.gsub(/\/$/, '') + "/"
18
- MailgunResource.site = api_url
19
- end
20
-
21
- # This is a patch of private ActiveResource method.
22
- # It takes HTTPResponse and raise AR-like error if response code is not 2xx
23
- def self.handle_response(response)
24
- case response.code.to_i
25
- when 301,302
26
- raise(Redirection.new(response))
27
- when 200...400
28
- response
29
- when 400
30
- raise(ActiveResource::BadRequest.new(response))
31
- when 401
32
- raise(ActiveResource::UnauthorizedAccess.new(response))
33
- when 403
34
- raise(ActiveResource::ForbiddenAccess.new(response))
35
- when 404
36
- raise(ActiveResource::ResourceNotFound.new(response))
37
- when 405
38
- raise(ActiveResource::MethodNotAllowed.new(response))
39
- when 409
40
- raise(ActiveResource::ResourceConflict.new(response))
41
- when 410
42
- raise(ActiveResource::ResourceGone.new(response))
43
- when 422
44
- raise(ActiveResource::ResourceInvalid.new(response))
45
- when 401...500
46
- raise(ActiveResource::ClientError.new(response))
47
- when 500...600
48
- raise(ActiveResource::ServerError.new(response))
49
- else
50
- raise(ConnectionError.new(response, "Unknown response code: #{response.code}"))
51
- end
52
- end
53
-
54
- module RequestBuilder
55
- def prepare_request(url_string)
56
- uri = URI.parse(url_string)
57
- http = Net::HTTP.new(uri.host, uri.port)
58
- http.use_ssl = true if uri.port == 443
59
- return [http, (uri.path + '?' + uri.query)]
60
- end
61
- end
62
- end
63
-
64
- class MailgunMessage
65
- extend Mailgun::RequestBuilder
66
-
67
- MAILGUN_TAG = 'X-Mailgun-Tag'
68
-
69
- # Sends a MIME-formatted message
70
- #
71
- # raw_mime =
72
- # "Content-Type: text/plain;charset=utf-8\n" +
73
- # "From: me@host\n" +
74
- # "To: you@host\n" +
75
- # "Subject: Hello!\n\n" +
76
- # "Body"
77
- # MailgunMessage::send_raw("me@host", "you@host", raw_mime)
78
- #
79
- def self.send_raw(sender, recipients, raw_body, servername='')
80
- uri_str = "#{MailgunResource.site}messages.eml?api_key=#{MailgunResource.password}&servername=#{servername}"
81
- http, url = prepare_request(uri_str)
82
- data = "#{sender}\n#{recipients}\n\n#{raw_body}"
83
- res = http.post(url, data, {"Content-type" => "text/plain" })
84
- Mailgun::handle_response(res)
85
- end
86
-
87
- # Sends a plain-text message
88
- #
89
- # MailgunMessage::send_text("me@host.com",
90
- # "you@host.com",
91
- # "Subject",
92
- # "Hi!\nThis is message body")
93
- #
94
- def self.send_text(sender, recipients, subject, text, servername='', options = nil)
95
- uri_str = "#{MailgunResource.site}messages.txt?api_key=#{MailgunResource.password}&servername=#{servername}"
96
- params = { :sender => sender, :recipients => recipients, :subject => subject, :body => text}
97
- unless options.nil?
98
- params['options'] = ActiveSupport::JSON.encode(options)
99
- end
100
- http, url = prepare_request(uri_str)
101
- req = Net::HTTP::Post.new(url)
102
- req.set_form_data(params)
103
- res = http.request(req)
104
- Mailgun::handle_response(res)
105
- end
106
- end
107
-
108
- # Base class for Mailgun resource classes
109
- # It adds upsert() method on top of ActiveResource::Base
110
- #
111
- class MailgunResource < ActiveResource::Base
112
- self.user = "api_key"
113
- extend Mailgun::RequestBuilder
114
-
115
- # Create new resource or update it if resource already exist.
116
- # There are 2 differences between upsert() and save():
117
- # - Upsert does not raise an exception if a resource already exist.
118
- # - Upsert does not return the id of freshly inserted resource
119
- #
120
- # >> route = Route.new
121
- # >> route.pattern = '*@mydomain.com'
122
- # >> route.destination = 'http://mydomain.com/addcomment'
123
- # >> route.upsert()
124
- #
125
- def upsert()
126
- self.class.post('upsert', {}, self.to_xml())
127
- end
128
- end
129
-
130
- # All mail arriving to emails addresses that have mailboxes associated
131
- # will be stored on the server and can be later accessed via IMAP or POP3
132
- # protocols.
133
- #
134
- # Mailbox has several properties:
135
- #
136
- # alex@gmail.com
137
- # ^ ^
138
- # | |
139
- # user domain
140
- #
141
- class Mailbox < MailgunResource
142
- # Example of a CSV file:
143
- #
144
- # john@domain.com, password
145
- # doe@domain.com, password2
146
- #
147
- def self.upsert_from_csv(mailboxes)
148
- uri_str = "#{MailgunResource.site}mailboxes.txt?api_key=#{MailgunResource.password}"
149
- http, url = prepare_request(uri_str)
150
- res = http.post(url, mailboxes, {"Content-type" => "text/plain" })
151
- Mailgun::handle_response(res)
152
- end
153
-
154
- def self.remove(mailbox)
155
- res = RestClient.delete "https://api:#{MailgunResource.password}"\
156
- "@api.mailgun.net/v2/#{mailbox.domain}/mailboxes/#{mailbox.user}"
157
- Mailgun::handle_response(res)
158
- end
159
- end
160
-
161
-
162
- # This class represents Mailgun route.
163
- # A route has 2 properties: pattern and destination
164
- #
165
- # Examples of patterns:
166
- # - '*' - match all
167
- # - exact match (foo@bar.com)
168
- # - domain pattern, i.e. a pattern like "@example.com" - it will match all emails going to example.com
169
- # - any regular expression
170
- #
171
- # Destination can be one of:
172
- # - an emails address to forward to
173
- # - a URL for HTTP POST
174
- class Route < MailgunResource
175
- end
@@ -1,61 +0,0 @@
1
- module MailgunHelper
2
-
3
- ##
4
- #
5
- # Creates new mailbox for given user_name
6
- #
7
- # *Parameters:*
8
- # * +user_name+ - user name
9
- # * +domain+ - domain (default to: settings.mail_pop3_domain )
10
- # * +password+ - password (default to: settings.mail_pop3_user_pass )
11
- #
12
-
13
-
14
- def create_mailbox(user_name,
15
- domain=settings.mail_pop3_domain,
16
- password=settings.mail_pop3_user_pass)
17
- log.info "Create '#{user_name}@#{domain}' mailbox"
18
- mbox = Mailbox.new(:user => user_name, :domain => domain, :password => password)
19
- mbox.upsert()
20
- mbox
21
- end
22
-
23
- ##
24
- #
25
- # Deletes given mailbox
26
- #
27
- # *Parameters:*
28
- # * +mailbox+ - mailbox to delete
29
- #
30
-
31
- def delete_mailbox(mailbox)
32
- log.info "Delete '#{mailbox.user}@#{mailbox.domain}' mailbox"
33
- begin
34
- Mailbox.remove(mailbox)
35
- rescue Exception => e
36
- log.warn "Unable to delete '#{mailbox.user}' mailbox: #{e.message}"
37
- end
38
- end
39
-
40
- ##
41
- #
42
- # Deletes all mailboxes except those in exceptions
43
- #
44
- # *Parameters:*
45
- # * +exceptions+ - list of email addresses
46
- #
47
-
48
- def delete_all_mailboxes(*exceptions)
49
- exceptions += ["postmaster@#{settings.mail_smtp_domain}"] #system and default mailbox
50
- exceptions = exceptions.uniq
51
- log.info "Delete all mailboxes except: #{exceptions.map(&:inspect).join(', ')}"
52
- i = 0
53
- Mailbox.find(:all).each do |m|
54
- next if exceptions.include?("#{m.user}@#{m.domain}")
55
- Mailbox.delete(m.id)
56
- i += 1
57
- end
58
-
59
- log.info "Were deleted '#{i}' mailboxes"
60
- end
61
- end
@@ -1,175 +0,0 @@
1
- require "spec_helper"
2
- load "bin/howitzer"
3
-
4
- HELP_MESSAGE = %{
5
- howitzer [command {--cucumber, --rspec}] | {options}
6
-
7
- Commands are ...
8
- install Generate test framework units:
9
- --rspec add RSpec integration with framework
10
- --cucumber add Cucumber integration with framework
11
- Options are ...
12
- --help Display this help message.
13
- --version Display the program version.
14
- }
15
-
16
- shared_examples "check argument" do |arg|
17
- before do
18
- stub_const("ARGV", [arg])
19
- expect(self).to_not receive(:puts)
20
- expect(self).to_not receive(:exit)
21
- end
22
- context "(#{arg})" do
23
- let(:arg) { arg }
24
- it { expect(subject).to be_nil }
25
- end
26
- end
27
-
28
- describe Howitzer do
29
- describe "#check_arguments" do
30
- subject { check_arguments }
31
- context "when right arguments specified" do
32
- it_behaves_like "check argument", 'install --cucumber'
33
- it_behaves_like "check argument", 'install --rspec'
34
- it_behaves_like "check argument", 'install --cucumber --rspec'
35
- it_behaves_like "check argument", 'install --rspec --cucumber'
36
- it_behaves_like "check argument", '--version'
37
- it_behaves_like "check argument", '--help'
38
- it_behaves_like "check argument", '--HELP'
39
- end
40
- context "when arguments incorrect" do
41
- before do
42
- expect(self).to receive(:puts).with("ERROR: incorrect options. Please, see help for details").once
43
- expect(self).to receive(:puts).with(HELP_MESSAGE)
44
- expect(self).to receive(:exit).with(1)
45
- end
46
- context "(missing arguments)" do
47
- it { expect(subject).to be_nil }
48
- end
49
- context "UNKNOWN argument" do
50
- let(:arg) { '--unknown' }
51
- before { stub_const("ARGV", [arg]) }
52
- it { expect(subject).to be_nil }
53
- end
54
- end
55
- end
56
-
57
- describe "#parse_options" do
58
- subject { parse_options }
59
- context "when correct argument received" do
60
- before do
61
- stub_const("ARGV", arg)
62
- expect(self).not_to receive(:puts).with("ERROR: incorrect first argument '#{arg}'")
63
- end
64
- context "'--version' argument given" do
65
- let(:arg) { ['--version'] }
66
- before{ stub_const("Howitzer::VERSION", '1.0.0') }
67
- it do
68
- expect(self).to receive(:exit).with(0).once
69
- expect(self).to receive(:puts).with("Version: 1.0.0")
70
- subject
71
- end
72
- end
73
- context "'--help' argument given" do
74
- let(:arg) { ['--help'] }
75
- it do
76
- expect(self).to receive(:puts).with(HELP_MESSAGE)
77
- subject
78
- end
79
- end
80
- context "'install' argument" do
81
- let(:primary_arg) { 'install' }
82
- let(:generator) { double('generator') }
83
- before do
84
- expect(Howitzer::ConfigGenerator).to receive(:new)
85
- expect(Howitzer::PagesGenerator).to receive(:new)
86
- expect(Howitzer::TasksGenerator).to receive(:new)
87
- expect(Howitzer::EmailsGenerator).to receive(:new)
88
- expect(Howitzer::RootGenerator).to receive(:new)
89
- expect(self).not_to receive(:puts).with("ERROR: Empty option specified.")
90
- expect(self).not_to receive(:puts).with("ERROR: Unknown option specified.")
91
- expect(self).not_to receive(:puts).with(HELP_MESSAGE)
92
- end
93
- context "with option '--cucumber'" do
94
- let(:arg) { [primary_arg, '--cucumber'] }
95
- it do
96
- expect(Howitzer::RspecGenerator).to_not receive(:new)
97
- expect(Howitzer::CucumberGenerator).to receive(:new)
98
- subject
99
- end
100
- end
101
- context "with option '--rspec'" do
102
- let(:arg) {[primary_arg, '--rspec']}
103
- it do
104
- expect(Howitzer::RspecGenerator).to receive(:new)
105
- expect(Howitzer::CucumberGenerator).to_not receive(:new)
106
- subject
107
- end
108
- end
109
- end
110
- end
111
- context "when incorrect arguments received" do
112
- before { stub_const("ARGV", arg) }
113
- context "with (missing) argument" do
114
- let(:arg) {[]}
115
- it do
116
- expect(self).to receive(:puts).with("ERROR: incorrect first argument ('')")
117
- expect(self).to receive(:puts).with(HELP_MESSAGE)
118
- expect(self).to receive(:exit).with(1)
119
- subject
120
- end
121
- end
122
- context "with UNKNOWN argument" do
123
- let(:arg) {['unknown']}
124
- it do
125
- expect(self).to receive(:puts).with("ERROR: incorrect first argument ('unknown')")
126
- expect(self).to receive(:puts).with(HELP_MESSAGE)
127
- expect(self).to receive(:exit).with(1)
128
- subject
129
- end
130
- end
131
- end
132
-
133
- context "when 'install' option received with incorrect arguments" do
134
- let(:primary_arg) { 'install' }
135
- let(:generator) { double('generator') }
136
- before { stub_const("ARGV", arg) }
137
- context "with UNKNOWN option specified" do
138
- let(:arg) {[primary_arg, '--unknown']}
139
- before do
140
- expect(Howitzer::ConfigGenerator).to_not receive(:new)
141
- expect(Howitzer::PagesGenerator).to_not receive(:new)
142
- expect(Howitzer::TasksGenerator).to_not receive(:new)
143
- expect(Howitzer::EmailsGenerator).to_not receive(:new)
144
- expect(Howitzer::RootGenerator).to_not receive(:new)
145
- expect(Howitzer::RspecGenerator).to_not receive(:new)
146
- expect(Howitzer::CucumberGenerator).to_not receive(:new)
147
- end
148
- it do
149
- expect(self).to receive(:puts).with("ERROR: Unknown '--unknown' option specified.")
150
- expect(self).to receive(:puts).with(HELP_MESSAGE)
151
- expect(self).to receive(:exit).with(1)
152
- subject
153
- end
154
- end
155
- context "with no option specified" do
156
- let(:arg) {[primary_arg]}
157
- before do
158
- expect(Howitzer::ConfigGenerator).to_not receive(:new)
159
- expect(Howitzer::PagesGenerator).to_not receive(:new)
160
- expect(Howitzer::TasksGenerator).to_not receive(:new)
161
- expect(Howitzer::EmailsGenerator).to_not receive(:new)
162
- expect(Howitzer::RootGenerator).to_not receive(:new)
163
- expect(Howitzer::RspecGenerator).to_not receive(:new)
164
- expect(Howitzer::CucumberGenerator).to_not receive(:new)
165
- end
166
- it do
167
- expect(self).to receive(:puts).with("ERROR: No option specified for install command.")
168
- expect(self).to receive(:puts).with(HELP_MESSAGE)
169
- expect(self).to receive(:exit).with(1)
170
- subject
171
- end
172
- end
173
- end
174
- end
175
- end
@@ -1,75 +0,0 @@
1
- require "spec_helper"
2
- require "#{lib_path}/howitzer/utils/log"
3
- require "#{lib_path}/howitzer/utils/email/email"
4
-
5
-
6
- describe Email do
7
- let(:message) { double }
8
- let(:message_subject) { 'test_subject' }
9
- let(:mail_address) { double }
10
- let(:recipient) { 'vasya@test.com' }
11
- let(:email_object) { Email.new(message) }
12
- before do
13
- stub_const("Email::SUBJECT", 'test_subject')
14
- stub_const("::Mail::Address", mail_address)
15
- allow(mail_address).to receive(:new).with(recipient).and_return(mail_address)
16
- allow(message).to receive(:to).and_return([recipient])
17
- end
18
-
19
- describe "#new" do
20
- subject { Email.new(message) }
21
- before { allow(message).to receive(:subject).and_return('test_subject') }
22
- context "when subject is the same" do
23
- it { expect(subject.instance_variable_get(:@recipient_address)).to eql(mail_address) }
24
- it { expect(subject.instance_variable_get(:@message)).to eql(message) }
25
- end
26
- end
27
-
28
- describe ".find_by_recipient" do
29
- subject { Email.find_by_recipient(recipient) }
30
- context "when 'recipient' specified " do
31
- before { expect(Email).to receive(:find).with(recipient, 'test_subject').and_return(true).once }
32
- it { expect(subject).to be_true }
33
- end
34
- context "when 'recipient' not specified " do
35
- let(:recipient) { nil }
36
- before { expect(Email).to receive(:find).with(recipient,'test_subject').and_return(nil).once }
37
- it { expect(subject).to be_nil }
38
- end
39
- end
40
-
41
- describe ".find" do
42
- let(:mail_client) { double }
43
- subject { Email.find('Vasya', 'Text') }
44
- before do
45
- stub_const("MailClient", double)
46
- allow(MailClient).to receive(:by_email).and_return(mail_client)
47
- allow(mail_client).to receive(:find_mail).and_return(messages )
48
- allow(message).to receive(:subject).and_return('test_subject')
49
- end
50
- context "when messages.first present" do
51
- let(:messages) { [message] }
52
- it {expect(subject).to be_kind_of(Email) }
53
- end
54
-
55
- context "when messages.first not present" do
56
- let(:messages) {[]}
57
- it do
58
- expect(log).to receive(:error).with("Email was not found (recipient: 'Vasya')").once
59
- subject
60
- end
61
- end
62
- end
63
-
64
- describe "#plain_text_body" do
65
- subject { email_object.plain_text_body }
66
- let(:email_object) { Email.new(message) }
67
- let(:mime_part) { double }
68
- before do
69
- allow(message).to receive(:subject).and_return('test_subject')
70
- expect(mime_part).to receive(:to_s).and_return('test_string')
71
- expect(email_object).to receive(:get_mime_part).with(message, 'text/plain').and_return(mime_part)
72
- end
73
- it { expect(subject).to eql('test_string') }
74
- end
75
- end