howitzer 2.0.3 → 2.1.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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -2
  3. data/.travis.yml +3 -3
  4. data/CHANGELOG.md +27 -11
  5. data/Gemfile +1 -0
  6. data/ISSUE_TEMPLATE.md +16 -0
  7. data/README.md +2 -1
  8. data/Rakefile +18 -2
  9. data/bin/howitzer +7 -6
  10. data/features/cli_help.feature +1 -1
  11. data/features/cli_new.feature +51 -11
  12. data/features/cli_update.feature +44 -4
  13. data/features/cli_version.feature +1 -1
  14. data/features/step_definitions/common_steps.rb +5 -0
  15. data/generators/base_generator.rb +30 -16
  16. data/generators/config/config_generator.rb +13 -3
  17. data/generators/config/templates/boot.rb +1 -1
  18. data/generators/config/templates/capybara.rb +2 -128
  19. data/generators/config/templates/default.yml +20 -3
  20. data/generators/config/templates/drivers/browserstack.rb +19 -0
  21. data/generators/config/templates/drivers/crossbrowsertesting.rb +25 -0
  22. data/generators/config/templates/drivers/headless_chrome.rb +16 -0
  23. data/generators/config/templates/drivers/phantomjs.rb +20 -0
  24. data/generators/config/templates/drivers/poltergeist.rb +11 -0
  25. data/generators/config/templates/drivers/sauce.rb +21 -0
  26. data/generators/config/templates/drivers/selenium.rb +24 -0
  27. data/generators/config/templates/drivers/selenium_grid.rb +27 -0
  28. data/generators/config/templates/drivers/testingbot.rb +20 -0
  29. data/generators/config/templates/drivers/webkit.rb +6 -0
  30. data/generators/cucumber/cucumber_generator.rb +2 -2
  31. data/generators/cucumber/templates/cucumber.rake +0 -8
  32. data/generators/cucumber/templates/env.rb +1 -1
  33. data/generators/cucumber/templates/transformers.rb +11 -25
  34. data/generators/emails/emails_generator.rb +2 -2
  35. data/generators/emails/templates/example_email.rb +1 -1
  36. data/generators/prerequisites/prerequisites_generator.rb +3 -3
  37. data/generators/prerequisites/templates/base.rb +1 -1
  38. data/generators/prerequisites/templates/{factory_girl.rb → factory_bot.rb} +6 -6
  39. data/generators/prerequisites/templates/users.rb +1 -1
  40. data/generators/root/root_generator.rb +2 -2
  41. data/generators/root/templates/.rubocop.yml +2 -2
  42. data/generators/root/templates/Gemfile.erb +14 -18
  43. data/generators/rspec/rspec_generator.rb +2 -2
  44. data/generators/rspec/templates/spec_helper.rb +1 -1
  45. data/generators/tasks/tasks_generator.rb +2 -2
  46. data/generators/turnip/templates/spec_helper.rb +1 -1
  47. data/generators/turnip/turnip_generator.rb +2 -2
  48. data/generators/web/web_generator.rb +2 -2
  49. data/howitzer.gemspec +3 -1
  50. data/lib/howitzer/capybara_helpers.rb +25 -8
  51. data/lib/howitzer/gmail_api.rb +7 -0
  52. data/lib/howitzer/gmail_api/client.rb +22 -0
  53. data/lib/howitzer/mail_adapters/gmail.rb +93 -0
  54. data/lib/howitzer/mail_adapters/mailgun.rb +2 -2
  55. data/lib/howitzer/mail_adapters/mailtrap.rb +105 -0
  56. data/lib/howitzer/mailtrap_api.rb +7 -0
  57. data/lib/howitzer/mailtrap_api/client.rb +52 -0
  58. data/lib/howitzer/version.rb +1 -1
  59. data/lib/howitzer/web/page.rb +13 -1
  60. data/lib/howitzer/web/page_dsl.rb +1 -1
  61. data/spec/config/custom.yml +1 -1
  62. data/spec/spec_helper.rb +1 -0
  63. data/spec/unit/generators/base_generator_spec.rb +23 -12
  64. data/spec/unit/generators/config_generator_spec.rb +27 -6
  65. data/spec/unit/generators/cucumber_generator_spec.rb +8 -8
  66. data/spec/unit/generators/emails_generator_spec.rb +2 -2
  67. data/spec/unit/generators/prerequisites_generator_spec.rb +7 -7
  68. data/spec/unit/generators/root_generator_spec.rb +25 -22
  69. data/spec/unit/generators/rspec_generator_spec.rb +4 -4
  70. data/spec/unit/generators/tasks_generator_spec.rb +2 -2
  71. data/spec/unit/generators/turnip_generator_spec.rb +7 -7
  72. data/spec/unit/generators/web_generator_spec.rb +3 -3
  73. data/spec/unit/lib/capybara_helpers_spec.rb +2 -1
  74. data/spec/unit/lib/gmail_api/client_spec.rb +26 -0
  75. data/spec/unit/lib/mail_adapters/gmail_spec.rb +128 -0
  76. data/spec/unit/lib/mail_adapters/mailgun_spec.rb +13 -18
  77. data/spec/unit/lib/mail_adapters/mailtrap_spec.rb +130 -0
  78. data/spec/unit/lib/mailgun_api/client_spec.rb +31 -9
  79. data/spec/unit/lib/mailtrap_api/client_spec.rb +67 -0
  80. data/spec/unit/lib/web/page_spec.rb +30 -1
  81. metadata +63 -8
  82. data/features/support/transformers.rb +0 -3
  83. data/spec/support/mailgun_unit_client.rb +0 -68
