wayfarer 0.4.5 → 0.4.7
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/.github/workflows/lint.yaml +25 -0
- data/.github/workflows/release.yaml +29 -0
- data/.github/workflows/tests.yaml +30 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +5 -0
- data/.vale.ini +5 -0
- data/.yardopts +1 -3
- data/Dockerfile +5 -4
- data/Gemfile +3 -0
- data/Gemfile.lock +107 -102
- data/Rakefile +5 -56
- data/bin/wayfarer +1 -1
- data/docker-compose.yml +20 -9
- data/docs/cookbook/consent_screen.md +2 -2
- data/docs/cookbook/executing_javascript.md +3 -3
- data/docs/cookbook/navigation.md +12 -12
- data/docs/cookbook/querying_html.md +3 -3
- data/docs/cookbook/screenshots.md +2 -2
- data/docs/cookbook/user_agent.md +1 -1
- data/docs/design.md +36 -0
- data/docs/guides/callbacks.md +24 -126
- data/docs/guides/configuration.md +8 -8
- data/docs/guides/handlers.md +60 -0
- data/docs/guides/index.md +1 -0
- data/docs/guides/jobs/error_handling.md +40 -0
- data/docs/guides/jobs.md +99 -31
- data/docs/guides/navigation.md +1 -1
- data/docs/guides/networking/capybara.md +13 -22
- data/docs/guides/networking/custom_adapters.md +82 -41
- data/docs/guides/networking/ferrum.md +4 -4
- data/docs/guides/networking/http.md +9 -13
- data/docs/guides/networking/selenium.md +10 -11
- data/docs/guides/pages.md +76 -10
- data/docs/guides/redis.md +10 -0
- data/docs/guides/routing.md +74 -0
- data/docs/guides/tasks.md +33 -9
- data/docs/guides/tutorial.md +60 -0
- data/docs/guides/user_agents.md +113 -0
- data/docs/index.md +17 -40
- data/docs/reference/cli.md +35 -25
- data/docs/reference/configuration.md +36 -0
- data/lib/wayfarer/base.rb +124 -46
- data/lib/wayfarer/batch_completion.rb +56 -0
- data/lib/wayfarer/callbacks.rb +22 -48
- data/lib/wayfarer/cli/route_printer.rb +71 -57
- data/lib/wayfarer/cli.rb +121 -0
- data/lib/wayfarer/gc.rb +13 -6
- data/lib/wayfarer/handler.rb +15 -7
- data/lib/wayfarer/logging.rb +38 -0
- data/lib/wayfarer/middleware/base.rb +2 -0
- data/lib/wayfarer/middleware/batch_completion.rb +19 -0
- data/lib/wayfarer/middleware/content_type.rb +54 -0
- data/lib/wayfarer/middleware/controller.rb +19 -15
- data/lib/wayfarer/middleware/dedup.rb +16 -13
- data/lib/wayfarer/middleware/dispatch.rb +12 -4
- data/lib/wayfarer/middleware/normalize.rb +12 -11
- data/lib/wayfarer/middleware/redis.rb +15 -0
- data/lib/wayfarer/middleware/router.rb +33 -35
- data/lib/wayfarer/middleware/stage.rb +5 -5
- data/lib/wayfarer/middleware/uri_parser.rb +30 -0
- data/lib/wayfarer/middleware/user_agent.rb +49 -0
- data/lib/wayfarer/networking/capybara.rb +1 -1
- data/lib/wayfarer/networking/context.rb +2 -2
- data/lib/wayfarer/networking/ferrum.rb +2 -2
- data/lib/wayfarer/networking/follow.rb +12 -6
- data/lib/wayfarer/networking/http.rb +1 -1
- data/lib/wayfarer/networking/pool.rb +17 -12
- data/lib/wayfarer/networking/selenium.rb +3 -3
- data/lib/wayfarer/networking/strategy.rb +2 -2
- data/lib/wayfarer/page.rb +36 -14
- data/lib/wayfarer/parsing/xml.rb +6 -6
- data/lib/wayfarer/parsing.rb +24 -0
- data/lib/wayfarer/redis/barrier.rb +13 -21
- data/lib/wayfarer/redis/counter.rb +19 -9
- data/lib/wayfarer/redis/pool.rb +1 -1
- data/lib/wayfarer/redis/resettable.rb +19 -0
- data/lib/wayfarer/routing/dsl.rb +1 -0
- data/lib/wayfarer/routing/matchers/path.rb +4 -2
- data/lib/wayfarer/routing/root_route.rb +5 -1
- data/lib/wayfarer/routing/route.rb +4 -14
- data/lib/wayfarer/stringify.rb +22 -30
- data/lib/wayfarer/task.rb +12 -18
- data/lib/wayfarer.rb +29 -2
- data/mkdocs.yml +52 -7
- data/rake/docs.rake +26 -0
- data/rake/lint.rake +105 -0
- data/rake/release.rake +29 -0
- data/rake/tests.rake +28 -0
- data/requirements.txt +1 -1
- data/spec/base_spec.rb +140 -160
- data/spec/batch_completion_spec.rb +104 -0
- data/spec/cli/job_spec.rb +19 -23
- data/spec/cli/routing_spec.rb +101 -0
- data/spec/cli/version_spec.rb +1 -1
- data/spec/factories/task.rb +7 -1
- data/spec/fixtures/dummy_job.rb +5 -3
- data/spec/gc_spec.rb +8 -50
- data/spec/handler_spec.rb +1 -1
- data/spec/integration/callbacks_spec.rb +157 -45
- data/spec/integration/content_type_spec.rb +145 -0
- data/spec/integration/gc_spec.rb +44 -0
- data/spec/integration/handler_spec.rb +66 -0
- data/spec/integration/page_spec.rb +44 -29
- data/spec/integration/params_spec.rb +33 -25
- data/spec/integration/parsing_spec.rb +125 -0
- data/spec/integration/routing_spec.rb +18 -0
- data/spec/integration/stage_spec.rb +27 -20
- data/spec/middleware/batch_completion_spec.rb +34 -0
- data/spec/middleware/chain_spec.rb +8 -8
- data/spec/middleware/content_type_spec.rb +86 -0
- data/spec/middleware/controller_spec.rb +5 -5
- data/spec/middleware/dedup_spec.rb +38 -55
- data/spec/middleware/dispatch_spec.rb +23 -7
- data/spec/middleware/normalize_spec.rb +44 -13
- data/spec/middleware/router_spec.rb +29 -30
- data/spec/middleware/stage_spec.rb +8 -8
- data/spec/middleware/uri_parser_spec.rb +53 -0
- data/spec/middleware/{fetch_spec.rb → user_agent_spec.rb} +28 -27
- data/spec/networking/context_spec.rb +17 -0
- data/spec/networking/follow_spec.rb +2 -2
- data/spec/networking/pool_spec.rb +5 -5
- data/spec/networking/strategy.rb +2 -2
- data/spec/page_spec.rb +42 -20
- data/spec/parsing/xml_spec.rb +11 -12
- data/spec/redis/barrier_spec.rb +8 -48
- data/spec/redis/counter_spec.rb +13 -1
- data/spec/redis/pool_spec.rb +1 -1
- data/spec/spec_helpers.rb +27 -16
- data/spec/support/test_app.rb +8 -0
- data/spec/task_spec.rb +3 -24
- data/spec/wayfarer_spec.rb +1 -1
- data/wayfarer.gemspec +4 -3
- metadata +61 -51
- data/.github/workflows/ci.yaml +0 -32
- data/docs/guides/error_handling.md +0 -31
- data/docs/guides/networking.md +0 -94
- data/docs/guides/performance.md +0 -130
- data/docs/guides/reliability.md +0 -41
- data/docs/guides/routing/steering.md +0 -30
- data/docs/reference/api/base.md +0 -48
- data/docs/reference/configuration_keys.md +0 -42
- data/docs/reference/environment_variables.md +0 -83
- data/lib/wayfarer/cli/base.rb +0 -45
- data/lib/wayfarer/cli/generate.rb +0 -17
- data/lib/wayfarer/cli/job.rb +0 -56
- data/lib/wayfarer/cli/route.rb +0 -29
- data/lib/wayfarer/cli/runner.rb +0 -34
- data/lib/wayfarer/cli/templates/Gemfile.tt +0 -5
- data/lib/wayfarer/cli/templates/job.rb.tt +0 -10
- data/lib/wayfarer/config/capybara.rb +0 -10
- data/lib/wayfarer/config/ferrum.rb +0 -11
- data/lib/wayfarer/config/networking.rb +0 -26
- data/lib/wayfarer/config/redis.rb +0 -14
- data/lib/wayfarer/config/root.rb +0 -11
- data/lib/wayfarer/config/selenium.rb +0 -21
- data/lib/wayfarer/config/strconv.rb +0 -45
- data/lib/wayfarer/config/struct.rb +0 -72
- data/lib/wayfarer/middleware/fetch.rb +0 -56
- data/lib/wayfarer/redis/connection.rb +0 -13
- data/lib/wayfarer/redis/version.rb +0 -19
- data/lib/wayfarer/routing/router.rb +0 -28
- data/spec/callbacks_spec.rb +0 -102
- data/spec/cli/generate_spec.rb +0 -39
- data/spec/config/capybara_spec.rb +0 -18
- data/spec/config/ferrum_spec.rb +0 -24
- data/spec/config/networking_spec.rb +0 -73
- data/spec/config/redis_spec.rb +0 -32
- data/spec/config/root_spec.rb +0 -31
- data/spec/config/selenium_spec.rb +0 -56
- data/spec/config/strconv_spec.rb +0 -58
- data/spec/config/struct_spec.rb +0 -66
- data/spec/integration/steering_spec.rb +0 -57
- data/spec/redis/version_spec.rb +0 -13
- data/spec/routing/router_spec.rb +0 -24
@@ -5,16 +5,31 @@ require "spec_helpers"
|
|
5
5
|
describe "Pages" do
|
6
6
|
let(:url) { test_app_path("git-scm.com/book/en/v2.html") }
|
7
7
|
|
8
|
-
|
8
|
+
before do
|
9
|
+
stub_const("DummyJob", Class.new(ActiveJob::Base).include(Wayfarer::Base))
|
10
|
+
stub_const("DummyHandler", Class.new.include(Wayfarer::Handler))
|
11
|
+
end
|
12
|
+
|
13
|
+
shared_examples "executes" do
|
9
14
|
specify do
|
10
|
-
|
11
|
-
|
15
|
+
DummyJob.crawl(url)
|
16
|
+
perform_enqueued_jobs
|
17
|
+
assert_performed_jobs 1
|
18
|
+
expect(enqueued_jobs).to be_empty
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "page content" do
|
23
|
+
before do
|
24
|
+
DummyJob.class_eval do
|
12
25
|
include RSpec::Matchers
|
26
|
+
extend SpecHelpers
|
27
|
+
include SpecHelpers
|
13
28
|
|
14
|
-
route
|
29
|
+
route.host test_app_host, to: :index
|
15
30
|
|
16
31
|
def index
|
17
|
-
expect(page.url).to eq("
|
32
|
+
expect(page.url).to eq(test_app_path("git-scm.com/book/en/v2.html"))
|
18
33
|
expect(page.status_code).to be(200)
|
19
34
|
expect(page.body).not_to be_empty
|
20
35
|
expect(page.headers.count).to be(9)
|
@@ -24,39 +39,39 @@ describe "Pages" do
|
|
24
39
|
expect(page.meta.links.external.count).to be(55)
|
25
40
|
end
|
26
41
|
end
|
27
|
-
|
28
|
-
self.class::DummyJob.crawl(url)
|
29
|
-
perform_enqueued_jobs
|
30
42
|
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe Wayfarer::Handler do
|
34
|
-
specify do
|
35
|
-
class self.class::DummyJob < Wayfarer::Base
|
36
|
-
extend SpecHelpers
|
37
43
|
|
38
|
-
|
44
|
+
it_behaves_like "executes"
|
45
|
+
end
|
39
46
|
|
40
|
-
|
41
|
-
|
47
|
+
describe "page content with handler" do
|
48
|
+
before do
|
49
|
+
DummyJob.class_eval do
|
50
|
+
include RSpec::Matchers
|
51
|
+
include SpecHelpers
|
42
52
|
|
43
|
-
|
53
|
+
route.to :index
|
44
54
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
55
|
+
def index
|
56
|
+
expect(page.url).to eq(test_app_path("git-scm.com/book/en/v2.html"))
|
57
|
+
expect(page.status_code).to be(200)
|
58
|
+
expect(page.body).not_to be_empty
|
59
|
+
expect(page.headers.count).to be(9)
|
50
60
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
61
|
+
expect(page.meta.links.all.count).to be(157)
|
62
|
+
expect(page.meta.links.internal.count).to be(102)
|
63
|
+
expect(page.meta.links.external.count).to be(55)
|
55
64
|
end
|
56
65
|
end
|
57
66
|
|
58
|
-
|
59
|
-
|
67
|
+
DummyHandler.class_eval do
|
68
|
+
extend SpecHelpers
|
69
|
+
include SpecHelpers
|
70
|
+
|
71
|
+
route.host test_app_host, to: DummyHandler
|
72
|
+
end
|
60
73
|
end
|
74
|
+
|
75
|
+
it_behaves_like "executes"
|
61
76
|
end
|
62
77
|
end
|
@@ -5,52 +5,60 @@ require "spec_helpers"
|
|
5
5
|
describe "URL parameters" do
|
6
6
|
let(:url) { test_app_path("git-scm.com/book/en/v2.html") }
|
7
7
|
|
8
|
-
|
8
|
+
before do
|
9
|
+
stub_const("DummyJob", Class.new(ActiveJob::Base).include(Wayfarer::Base))
|
10
|
+
stub_const("DummyHandler", Class.new.include(Wayfarer::Handler))
|
11
|
+
end
|
12
|
+
|
13
|
+
shared_examples "executes" do
|
9
14
|
specify do
|
10
|
-
|
15
|
+
DummyJob.crawl(url)
|
16
|
+
perform_enqueued_jobs
|
17
|
+
assert_performed_jobs 1
|
18
|
+
expect(enqueued_jobs).to be_empty
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "path pattern matching" do
|
23
|
+
before do
|
24
|
+
DummyJob.class_eval do
|
11
25
|
extend SpecHelpers
|
12
26
|
include RSpec::Matchers
|
13
27
|
|
14
|
-
route do
|
15
|
-
|
16
|
-
path "git-scm.com/book/:lang/:file"
|
17
|
-
end
|
28
|
+
route.to :index, host: test_app_host do
|
29
|
+
path "git-scm.com/book/:lang/:file"
|
18
30
|
end
|
19
31
|
|
20
32
|
def index
|
21
33
|
expect(params).to eq("lang" => "en", "file" => "v2.html")
|
22
34
|
end
|
23
35
|
end
|
24
|
-
|
25
|
-
self.class::DummyJob.crawl(url)
|
26
|
-
perform_enqueued_jobs
|
27
36
|
end
|
37
|
+
|
38
|
+
it_behaves_like "executes"
|
28
39
|
end
|
29
40
|
|
30
|
-
describe
|
31
|
-
|
32
|
-
|
41
|
+
describe "path pattern matching with handler" do
|
42
|
+
before do
|
43
|
+
DummyJob.class_eval do
|
33
44
|
extend SpecHelpers
|
34
45
|
|
35
|
-
route do
|
36
|
-
|
37
|
-
path "git-scm.com/book/:lang/:file"
|
38
|
-
end
|
46
|
+
route.to DummyHandler, host: test_app_host do
|
47
|
+
path "git-scm.com/book/:lang/:file"
|
39
48
|
end
|
49
|
+
end
|
40
50
|
|
41
|
-
|
42
|
-
|
51
|
+
DummyHandler.class_eval do
|
52
|
+
include RSpec::Matchers
|
43
53
|
|
44
|
-
|
54
|
+
route.to :index
|
45
55
|
|
46
|
-
|
47
|
-
|
48
|
-
end
|
56
|
+
def index
|
57
|
+
expect(params).to eq("lang" => "en", "file" => "v2.html")
|
49
58
|
end
|
50
59
|
end
|
51
|
-
|
52
|
-
self.class::DummyJob.crawl(url)
|
53
|
-
perform_enqueued_jobs
|
54
60
|
end
|
55
61
|
end
|
62
|
+
|
63
|
+
it_behaves_like "executes"
|
56
64
|
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helpers"
|
4
|
+
|
5
|
+
describe "Response body parsing", redis: true do
|
6
|
+
before do
|
7
|
+
stub_const("DummyJob", Class.new(ActiveJob::Base).include(Wayfarer::Base))
|
8
|
+
stub_const("DummyHandler", Class.new.include(Wayfarer::Handler))
|
9
|
+
end
|
10
|
+
|
11
|
+
shared_examples "executes" do
|
12
|
+
specify do
|
13
|
+
DummyJob.crawl(url)
|
14
|
+
perform_enqueued_jobs
|
15
|
+
assert_performed_jobs 1
|
16
|
+
expect(enqueued_jobs).to be_empty
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with XML" do
|
21
|
+
let(:url) { test_app_path("xml/dummy.xml") }
|
22
|
+
|
23
|
+
before do
|
24
|
+
DummyJob.class_eval do
|
25
|
+
include RSpec::Matchers
|
26
|
+
|
27
|
+
route.to :index
|
28
|
+
|
29
|
+
def index
|
30
|
+
expect(page.doc).to be_a(Nokogiri::XML::Document)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it_behaves_like "executes"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with HTML" do
|
39
|
+
let(:url) { test_app_path("finders.html") }
|
40
|
+
|
41
|
+
before do
|
42
|
+
DummyJob.class_eval do
|
43
|
+
include RSpec::Matchers
|
44
|
+
|
45
|
+
route.to :index
|
46
|
+
|
47
|
+
def index
|
48
|
+
expect(page.doc).to be_a(Nokogiri::HTML::Document)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it_behaves_like "executes"
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with JSON" do
|
57
|
+
let(:url) { test_app_path("json/dummy.json") }
|
58
|
+
|
59
|
+
before do
|
60
|
+
DummyJob.class_eval do
|
61
|
+
include RSpec::Matchers
|
62
|
+
|
63
|
+
route.to :index
|
64
|
+
|
65
|
+
def index
|
66
|
+
expect(page.doc).to be_a(Hash)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it_behaves_like "executes"
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "custom Content-Type parsers" do
|
75
|
+
context "with registered Content-Types" do
|
76
|
+
let(:parser) do
|
77
|
+
Class.new do
|
78
|
+
def self.parse(_body)
|
79
|
+
:ok
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
let(:parser_with_options) do
|
85
|
+
Class.new do
|
86
|
+
def self.parse(_body, options)
|
87
|
+
options
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
before do
|
93
|
+
Wayfarer::Parsing.registry["foo/bar"] = parser
|
94
|
+
Wayfarer::Parsing.registry["bar/qux"] = [parser_with_options, :ok]
|
95
|
+
end
|
96
|
+
|
97
|
+
after do
|
98
|
+
Wayfarer::Parsing.registry.delete("foo/bar")
|
99
|
+
Wayfarer::Parsing.registry.delete("bar/qux")
|
100
|
+
end
|
101
|
+
|
102
|
+
before do
|
103
|
+
DummyJob.class_eval do
|
104
|
+
route.to :index
|
105
|
+
|
106
|
+
def index
|
107
|
+
page.doc
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def perform(content_type)
|
113
|
+
DummyJob.new.perform(
|
114
|
+
build(:task, url: test_app_path("response_header/Content-Type/#{content_type}"))
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
118
|
+
specify do
|
119
|
+
expect(perform("foo/bar")).to be(:ok)
|
120
|
+
expect(perform("bar/qux")).to be(:ok)
|
121
|
+
expect(perform("image/jpeg")).to be(nil)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helpers"
|
4
|
+
|
5
|
+
describe "Routing" do
|
6
|
+
let(:task) { build(:task) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_const("DummyJob", Class.new(ActiveJob::Base).include(Wayfarer::Base))
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "custom routing" do
|
13
|
+
before do
|
14
|
+
DummyJob.class_eval do
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,50 +2,57 @@
|
|
2
2
|
|
3
3
|
require "spec_helpers"
|
4
4
|
|
5
|
-
describe "Staging" do
|
5
|
+
describe "Staging", redis: true do
|
6
6
|
let(:url) { test_app_path("git-scm.com/book/en/v2.html") }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
before do
|
9
|
+
stub_const("DummyJob", Class.new(ActiveJob::Base).include(Wayfarer::Base))
|
10
|
+
stub_const("DummyHandler", Class.new.include(Wayfarer::Handler))
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "staging URLs" do
|
14
|
+
before do
|
15
|
+
DummyJob.class_eval do
|
11
16
|
extend SpecHelpers
|
12
17
|
|
13
|
-
route
|
18
|
+
route.host test_app_host, to: :index
|
14
19
|
|
15
20
|
def index
|
16
21
|
stage page.meta.links.all
|
17
22
|
end
|
18
23
|
end
|
24
|
+
end
|
19
25
|
|
26
|
+
specify do
|
20
27
|
expect {
|
21
|
-
|
28
|
+
DummyJob.crawl(url)
|
22
29
|
perform_enqueued_jobs
|
23
|
-
}.to change { enqueued_jobs.size }.by(
|
30
|
+
}.to change { enqueued_jobs.size }.by(157)
|
24
31
|
end
|
25
32
|
end
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
context "with handler" do
|
35
|
+
before do
|
36
|
+
DummyJob.class_eval do
|
30
37
|
extend SpecHelpers
|
31
38
|
|
32
|
-
route
|
33
|
-
|
34
|
-
end
|
39
|
+
route.host test_app_host, to: DummyHandler
|
40
|
+
end
|
35
41
|
|
36
|
-
|
37
|
-
|
42
|
+
DummyHandler.class_eval do
|
43
|
+
route.to :index
|
38
44
|
|
39
|
-
|
40
|
-
|
41
|
-
end
|
45
|
+
def index
|
46
|
+
stage page.meta.links.all
|
42
47
|
end
|
43
48
|
end
|
49
|
+
end
|
44
50
|
|
51
|
+
specify do
|
45
52
|
expect {
|
46
|
-
|
53
|
+
DummyJob.crawl(url)
|
47
54
|
perform_enqueued_jobs
|
48
|
-
}.to change { enqueued_jobs.size }.by(
|
55
|
+
}.to change { enqueued_jobs.size }.by(157)
|
49
56
|
end
|
50
57
|
end
|
51
58
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helpers"
|
4
|
+
|
5
|
+
describe Wayfarer::Middleware::BatchCompletion, "#call" do
|
6
|
+
let(:task) { build(:task) }
|
7
|
+
let(:job) { double(exception_executions: exception_executions) }
|
8
|
+
let(:exception_executions) { {} }
|
9
|
+
subject(:batch_completion) { described_class.new }
|
10
|
+
|
11
|
+
before { task[:job] = job }
|
12
|
+
|
13
|
+
it "assigns cloned exception_executions" do
|
14
|
+
expect {
|
15
|
+
batch_completion.call(task)
|
16
|
+
}.to change {
|
17
|
+
task[:initial_exception_executions]
|
18
|
+
}.from(nil).to(exception_executions)
|
19
|
+
|
20
|
+
expect(task[:initial_exception_executions]).not_to be(exception_executions)
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when already assigned" do
|
24
|
+
before { task[:initial_exception_executions] = Object.new }
|
25
|
+
|
26
|
+
specify do
|
27
|
+
expect { |spy| batch_completion.call(task, &spy) }.to yield_control
|
28
|
+
end
|
29
|
+
|
30
|
+
it "doesn't assign exception_executions" do
|
31
|
+
expect { batch_completion.call(task) }.not_to(change { task[:initial_exception_executions] })
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -65,11 +65,11 @@ describe Wayfarer::Middleware::Chain do
|
|
65
65
|
describe "Return value" do
|
66
66
|
let(:middlewares) do
|
67
67
|
[build(:middleware, receiver: lambda do |task, &block|
|
68
|
-
task
|
68
|
+
task[:foobar] = 42
|
69
69
|
block.call
|
70
70
|
end),
|
71
71
|
build(:middleware, receiver: lambda do |task|
|
72
|
-
task
|
72
|
+
task[:foobar] *= 1337
|
73
73
|
end)]
|
74
74
|
end
|
75
75
|
|
@@ -81,16 +81,16 @@ describe Wayfarer::Middleware::Chain do
|
|
81
81
|
describe "Metadata" do
|
82
82
|
let(:first) do
|
83
83
|
build(:middleware, receiver: lambda do |task, &block|
|
84
|
-
task
|
84
|
+
task[:foobar] = 42
|
85
85
|
block.call
|
86
|
-
task
|
86
|
+
task[:barqux] = 1337
|
87
87
|
end)
|
88
88
|
end
|
89
89
|
|
90
90
|
let(:last) do
|
91
91
|
build(:middleware, receiver: lambda do |task|
|
92
|
-
raise unless task
|
93
|
-
raise if task
|
92
|
+
raise unless task[:foobar] == 42
|
93
|
+
raise if task[:barqux]
|
94
94
|
end)
|
95
95
|
end
|
96
96
|
|
@@ -101,8 +101,8 @@ describe Wayfarer::Middleware::Chain do
|
|
101
101
|
chain.call(task)
|
102
102
|
}.not_to raise_error
|
103
103
|
|
104
|
-
expect(task
|
105
|
-
expect(task
|
104
|
+
expect(task[:foobar]).to be(42)
|
105
|
+
expect(task[:barqux]).to be(1337)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helpers"
|
4
|
+
|
5
|
+
describe Wayfarer::Middleware::ContentType do
|
6
|
+
let(:content_type) { "text/html" }
|
7
|
+
let(:task) { build(:task) }
|
8
|
+
let(:page) { build(:page, headers: { "Content-Type" => content_type }) }
|
9
|
+
|
10
|
+
describe "#call" do
|
11
|
+
subject { Class.new(described_class).include(described_class::API).new }
|
12
|
+
|
13
|
+
before do
|
14
|
+
task[:page] = page
|
15
|
+
task[:controller] = subject
|
16
|
+
end
|
17
|
+
|
18
|
+
before { subject.class.content_type "text/html" }
|
19
|
+
|
20
|
+
context "with permitted Content-Type" do
|
21
|
+
it "yields" do
|
22
|
+
expect { |spy| subject.call(task, &spy) }.to yield_control
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when permitted Content-Type has parameters" do
|
27
|
+
let(:page) { build(:page, headers: { "Content-Type" => "#{content_type}; charset=UTF-" }) }
|
28
|
+
|
29
|
+
it "yields" do
|
30
|
+
expect { |spy| subject.call(task, &spy) }.to yield_control
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with forbidden Content-Type" do
|
35
|
+
let(:content_type) { "application/json" }
|
36
|
+
|
37
|
+
it "does not yield" do
|
38
|
+
expect { |spy| subject.call(task, &spy) }.not_to yield_control
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with permitted Regexp Content-Type" do
|
43
|
+
before do
|
44
|
+
subject.class.content_type(/text/)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "yields" do
|
48
|
+
expect { |spy| subject.call(task, &spy) }.to yield_control
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe described_class::API do
|
54
|
+
subject(:controller) do
|
55
|
+
Struct.new(:task).include(described_class).new(task)
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "::allowed_content_types" do
|
59
|
+
describe "index" do
|
60
|
+
subject { controller.class.allowed_content_types[:index] }
|
61
|
+
|
62
|
+
it { is_expected.to be_empty }
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "patterns" do
|
66
|
+
subject { controller.class.allowed_content_types[:patterns] }
|
67
|
+
|
68
|
+
it { is_expected.to be_empty }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#content_type" do
|
73
|
+
it "allows Content-Types" do
|
74
|
+
controller.class.content_type(content_type)
|
75
|
+
|
76
|
+
expect(controller.class.allowed_content_types[:index][content_type]).to be(true)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "allows Content-Type patterns" do
|
80
|
+
controller.class.content_type(/text/)
|
81
|
+
|
82
|
+
expect(controller.class.allowed_content_types[:patterns]).to contain_exactly(/text/)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -54,28 +54,28 @@ describe Wayfarer::Middleware::Controller do
|
|
54
54
|
it "assigns itself" do
|
55
55
|
expect {
|
56
56
|
subject.call(task)
|
57
|
-
}.to change { task
|
57
|
+
}.to change { task[:job] }.to(subject)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
context "with job assigned" do
|
62
|
-
before { task
|
62
|
+
before { task[:job] = Object.new }
|
63
63
|
|
64
64
|
it "does not override the job" do
|
65
65
|
expect {
|
66
66
|
subject.call(task)
|
67
|
-
}.not_to(change { task
|
67
|
+
}.not_to(change { task[:job] })
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
71
|
it "assigns itself as controller" do
|
72
72
|
expect {
|
73
73
|
subject.call(task)
|
74
|
-
}.to change { task
|
74
|
+
}.to change { task[:controller] }.to(subject)
|
75
75
|
end
|
76
76
|
|
77
77
|
it "calls the chain" do
|
78
|
-
expect(subject.chain).to receive(:call)
|
78
|
+
expect(subject.class.chain).to receive(:call)
|
79
79
|
subject.call(task)
|
80
80
|
end
|
81
81
|
|