ruby_pocket 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +191 -0
  4. data/Rakefile +51 -0
  5. data/config/config.rb +14 -0
  6. data/config/database.rb +14 -0
  7. data/db/migrations/001_create_tags.rb +15 -0
  8. data/db/migrations/002_create_favorites.rb +17 -0
  9. data/db/migrations/003_create_favorites_tags.rb +20 -0
  10. data/db/pocket_development.db +0 -0
  11. data/db/pocket_test.db +0 -0
  12. data/lib/ruby_pocket/all.rb +5 -0
  13. data/lib/ruby_pocket/cli/add_action.rb +12 -0
  14. data/lib/ruby_pocket/cli/delete_action.rb +16 -0
  15. data/lib/ruby_pocket/cli/list_action.rb +39 -0
  16. data/lib/ruby_pocket/cli/open_action.rb +12 -0
  17. data/lib/ruby_pocket/cli/options.rb +23 -0
  18. data/lib/ruby_pocket/cli.rb +8 -0
  19. data/lib/ruby_pocket/environment.rb +11 -0
  20. data/lib/ruby_pocket/favorite.rb +36 -0
  21. data/lib/ruby_pocket/favorite_creator.rb +62 -0
  22. data/lib/ruby_pocket/favorite_query.rb +34 -0
  23. data/lib/ruby_pocket/tag.rb +32 -0
  24. data/lib/ruby_pocket/version.rb +3 -0
  25. data/lib/ruby_pocket/web_page.rb +33 -0
  26. data/lib/ruby_pocket.rb +37 -0
  27. data/test/ruby_pocket/cli/options_test.rb +49 -0
  28. data/test/ruby_pocket/favorite_creator_test.rb +80 -0
  29. data/test/ruby_pocket/favorite_query_test.rb +98 -0
  30. data/test/ruby_pocket/favorite_test.rb +76 -0
  31. data/test/ruby_pocket/features/add_test.rb +40 -0
  32. data/test/ruby_pocket/features/delete_test.rb +45 -0
  33. data/test/ruby_pocket/features/list_test.rb +75 -0
  34. data/test/ruby_pocket/tag_test.rb +53 -0
  35. data/test/ruby_pocket/web_page_test.rb +68 -0
  36. data/test/support/add_feature_mocker.rb +37 -0
  37. data/test/support/custom_assertions.rb +9 -0
  38. data/test/support/database_test_case.rb +11 -0
  39. data/test/support/default_test_case.rb +9 -0
  40. data/test/support/favorite_factory.rb +14 -0
  41. data/test/support/feature_assertions.rb +22 -0
  42. data/test/support/feature_test_case.rb +32 -0
  43. data/test/support/webmock.rb +3 -0
  44. data/test/test_helper.rb +19 -0
  45. metadata +305 -0