@@ -18,7 +18,7 @@ module Howitzer
18
18
  # HomePage.on { expect(HomePage.given).to have_menu_section } # Bad
19
19
  # HomePage.on { is_expected.to have_menu_section } # Good
20
20
 
21
- def is_expected # rubocop:disable Style/PredicateName
21
+ def is_expected # rubocop:disable Naming/PredicateName
22
22
  expect(page_klass.given)
23
23
  end
24
24
 
@@ -1,7 +1,7 @@
1
1
  log_dir: "spec/log"
2
2
  driver: selenium
3
3
  mailgun_domain: mailgun@test.domain
4
- mailgun_sleep_time: 0.05
4
+ mail_sleep_time: 0.05
5
5
  page_load_idle_timeout: 0.1
6
6
  capybara_wait_time: 5
7
7
  cloud_http_idle_timeout: 10
@@ -31,6 +31,7 @@ require 'active_support/deprecation/method_wrappers'
31
31
  require 'active_support/core_ext'
32
32
  require 'repeater'
33
33
  require 'sexy_settings'
34
+ require 'fake_web'
34
35
 
35
36
  SexySettings.configure do |config|
36
37
  config.path_to_default_settings = File.expand_path(
@@ -121,10 +121,14 @@ RSpec.describe Howitzer::BaseGenerator do
121
121
  after { subject }
122
122
  context 'when destination file exists' do
123
123
  before { allow(File).to receive(:exist?).with(destination_path) { true } }
124
- it { expect(generator).to receive(:puts_info).with("Conflict with '#{list.first[:destination]}' template").once }
124
+ it do
125
+ expect(generator).to receive(:puts_info).with(
126
+ ColorizedString.new("Conflict with '#{list.first[:destination]}' template").yellow
127
+ ).once
128
+ end
125
129
  it do
126
130
  expect(generator).to receive(:print_info).with(
127
- " Overwrite '#{list.first[:destination]}' template? [Yn]:"
131
+ ColorizedString.new(" Overwrite '#{list.first[:destination]}' template? [Yn]:").yellow
128
132
  ).once
129
133
  end
130
134
  context 'and answer is yes' do
@@ -152,7 +156,7 @@ RSpec.describe Howitzer::BaseGenerator do
152
156
  after { subject }
153
157
  context 'when banner present' do
154
158
  let(:banner) { 'banner' }
155
- it { expect(described_class.logger).to receive(:puts).with(banner).twice }
159
+ it { expect(described_class.logger).to receive(:puts).with(ColorizedString.new(banner.chomp).light_cyan).twice }
156
160
  end
157
161
  context 'when banner blank' do
158
162
  let(:banner) { '' }
@@ -178,7 +182,7 @@ RSpec.describe Howitzer::BaseGenerator do
178
182
  subject { described_class.new({}).send(:puts_error, 'data') }
179
183
  before { allow_any_instance_of(described_class).to receive(:print_banner) { nil } }
180
184
  after { subject }
181
- it { expect(described_class.logger).to receive(:puts).with(' ERROR: data') }
185
+ it { expect(described_class.logger).to receive(:puts).with(ColorizedString.new(' ERROR: data').red) }
182
186
  end
183
187
 
184
188
  describe '#source_path' do
@@ -212,39 +216,46 @@ RSpec.describe Howitzer::BaseGenerator do
212
216
  before { allow(File).to receive(:exist?).with(dst) { true } }
213
217
  context 'when identical with source file' do
214
218
  before { allow(FileUtils).to receive(:identical?).with(src, dst) { true } }
215
- it { expect(generator).to receive(:puts_info).with("Identical 'd.txt' file").once }
219
+ it do
220
+ expect(generator).to receive(:puts_info).with("#{ColorizedString.new('Identical').light_green}"\
221
+ " 'd.txt' file").once
222
+ end
216
223
  end
217
224
  context 'when not identical with source file' do
218
225
  before do
219
226
  allow(FileUtils).to receive(:identical?).with(src, dst) { false }
220
- expect(generator).to receive(:puts_info).with("Conflict with 'd.txt' file")
221
- expect(generator).to receive(:print_info).with(" Overwrite 'd.txt' file? [Yn]:")
227
+ expect(generator).to receive(:puts_info).with(ColorizedString.new("Conflict with 'd.txt' file").yellow)
228
+ expect(generator).to receive(:print_info).with(ColorizedString.new(" Overwrite 'd.txt' file? [Yn]:").yellow)
222
229
  end
223
230
  context 'when user typed Y' do
224
231
  before { allow(generator).to receive(:gets) { 'Y' } }
225
232
  it do
226
233
  expect(FileUtils).to receive(:cp).with(src, dst) { nil }.once
227
- expect(generator).to receive(:puts_info).with(" Forced 'd.txt' file")
234
+ expect(generator).to receive(:puts_info).with(" #{ColorizedString.new('Forced').light_green}"\
235
+ " 'd.txt' file")
228
236
  end
229
237
  end
230
238
  context 'when user typed y' do
231
239
  before { allow(generator).to receive(:gets) { 'y' } }
232
240
  it do
233
241
  expect(FileUtils).to receive(:cp).with(src, dst) { nil }.once
234
- expect(generator).to receive(:puts_info).with(" Forced 'd.txt' file")
242
+ expect(generator).to receive(:puts_info).with(" #{ColorizedString.new('Forced').light_green}"\
243
+ " 'd.txt' file")
235
244
  end
236
245
  end
237
246
  context 'when user typed N' do
238
247
  before { allow(generator).to receive(:gets) { 'N' } }
239
248
  it do
240
- expect(generator).to receive(:puts_info).with(" Skipped 'd.txt' file")
249
+ expect(generator).to receive(:puts_info).with(" #{ColorizedString.new('Skipped').light_black}"\
250
+ " 'd.txt' file")
241
251
  expect(FileUtils).not_to receive(:cp)
242
252
  end
243
253
  end
244
254
  context 'when user typed n' do
245
255
  before { allow(generator).to receive(:gets) { 'n' } }
246
256
  it do
247
- expect(generator).to receive(:puts_info).with(" Skipped 'd.txt' file")
257
+ expect(generator).to receive(:puts_info).with(" #{ColorizedString.new('Skipped').light_black}"\
258
+ " 'd.txt' file")
248
259
  expect(FileUtils).not_to receive(:cp)
249
260
  end
250
261
  end
@@ -260,7 +271,7 @@ RSpec.describe Howitzer::BaseGenerator do
260
271
  context 'when destination file missing' do
261
272
  before { allow(File).to receive(:exist?).with(dst) { false } }
262
273
  it do
263
- expect(generator).to receive(:puts_info).with("Added 'd.txt' file")
274
+ expect(generator).to receive(:puts_info).with("#{ColorizedString.new('Added').light_green} 'd.txt' file")
264
275
  expect(FileUtils).to receive(:cp).with(src, dst).once
265
276
  end
266
277
  end
@@ -18,18 +18,39 @@ RSpec.describe 'Generators' do
18
18
  { name: '/config/boot.rb', is_directory: false, size: template_file_size('config', 'boot.rb') },
19
19
  { name: '/config/capybara.rb', is_directory: false, size: template_file_size('config', 'capybara.rb') },
20
20
  { name: '/config/custom.yml', is_directory: false, size: template_file_size('config', 'custom.yml') },
21
- { name: '/config/default.yml', is_directory: false, size: template_file_size('config', 'default.yml') }
21
+ { name: '/config/default.yml', is_directory: false, size: template_file_size('config', 'default.yml') },
22
+ { name: '/config/drivers', is_directory: true },
23
+ { name: '/config/drivers/browserstack.rb', is_directory: false, size: 914 },
24
+ { name: '/config/drivers/crossbrowsertesting.rb', is_directory: false, size: 1126 },
25
+ { name: '/config/drivers/headless_chrome.rb', is_directory: false, size: 696 },
26
+ { name: '/config/drivers/phantomjs.rb', is_directory: false, size: 636 },
27
+ { name: '/config/drivers/poltergeist.rb', is_directory: false, size: 362 },
28
+ { name: '/config/drivers/sauce.rb', is_directory: false, size: 871 },
29
+ { name: '/config/drivers/selenium.rb', is_directory: false, size: 1097 },
30
+ { name: '/config/drivers/selenium_grid.rb', is_directory: false, size: 1272 },
31
+ { name: '/config/drivers/testingbot.rb', is_directory: false, size: 804 },
32
+ { name: '/config/drivers/webkit.rb', is_directory: false, size: 179 }
22
33
  ]
23
34
  end
24
35
 
25
36
  it { is_expected.to eql(expected_result) }
26
37
  describe 'output' do
27
38
  let(:expected_output) do
28
- " * Config files generation ...
29
- Added 'config/boot.rb' file
30
- Added 'config/custom.yml' file
31
- Added 'config/capybara.rb' file
32
- Added 'config/default.yml' file\n"
39
+ "#{ColorizedString.new(' * Config files generation ...').light_cyan}
40
+ #{ColorizedString.new('Added').light_green} 'config/boot.rb' file
41
+ #{ColorizedString.new('Added').light_green} 'config/custom.yml' file
42
+ #{ColorizedString.new('Added').light_green} 'config/capybara.rb' file
43
+ #{ColorizedString.new('Added').light_green} 'config/default.yml' file
44
+ #{ColorizedString.new('Added').light_green} 'config/drivers/browserstack.rb' file
45
+ #{ColorizedString.new('Added').light_green} 'config/drivers/crossbrowsertesting.rb' file
46
+ #{ColorizedString.new('Added').light_green} 'config/drivers/headless_chrome.rb' file
47
+ #{ColorizedString.new('Added').light_green} 'config/drivers/phantomjs.rb' file
48
+ #{ColorizedString.new('Added').light_green} 'config/drivers/poltergeist.rb' file
49
+ #{ColorizedString.new('Added').light_green} 'config/drivers/sauce.rb' file
50
+ #{ColorizedString.new('Added').light_green} 'config/drivers/selenium.rb' file
51
+ #{ColorizedString.new('Added').light_green} 'config/drivers/selenium_grid.rb' file
52
+ #{ColorizedString.new('Added').light_green} 'config/drivers/testingbot.rb' file
53
+ #{ColorizedString.new('Added').light_green} 'config/drivers/webkit.rb' file\n"
33
54
  end