@@ -0,0 +1,33 @@
1
+ module RubyPocket
2
+ HttpError = Class.new RubyPocketError
3
+
4
+ class WebPage
5
+ class << self
6
+ alias :for :new
7
+ end
8
+
9
+ def initialize(url, scrapper = nil)
10
+ fetch_page url, scrapper
11
+ end
12
+
13
+ def title
14
+ @page.title
15
+ end
16
+
17
+ private
18
+
19
+ def fetch_page(url, scrapper)
20
+ @page = (scrapper || default_scrapper).get(url)
21
+ rescue SocketError => e
22
+ raise HttpError, 'Got a socket error'
23
+ rescue Mechanize::ResponseCodeError => e
24
+ raise HttpError, "#{e.response_code} response code"
25
+ end
26
+
27
+ def default_scrapper
28
+ require 'mechanize'
29
+
30
+ Mechanize.new
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,37 @@
1
+ require 'etc'
2
+ require 'ruby_pocket/version'
3
+ require 'ruby_pocket/environment'
4
+
5
+ module RubyPocket
6
+ RubyPocketError = Class.new StandardError
7
+
8
+ class << self
9
+ attr_accessor :environment
10
+
11
+ def environment=(environment)
12
+ @environment = Environment.new(environment)
13
+ end
14
+
15
+ def environment
16
+ self.environment = 'PRODUCTION' unless @environment
17
+ @environment
18
+ end
19
+
20
+ def setup_data_dir
21
+ return unless environment.production?
22
+ return if Dir.exist?(data_dir)
23
+
24
+ Dir.mkdir data_dir
25
+ end
26
+
27
+ def data_dir
28
+ @data_dir ||= File.join(home_dir, '.ruby_pocket')
29
+ end
30
+
31
+ private
32
+
33
+ def home_dir
34
+ Etc.getpwuid.dir
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+ require 'ruby_pocket/cli/options'
3
+
4
+ module RubyPocket
5
+ module Cli
6
+ class OptionsTest < DefaultTestCase
7
+ def test_has_an_action
8
+ options = Options.new
9
+ options.action = :add
10
+
11
+ assert_equal :add, options.action
12
+ end
13
+
14
+ def test_cant_assign_two_subsequent_actions
15
+ options = Options.new
16
+ options.action = :add
17
+
18
+ error = assert_raises(ArgumentError) do
19
+ options.action = :list
20
+ end
21
+
22
+ assert_match %r(list and add), error.message
23
+ end
24
+
25
+ def test_validate_fails_when_has_no_action
26
+ options = Options.new
27
+
28
+ error = assert_raises(ArgumentError) do
29
+ options.validate!
30
+ end
31
+
32
+ assert_match %r(supply an action), error.message
33
+ end
34
+
35
+ def test_validate_succeeds_when_has_an_action
36
+ options = Options.new
37
+ options.action = :add
38
+
39
+ assert_nil options.validate!
40
+ end
41
+
42
+ def test_has_a_values_hash
43
+ options = Options.new
44
+
45
+ assert_equal Hash.new, options.values
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,80 @@
1
+ require 'test_helper'
2
+ require 'minitest/mock'
3
+ require 'ruby_pocket/favorite_creator'
4
+
5
+ module RubyPocket
6
+ class FavoriteCreatorTest < DatabaseTestCase
7
+ def test_does_not_inject_a_persisted_favorite
8
+ persisted_favorite = Favorite.create url: 'http://www.rubytapas.com'
9
+ creator = build_favorite_creator({})
10
+
11
+ error = assert_raises StandardError do
12
+ creator.favorite = persisted_favorite
13
+ end
14
+
15
+ assert_match %r(new favorite), error.message
16
+ end
17
+
18
+ def test_when_no_name_present_in_values_fetches_web_page_from_url
19
+ url = 'http://www.rubytapas.com'
20
+
21
+ values = { name: nil, url: url }
22
+ favorite = Favorite.new
23
+ web_page = web_page_mock(url, page_title: 'Ruby Tapas')
24
+
25
+ creator = build_favorite_creator(values, favorite, web_page)
26
+ creator.save
27
+
28
+ assert web_page.verify
29
+ end
30
+
31
+ def test_when_no_name_present_in_values_fetches_name_from_web_pages_title
32
+ url = 'http://www.rubytapas.com'
33
+
34
+ values = { name: nil, url: url }
35
+ favorite = Favorite.new
36
+ web_page = web_page_mock(url, page_title: 'Ruby Tapas')
37
+
38
+ creator = build_favorite_creator(values, favorite, web_page)
39
+ creator.save
40
+
41
+ assert_equal 'Ruby Tapas', favorite.name
42
+ end
43
+
44
+ def test_does_not_save_favorite_when_values_are_invalid
45
+ favorite = Favorite.new
46
+ creator = build_favorite_creator({}, favorite)
47
+
48
+ error = assert_raises ValidationError do
49
+ assert_not creator.save
50
+ end
51
+
52
+ assert_equal 'url is not present', error.message
53
+ end
54
+
55
+ def test_saves_favorite_when_values_are_valid
56
+ favorite = Favorite.new
57
+ params = { name: 'RubyTapas', url: 'http://www.rubytapas.com' }
58
+ creator = build_favorite_creator(params, favorite)
59
+
60
+ assert creator.save
61
+ assert_not favorite.new?
62
+ end
63
+
64
+ private
65
+
66
+ def build_favorite_creator(values, favorite = nil, web_page = nil)
67
+ FavoriteCreator.new(values).tap do |creator|
68
+ creator.favorite = favorite if favorite
69
+ creator.web_page = web_page if web_page
70
+ end
71
+ end
72
+
73
+ def web_page_mock(url, page_title: 'Ruby Tapas')
74
+ contents = OpenStruct.new(title: page_title)
75
+
76
+ web_page_class = Minitest::Mock.new
77
+ web_page_class.expect :for, contents, [url]
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,98 @@
1
+ require 'test_helper'
2
+ require 'support/favorite_factory'
3
+ require 'ruby_pocket/favorite_query'
4
+
5
+ module RubyPocket
6
+ class FavoriteQueryTest < DatabaseTestCase
7
+ include FavoriteFactory
8
+
9
+ def test_finds_all_favorites
10
+ ruby_flow = create_favorite(url: 'http://www.rubyflow.com')
11
+ ruby_tapas = create_favorite(url: 'http://www.rubytapas.com')
12
+
13
+ favorites = FavoriteQuery.new.all
14
+
15
+ assert_equal [ruby_flow, ruby_tapas], favorites
16
+ end
17
+
18
+ def test_when_no_tag_names_finds_all_favorites
19
+ ruby_flow = create_favorite(url: 'http://www.rubyflow.com')
20
+ ruby_tapas = create_favorite(url: 'http://www.rubytapas.com')
21
+
22
+ favorites = FavoriteQuery.new.where(tag_names: nil).all
23
+
24
+ assert_equal [ruby_flow, ruby_tapas], favorites
25
+ end
26
+
27
+ def test_finds_favorite_by_tag_name
28
+ create_favorite(
29
+ url: 'http://www.rubyflow.com',
30
+ tag_names: %w(ruby)
31
+ )
32
+ microservices = create_favorite(
33
+ url: 'http://martinfowler.com/microservices',
34
+ tag_names: %w(microservices)
35
+ )
36
+
37
+ favorites = FavoriteQuery
38
+ .new
39
+ .where(tag_names: %w[microservices])
40
+ .all
41
+
42
+ assert_equal [microservices], favorites
43
+ end
44
+
45
+ def test_finds_favorite_by_more_than_one_tag_name
46
+ create_favorite(
47
+ url: 'http://www.rubyflow.com',
48
+ tag_names: %w(ruby)
49
+ )
50
+ create_favorite(
51
+ url: 'http://railscasts.com',
52
+ tag_names: %w(screencasts)
53
+ )
54
+ ruby_tapas = create_favorite(
55
+ url: 'http://www.rubytapas.com',
56
+ tag_names: %w(ruby screencasts)
57
+ )
58
+
59
+ favorites = FavoriteQuery
60
+ .new
61
+ .where(tag_names: %w[ruby screencasts])
62
+ .all
63
+
64
+ assert_equal [ruby_tapas], favorites
65
+ end
66
+
67
+ def test_finds_favorite_by_more_than_one_tag_name_with_chained_syntax
68
+ create_favorite(
69
+ url: 'http://www.rubyflow.com',
70
+ tag_names: %w(ruby)
71
+ )
72
+ create_favorite(
73
+ url: 'http://railscasts.com',
74
+ tag_names: %w(screencasts)
75
+ )
76
+ ruby_tapas = create_favorite(
77
+ url: 'http://www.rubytapas.com',
78
+ tag_names: %w(ruby screencasts)
79
+ )
80
+
81
+ favorites = FavoriteQuery
82
+ .new
83
+ .where(tag_names: %w[ruby])
84
+ .where(tag_names: %w[screencasts])
85
+ .all
86
+
87
+ assert_equal [ruby_tapas], favorites
88
+ end
89
+
90
+ def test_fails_when_tag_name_does_not_exist
91
+ error = assert_raises ArgumentError do
92
+ FavoriteQuery.new.where(tag_names: %w[microservices]).all
93
+ end
94
+
95
+ assert_match %r(not found), error.message
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,76 @@
1
+ require 'test_helper'
2
+ require 'support/favorite_factory'
3
+ require 'ruby_pocket/favorite'
4
+
5
+ module RubyPocket
6
+ class FavoriteTest < DatabaseTestCase
7
+ include FavoriteFactory
8
+
9
+ def test_persists_a_favorite
10
+ favorite = create_favorite
11
+
12
+ assert_not favorite.new?
13
+ end
14
+
15
+ def test_url_is_unique
16
+ create_favorite
17
+
18
+ error = assert_raises(Sequel::ValidationFailed) do
19
+ create_favorite
20
+ end
21
+
22
+ assert_match(/url is already taken/, error.message)
23
+ end
24
+
25
+ def test_name_is_trimmed
26
+ values = build_values(name: ' Ruby is Cool ')
27
+ favorite = create_favorite(values)
28
+
29
+ assert_equal 'Ruby is Cool', favorite.name
30
+ end
31
+
32
+ def test_favorite_is_persisted_correctly
33
+ values = build_values
34
+ favorite = create_favorite
35
+
36
+ assert_subset values, favorite.values
37
+ end
38
+
39
+ def test_persists_a_favorite_with_tags
40
+ values = build_values(tag_names: %w(ruby cool))
41
+ favorite = create_favorite(values)
42
+
43
+ assert_not favorite.new?
44
+ assert_equal %w(ruby cool), favorite.tags.map(&:name)
45
+ end
46
+
47
+ def test_persists_a_favorite_without_tags
48
+ favorite = create_favorite
49
+
50
+ assert_empty favorite.tags
51
+ end
52
+
53
+ def test_tags_with_equal_names_are_not_duplicated
54
+ ruby_flow_values = build_values(
55
+ url: 'http://www.rubyflow.com',
56
+ tag_names: %w(Ruby)
57
+ )
58
+ ruby_flow = create_favorite(ruby_flow_values)
59
+
60
+ ruby_tapas_values = build_values(
61
+ url: 'http://www.rubytapas.com',
62
+ tag_names: %w(ruby)
63
+ )
64
+ ruby_tapas = create_favorite(ruby_tapas_values)
65
+
66
+ assert_equal ruby_flow.tags, ruby_tapas.tags
67
+ end
68
+
69
+ def test_favorites_with_tags_are_deleted_without_errors
70
+ values = build_values(tag_names: %w(one two))
71
+ favorite = create_favorite(values)
72
+
73
+ assert favorite.destroy
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+ require 'ruby_pocket/favorite'
3
+
4
+ module RubyPocket
5
+ module Cli
6
+ class AddTest < FeatureTestCase
7
+ def test_adds_a_favorite
8
+ url = 'http://www.rubytapas.com'
9
+ title = 'Ruby Tapas'
10
+
11
+ output = run_command_web_mocked("pocket -a #{url}", url, title)
12
+
13
+ assert_match %r(Ruby Tapas.+created), output.stdout
14
+ assert Favorite.find(name: 'Ruby Tapas')
15
+ end
16
+
17
+ def test_adds_a_favorite_with_name_and_tags
18
+ url = 'http://www.fancyname.com'
19
+
20
+ output = run_command("pocket -a #{url} -n 'Fancy Name' -t ruby")
21
+ added_favorite = Favorite.find(name: 'Fancy Name')
22
+
23
+ assert_match %r(Fancy Name.+created), output.stdout
24
+ assert added_favorite
25
+ assert_equal %w(ruby), added_favorite.tags.map(&:name)
26
+ end
27
+
28
+ private
29
+
30
+ def run_command_web_mocked(command, url, title)
31
+ run_command(
32
+ command,
33
+ MOCK_FEATURE: 'add',
34
+ WEB_MOCK_URL: url,
35
+ WEB_MOCK_PAGE_TITLE: title
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+ require 'support/favorite_factory'
3
+ require 'ruby_pocket/favorite'
4
+
5
+ module RubyPocket
6
+ module Cli
7
+ class DeleteTest < FeatureTestCase
8
+ include FavoriteFactory
9
+
10
+ def test_deletes_one_favorite_by_id
11
+ favorite = create_favorite
12
+
13
+ output = run_command("pocket -d #{favorite.id}")
14
+
15
+ assert_match %r(#{favorite.name}.+deleted), output.stdout
16
+ assert_raises(Sequel::Error) { favorite.reload }
17
+ end
18
+
19
+ def test_deletes_two_favorites_by_id
20
+ favorite_one = create_favorite
21
+ favorite_two = create_favorite(
22
+ name: 'Ruby',
23
+ url: 'http://www.ruby-lang.org'
24
+ )
25
+
26
+ output = run_command("pocket -d #{favorite_one.id},#{favorite_two.id}")
27
+
28
+ assert_match %r(#{favorite_one.name}.+deleted), output.stdout
29
+ assert_match %r(#{favorite_two.name}.+deleted), output.stdout
30
+ assert_raises(Sequel::Error) { favorite_one.reload }
31
+ assert_raises(Sequel::Error) { favorite_two.reload }
32
+ end
33
+
34
+ def test_does_not_delete_favorite_when_not_found
35
+ favorite = create_favorite
36
+
37
+ output = run_command("pocket -d #{favorite.id},1000")
38
+
39
+ assert_match %r(#{favorite.name}.+deleted), output.stdout
40
+ assert_match %r(1000 not found), output.stdout
41
+ assert_raises(Sequel::Error) { favorite.reload }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,75 @@
1
+ require 'test_helper'
2
+ require 'support/favorite_factory'
3
+ require 'ruby_pocket/favorite'
4
+
5
+ module RubyPocket
6
+ module Cli
7
+ class ListTest < FeatureTestCase
8
+ include FavoriteFactory
9
+
10
+ def test_lists_available_favorites_with_id_name_and_tags
11
+ values = build_values(tag_names: %w(ruby))
12
+ favorite = create_favorite(values)
13
+
14
+ output = run_command('pocket -l')
15
+
16
+ assert_shows_favorite favorite, output
17
+ end
18
+
19
+ def test_shows_message_when_has_no_favorites
20
+ output = run_command('pocket -l')
21
+
22
+ assert_match %r(is empty), output.stdout
23
+ end
24
+
25
+ def test_searches_for_favorites_by_tags
26
+ values = {
27
+ name: 'Ruby Tapas',
28
+ url: 'http://www.rubytapas.com',
29
+ tag_names: %w(ruby)
30
+ }
31
+ ruby_tapas_favorite = create_favorite(values)
32
+
33
+ values = {
34
+ name: 'Martin Fowler - Microservices article',
35
+ url: 'http://martinfowler.com/articles/microservices.html',
36
+ tag_names: %w(microservices)
37
+ }
38
+ microservices_favorite = create_favorite(values)
39
+
40
+ output = run_command('pocket -l -t microservices')
41
+
42
+ assert_not_shows_favorite ruby_tapas_favorite, output
43
+ assert_shows_favorite microservices_favorite, output
44
+ end
45
+
46
+ def test_searches_for_favorites_by_more_than_one_tag
47
+ values = {
48
+ name: 'Ruby Tapas',
49
+ url: 'http://www.rubytapas.com',
50
+ tag_names: %w(ruby screencasts)
51
+ }
52
+ ruby_tapas_favorite = create_favorite(values)
53
+
54
+ values = {
55
+ name: 'Ruby Flow',
56
+ url: 'http://www.rubyflow.com',
57
+ tag_names: %w(ruby aggregator)
58
+ }
59
+ ruby_flow_favorite = create_favorite(values)
60
+
61
+ output = run_command('pocket -l -t ruby,screencasts')
62
+
63
+ assert_shows_favorite ruby_tapas_favorite, output
64
+ assert_not_shows_favorite ruby_flow_favorite, output
65
+ end
66
+
67
+ def test_shows_an_error_when_tag_not_found
68
+ output = run_command('pocket -l -t microservices')
69
+
70
+ assert_match %r(Tag.+not found), output.stderr
71
+ assert_empty output.stdout
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,53 @@
1
+ require 'test_helper'
2
+ require 'ruby_pocket/tag'
3
+
4
+ module RubyPocket
5
+ class TagTest < DatabaseTestCase
6
+ def test_tag_name_is_unique
7
+ Tag.create name: 'ruby'
8
+
9
+ error = assert_raises Sequel::ValidationFailed do
10
+ Tag.create name: 'ruby'
11
+ end
12
+
13
+ assert_match 'name is already taken', error.message
14
+ end
15
+
16
+ def test_trims_white_space_from_tag_name
17
+ tag = Tag.create(name: ' Ruby ')
18
+
19
+ assert_equal 'ruby', tag.name
20
+ end
21
+
22
+ def test_downcases_tag_name
23
+ tag = Tag.create(name: 'Ruby')
24
+
25
+ assert_equal 'ruby', tag.name
26
+ end
27
+
28
+ def test_puts_dashes_between_words_on_tag_name
29
+ tag = Tag.create(name: 'Precious Ruby')
30
+
31
+ assert_equal 'precious-ruby', tag.name
32
+ end
33
+
34
+ def test_replaces_non_letter_characters_with_dashes_on_tag_name
35
+ names = ['Precious_Ruby', 'Cool_!#>Precious%$#%%Ruby']
36
+ tags = names.map { |name| Tag.create(name: name) }
37
+
38
+ assert_equal %w(precious-ruby cool-precious-ruby), tags.map(&:name)
39
+ end
40
+
41
+ def test_normalizes_dashes_of_the_tag_name
42
+ tag = Tag.create(name: 'Precious__Ruby')
43
+
44
+ assert_equal 'precious-ruby', tag.name
45
+ end
46
+
47
+ def test_normalizes_spaces_between_words_of_tag_name
48
+ tag = Tag.create(name: 'Cool Precious Ruby')
49
+
50
+ assert_equal 'cool-precious-ruby', tag.name
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+ require 'support/webmock'
3
+ require 'ruby_pocket/web_page'
4
+
5
+ module RubyPocket
6
+ class WebPageTest < DefaultTestCase
7
+ def test_calls_the_scrapper_with_the_url
8
+ url = 'http://www.rubytapas.com'
9
+ scrapper = scrapper_mock(url)
10
+ WebPage.for(url, scrapper)
11
+
12
+ assert scrapper.verify
13
+ end
14
+
15
+ def test_fetches_the_title_from_the_web_page
16
+ url = 'http://www.rubytapas.com'
17
+ scrapper = scrapper_mock(url, 'Ruby Tapas')
18
+ web_page = WebPage.for(url, scrapper)
19
+
20
+ assert_equal 'Ruby Tapas', web_page.title
21
+ end
22
+
23
+ def test_throws_http_error_when_url_not_found
24
+ url = 'http://google.com/does_not_exist'
25
+ stub_request(:any, url).to_return status: 404
26
+
27
+ error = assert_raises(HttpError) do
28
+ WebPage.for url
29
+ end
30
+
31
+ assert_match %r(404), error.message
32
+ end
33
+
34
+ def test_throws_http_error_when_internal_server_error
35
+ url = 'http://throwmea500.com'
36
+ stub_request(:any, url).to_return status: 500
37
+
38
+ error = assert_raises(HttpError) do
39
+ WebPage.for url
40
+ end
41
+
42
+ assert_match %r(500), error.message
43
+ end
44
+
45
+ def test_throws_http_error_url_does_not_exist
46
+ url = 'http://inexistenturl.com'
47
+ stub_request(:any, url).to_raise SocketError
48
+
49
+ error = assert_raises(HttpError) do
50
+ WebPage.for url
51
+ end
52
+
53
+ assert_match %r(socket error), error.message
54
+ end
55
+
56
+ private
57
+
58
+ def scrapper_mock(url, title = nil)
59
+ title ||= 'Ruby Tapas'
60
+
61
+ page = OpenStruct.new(title: title)
62
+
63
+ scrapper = Minitest::Mock.new
64
+ scrapper.expect :get, page, [url]
65
+ scrapper
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,37 @@
1
+ require_relative 'webmock'
2
+
3
+ class AddFeatureMocker
4
+ include WebMock::API
5
+
6
+ def run
7
+ return unless url && page_title
8
+
9
+ stub_request(:any, url).to_return(
10
+ body: html_body,
11
+ status: 200,
12
+ headers: { 'Content-Type': 'text/html' }
13
+ )
14
+ end
15
+
16
+ def url
17
+ ENV['WEB_MOCK_URL']
18
+ end
19
+
20
+ def page_title
21
+ ENV['WEB_MOCK_PAGE_TITLE']
22
+ end
23
+
24
+ def html_body
25
+ <<-HTML
26
+ <!DOCTYPE html>
27
+ <html>
28
+ <head>
29
+ <title>#{page_title}</title>
30
+ </head>
31
+
32
+ <body>
33
+ </body>
34
+ </html>
35
+ HTML
36
+ end
37
+ end