34
55
  subject { output.string }
35
56
  it { is_expected.to eql(expected_output) }
@@ -46,14 +46,14 @@ RSpec.describe 'Generators' do
46
46
  it { is_expected.to eql(expected_result) }
47
47
  describe 'output' do
48
48
  let(:expected_output) do
49
- " * Cucumber integration to the framework ...
50
- Added 'features/step_definitions/common_steps.rb' file
51
- Added 'features/support/env.rb' file
52
- Added 'features/support/hooks.rb' file
53
- Added 'features/support/transformers.rb' file
54
- Added 'features/example.feature' file
55
- Added 'tasks/cucumber.rake' file
56
- Added 'tasks/cuke_sniffer.rake' file\n"
49
+ "#{ColorizedString.new(' * Cucumber integration to the framework ...').light_cyan}
50
+ #{ColorizedString.new('Added').light_green} 'features/step_definitions/common_steps.rb' file
51
+ #{ColorizedString.new('Added').light_green} 'features/support/env.rb' file
52
+ #{ColorizedString.new('Added').light_green} 'features/support/hooks.rb' file
53
+ #{ColorizedString.new('Added').light_green} 'features/support/transformers.rb' file
54
+ #{ColorizedString.new('Added').light_green} 'features/example.feature' file
55
+ #{ColorizedString.new('Added').light_green} 'tasks/cucumber.rake' file
56
+ #{ColorizedString.new('Added').light_green} 'tasks/cuke_sniffer.rake' file\n"
57
57
  end
58
58
  subject { output.string }
59
59
  it { is_expected.to eql(expected_output) }
@@ -25,8 +25,8 @@ RSpec.describe 'Generators' do
25
25
  it { is_expected.to eql(expected_result) }
26
26
  describe 'output' do
27
27
  let(:expected_output) do
28
- " * Email example generation ...
29
- Added '/emails/example_email.rb' file\n"
28
+ "#{ColorizedString.new(' * Email example generation ...').light_cyan}
29
+ #{ColorizedString.new('Added').light_green} '/emails/example_email.rb' file\n"
30
30
  end
31
31
  subject { output.string }
32
32
  it { is_expected.to eql(expected_output) }
@@ -21,8 +21,8 @@ RSpec.describe 'Generators' do
21
21
  is_directory: false, size: template_file_size('prerequisites', 'users.rb')
22
22
  },
23
23
  {
24
- name: '/prerequisites/factory_girl.rb',
25
- is_directory: false, size: template_file_size('prerequisites', 'factory_girl.rb')
24
+ name: '/prerequisites/factory_bot.rb',
25
+ is_directory: false, size: template_file_size('prerequisites', 'factory_bot.rb')
26
26
  },
27
27
  { name: '/prerequisites/models', is_directory: true },
28
28
  {
@@ -40,11 +40,11 @@ RSpec.describe 'Generators' do
40
40
  it { is_expected.to eql(expected_result) }
41
41
  describe 'output' do
42
42
  let(:expected_output) do
43
- " * Pre-requisites integration to the framework ...
44
- Added 'prerequisites/factory_girl.rb' file
45
- Added 'prerequisites/factories/users.rb' file
46
- Added 'prerequisites/models/base.rb' file
47
- Added 'prerequisites/models/user.rb' file\n"
43
+ "#{ColorizedString.new(' * Pre-requisites integration to the framework ...').light_cyan}
44
+ #{ColorizedString.new('Added').light_green} 'prerequisites/factory_bot.rb' file
45
+ #{ColorizedString.new('Added').light_green} 'prerequisites/factories/users.rb' file
46
+ #{ColorizedString.new('Added').light_green} 'prerequisites/models/base.rb' file
47
+ #{ColorizedString.new('Added').light_green} 'prerequisites/models/user.rb' file\n"
48
48
  end
49
49
  subject { output.string }
50
50
  it { is_expected.to eql(expected_output) }
@@ -15,8 +15,8 @@ RSpec.describe 'Generators' do
15
15
  let(:expected_result) do
16
16
  [
17
17
  { name: '/.gitignore', is_directory: false, size: 196 },
18
- { name: '/.rubocop.yml', is_directory: false, size: 634 },
19
- { name: '/Gemfile', is_directory: false, size: 625 },
18
+ { name: '/.rubocop.yml', is_directory: false, size: 633 },
19
+ { name: '/Gemfile', is_directory: false, size: 624 },
20
20
  { name: '/Rakefile', is_directory: false, size: template_file_size('root', 'Rakefile') }
21
21
  ]
22
22
  end
@@ -26,43 +26,46 @@ RSpec.describe 'Generators' do
26
26
  subject { output.string }
27
27
  context 'when options is empty' do
28
28
  let(:expected_output) do
29
- " * Root files generation ...
30
- Added '.gitignore' file
31
- Added '.rubocop.yml' file
32
- Added 'Rakefile' file
33
- Added template 'Gemfile.erb' with params '{}' to destination 'Gemfile'\n"
29
+ "#{ColorizedString.new(' * Root files generation ...').light_cyan}
30
+ #{ColorizedString.new('Added').light_green} '.gitignore' file
31
+ #{ColorizedString.new('Added').light_green} '.rubocop.yml' file
32
+ #{ColorizedString.new('Added').light_green} 'Rakefile' file
33
+ #{ColorizedString.new('Added').light_green} template 'Gemfile.erb' with params '{}' to destination 'Gemfile'\n"
34
34
  end
35
35
  it { is_expected.to eql(expected_output) }
36
36
  end
37
37
  context 'when options is rspec => true' do
38
38
  let(:expected_output) do
39
- " * Root files generation ...
40
- Added '.gitignore' file
41
- Added '.rubocop.yml' file
42
- Added 'Rakefile' file
43
- Added template 'Gemfile.erb' with params '{:rspec=>true}' to destination 'Gemfile'\n"
39
+ "#{ColorizedString.new(' * Root files generation ...').light_cyan}
40
+ #{ColorizedString.new('Added').light_green} '.gitignore' file
41
+ #{ColorizedString.new('Added').light_green} '.rubocop.yml' file
42
+ #{ColorizedString.new('Added').light_green} 'Rakefile' file
43
+ #{ColorizedString.new('Added').light_green} template 'Gemfile.erb' with params '{:rspec=>true}' to"\
44
+ " destination 'Gemfile'\n"
44
45
  end
45
46
  let(:options) { { rspec: true } }
46
47
  it { is_expected.to eql(expected_output) }
47
48
  end
48
49
  context 'when options is cucumber => cucumber' do
49
50
  let(:expected_output) do
50
- " * Root files generation ...
51
- Added '.gitignore' file
52
- Added '.rubocop.yml' file
53
- Added 'Rakefile' file
54
- Added template 'Gemfile.erb' with params '{:cucumber=>true}' to destination 'Gemfile'\n"
51
+ "#{ColorizedString.new(' * Root files generation ...').light_cyan}
52
+ #{ColorizedString.new('Added').light_green} '.gitignore' file
53
+ #{ColorizedString.new('Added').light_green} '.rubocop.yml' file
54
+ #{ColorizedString.new('Added').light_green} 'Rakefile' file
55
+ #{ColorizedString.new('Added').light_green} template 'Gemfile.erb' with params '{:cucumber=>true}'"\
56
+ " to destination 'Gemfile'\n"
55
57
  end
56
58
  let(:options) { { cucumber: true } }
57
59
  it { is_expected.to eql(expected_output) }
58
60
  end
59
61
  context 'when options is turnip => true' do
60
62
  let(:expected_output) do
61
- " * Root files generation ...
62
- Added '.gitignore' file
63
- Added '.rubocop.yml' file
64
- Added 'Rakefile' file
65
- Added template 'Gemfile.erb' with params '{:turnip=>true}' to destination 'Gemfile'\n"
63
+ "#{ColorizedString.new(' * Root files generation ...').light_cyan}
64
+ #{ColorizedString.new('Added').light_green} '.gitignore' file
65
+ #{ColorizedString.new('Added').light_green} '.rubocop.yml' file
66
+ #{ColorizedString.new('Added').light_green} 'Rakefile' file
67
+ #{ColorizedString.new('Added').light_green} template 'Gemfile.erb' with params '{:turnip=>true}' to"\
68
+ " destination 'Gemfile'\n"
66
69
  end
67
70
  let(:options) { { turnip: true } }
68
71
  it { is_expected.to eql(expected_output) }
@@ -24,10 +24,10 @@ RSpec.describe 'Generators' do
24
24
  it { is_expected.to eql(expected_result) }
25
25
  describe 'output' do
26
26
  let(:expected_output) do
27
- " * RSpec integration to the framework ...
28
- Added 'spec/spec_helper.rb' file
29
- Added 'spec/example_spec.rb' file
30
- Added 'tasks/rspec.rake' file\n"
27
+ "#{ColorizedString.new(' * RSpec integration to the framework ...').light_cyan}
28
+ #{ColorizedString.new('Added').light_green} 'spec/spec_helper.rb' file
29
+ #{ColorizedString.new('Added').light_green} 'spec/example_spec.rb' file
30
+ #{ColorizedString.new('Added').light_green} 'tasks/rspec.rake' file\n"
31
31
  end
32
32
  subject { output.string }
33
33
  it { is_expected.to eql(expected_output) }
@@ -21,8 +21,8 @@ RSpec.describe 'Generators' do
21
21
  it { is_expected.to eql(expected_result) }
22
22
  describe 'output' do
23
23
  let(:expected_output) do
24
- " * Base rake task generation ...
25
- Added 'tasks/common.rake' file\n"
24
+ "#{ColorizedString.new(' * Base rake task generation ...').light_cyan}
25
+ #{ColorizedString.new('Added').light_green} 'tasks/common.rake' file\n"
26
26
  end
27
27
  subject { output.string }
28
28
  it { is_expected.to eql(expected_output) }
@@ -37,13 +37,13 @@ RSpec.describe 'Generators' do
37
37
  it { is_expected.to eql(expected_result) }
38
38
  describe 'output' do
39
39
  let(:expected_output) do
40
- " * Turnip integration to the framework ...
41
- Added '.rspec' file
42
- Added 'spec/spec_helper.rb' file
43
- Added 'spec/turnip_helper.rb' file
44
- Added 'spec/acceptance/example.feature' file
45
- Added 'spec/steps/common_steps.rb' file
46
- Added 'tasks/turnip.rake' file\n"
40
+ "#{ColorizedString.new(' * Turnip integration to the framework ...').light_cyan}
41
+ #{ColorizedString.new('Added').light_green} '.rspec' file
42
+ #{ColorizedString.new('Added').light_green} 'spec/spec_helper.rb' file
43
+ #{ColorizedString.new('Added').light_green} 'spec/turnip_helper.rb' file
44
+ #{ColorizedString.new('Added').light_green} 'spec/acceptance/example.feature' file
45
+ #{ColorizedString.new('Added').light_green} 'spec/steps/common_steps.rb' file
46
+ #{ColorizedString.new('Added').light_green} 'tasks/turnip.rake' file\n"
47
47
  end
48
48
  subject { output.string }
49
49
  it { is_expected.to eql(expected_output) }
@@ -41,9 +41,9 @@ RSpec.describe 'Generators' do
41
41
  it { is_expected.to eql(expected_result) }
42
42
  describe 'output' do
43
43
  let(:expected_output) do
44
- " * PageOriented pattern structure generation ...
45
- Added 'web/pages/example_page.rb' file
46
- Added 'web/sections/menu_section.rb' file\n"
44
+ "#{ColorizedString.new(' * PageOriented pattern structure generation ...').light_cyan}
45
+ #{ColorizedString.new('Added').light_green} 'web/pages/example_page.rb' file
46
+ #{ColorizedString.new('Added').light_green} 'web/sections/menu_section.rb' file\n"
47
47
  end
48
48
  subject { output.string }
49
49
  it { is_expected.to eql(expected_output) }
@@ -643,7 +643,8 @@ RSpec.describe Howitzer::CapybaraHelpers do
643
643
  allow(cap_class).to receive(:new).with(caps) { des_caps }
644
644
  stub_const('Selenium::WebDriver::Remote::Http::Default', http_class)
645
645
  allow(http_class).to receive(:new).with(no_args) { http_client }
646
- expect(http_client).to receive(:timeout=).with(10)
646
+ expect(http_client).to receive(:read_timeout=).with(10)
647
+ expect(http_client).to receive(:open_timeout=).with(10)
647
648
  allow(Capybara::Selenium::Driver).to receive(:new).with(app, kind_of(Hash)) { driver }
648
649
  expect(driver).to receive(:browser) { driver_browser }
649
650
  expect(driver_browser).to receive(:file_detector=).with(file_detector)
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'howitzer/gmail_api/client'
3
+
4
+ RSpec.describe Howitzer::GmailApi::Client do
5
+ let(:gmail_obj) { described_class.new }
6
+ let(:recipient) { 'test@gmail.com' }
7
+ let(:mail_subject) { 'Confirmation instructions' }
8
+
9
+ describe '.new' do
10
+ subject { gmail_obj }
11
+ it { expect { subject }.not_to raise_error }
12
+ end
13
+
14
+ describe '#find_message' do
15
+ let(:mailbox) { double(Gmail::Mailbox) }
16
+ before do
17
+ allow(mailbox).to receive(:emails).with(
18
+ to: recipient, subject: mail_subject
19
+ ) { [Gmail::Message.new('INBOX', 30)] }
20
+ allow(gmail_obj.instance_variable_get(:@client)).to receive(:inbox) { mailbox }
21
+ end
22
+ it do
23
+ expect(gmail_obj.find_message(recipient, mail_subject)).to be_an_instance_of(Gmail::Message)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+ require 'howitzer/email'
3
+ require 'howitzer/log'
4
+ require 'howitzer/exceptions'
5
+ RSpec.describe 'Gmail Email Adapter' do
6
+ before do
7
+ allow(Howitzer).to receive(:mail_adapter) { 'gmail' }
8
+ Howitzer::Email.adapter = 'gmail'
9
+ end
10
+ let(:email) { 'test@gmail.com' }
11
+ let(:mail_subject) { 'Confirmation instructions' }
12
+ let(:message) { double(Gmail::Message) }
13
+ let(:email_object) { Howitzer::Email.adapter.new(message) }
14
+ let(:client) { instance_double(Howitzer::GmailApi::Client) }
15
+ let(:to_msg) { { 'name' => 'test', 'route' => nil, 'mailbox' => 'test', 'host' => 'gmail.com' } }
16
+ let(:attachment) do
17
+ '--f403043c3de80c1017055511c33d
18
+ Content-Type: text/plain; charset="US-ASCII"; name="te.txt"
19
+ Content-Disposition: attachment; filename="te.txt"
20
+ Content-Transfer-Encoding: base64
21
+ X-Attachment-Id: f_j5iaurws0'
22
+ end
23
+ before do
24
+ allow_any_instance_of(Howitzer::GmailApi::Client).to receive(:find_message).with(
25
+ email,
26
+ mail_subject
27
+ ) { message }
28
+ allow_any_instance_of(Howitzer::GmailApi::Client).to receive(:find_message).with(
29
+ email,
30
+ 'Wrong subject'
31
+ ) { nil }
32
+ end
33
+ describe '.find' do
34
+ subject { Howitzer::MailAdapters::Gmail.find(email, mail_subject, wait: 0.01) }
35
+ context 'when message is found' do
36
+ it do
37
+ expect(Howitzer::Email.adapter).to receive(:new).with(message).once
38
+ subject
39
+ end
40
+ end
41
+
42
+ context 'when message is not found' do
43
+ let(:mail_subject) { 'Wrong subject' }
44
+ it do
45
+ expect { subject }.to raise_error(
46
+ Howitzer::EmailNotFoundError,
47
+ "Message with subject '#{mail_subject}' for recipient '#{email}' was not found."
48
+ )
49
+ end
50
+ end
51
+ end
52
+
53
+ describe '#plain_text_body' do
54
+ before { allow(message).to receive(:body) { Mail::Body.new('test body') } }
55
+ it { expect(email_object.plain_text_body).to eql 'test body' }
56
+ end
57
+
58
+ describe '#html_body' do
59
+ before do
60
+ html_part = <<-HTML
61
+ Content-Type: text/html;
62
+ charset=UTF-8
63
+ Content-Transfer-Encoding: 7bit
64
+ <p>test body</p>
65
+ HTML
66
+ allow(message).to receive(:html_part) { Mail::Part.new(html_part) }
67
+ end
68
+ it { expect(email_object.html_body).to include('<p>test body</p>') }
69
+ end
70
+
71
+ describe '#text' do
72
+ before { allow(message).to receive(:text_part) { Mail::Part.new('test text part') } }
73
+ it { expect(email_object.text).to include 'test text part' }
74
+ end
75
+
76
+ describe '#mail_from' do
77
+ before { allow(message).to receive(:from) { [to_msg] } }
78
+ it { expect(email_object.mail_from).to eql email }
79
+ end
80
+
81
+ describe '#recipients' do
82
+ context 'when one recipient' do
83
+ before { allow(message).to receive(:to) { [to_msg] } }
84
+ it { expect(email_object.recipients).to include email }
85
+ end
86
+ context 'when several recipients' do
87
+ before { allow(message).to receive(:to) { [to_msg, to_msg.merge('mailbox' => 'test2')] } }
88
+ it { expect(email_object.recipients).to eql [email, 'test2@gmail.com'] }
89
+ end
90
+ end
91
+
92
+ describe '#received_time' do
93
+ before { allow(message).to receive(:date) { 'Mon, 24 Jul 2017 18:20:58 +0300' } }
94
+ it { expect(email_object.received_time).to eql Time.parse('Mon, 24 Jul 2017 18:20:58 +0300').strftime('%F %T') }
95
+ end
96
+
97
+ describe '#sender_email' do
98
+ before { allow(message).to receive(:from) { [to_msg] } }
99
+ it { expect(email_object.mail_from).to eql email }
100
+ end
101
+
102
+ describe '#mime_part' do
103
+ before { allow(message).to receive(:attachments) { Mail::AttachmentsList.new([Mail::Part.new(attachment)]) } }
104
+ context 'when has attachments'
105
+ it { expect(email_object.mime_part).not_to be_empty }
106
+
107
+ context 'when no attachments' do
108
+ it do
109
+ allow(message).to receive(:attachments) { [] }
110
+ expect(email_object.mime_part).to be_empty
111
+ end
112
+ end
113
+ end
114
+
115
+ describe '#mime_part!' do
116
+ before { allow(message).to receive(:attachments) { Mail::AttachmentsList.new([Mail::Part.new(attachment)]) } }
117
+ context 'when has attachments' do
118
+ it { expect(email_object.mime_part!).not_to be_empty }
119
+ end
120
+
121
+ context 'when no attachments' do
122
+ it do
123
+ allow(message).to receive(:attachments) { [] }
124
+ expect { email_object.mime_part! }.to raise_error(Howitzer::NoAttachmentsError, 'No attachments were found.')
125
+ end
126
+ end
127
+ end
128
+ end