startback-jobs 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -3
  3. data/README.md +13 -0
  4. data/lib/startback/audit/prometheus.rb +87 -0
  5. data/lib/startback/audit/shared.rb +17 -0
  6. data/lib/startback/audit/trailer.rb +129 -0
  7. data/lib/startback/audit.rb +3 -0
  8. data/lib/startback/caching/entity_cache.rb +157 -0
  9. data/lib/startback/caching/no_store.rb +28 -0
  10. data/lib/startback/caching/store.rb +34 -0
  11. data/lib/startback/context/h_factory.rb +43 -0
  12. data/lib/startback/context/middleware.rb +53 -0
  13. data/lib/startback/context.rb +122 -0
  14. data/lib/startback/errors.rb +197 -0
  15. data/lib/startback/event/agent.rb +84 -0
  16. data/lib/startback/event/bus/bunny/async.rb +162 -0
  17. data/lib/startback/event/bus/bunny.rb +1 -0
  18. data/lib/startback/event/bus/memory/async.rb +45 -0
  19. data/lib/startback/event/bus/memory/sync.rb +35 -0
  20. data/lib/startback/event/bus/memory.rb +2 -0
  21. data/lib/startback/event/bus.rb +100 -0
  22. data/lib/startback/event/engine.rb +94 -0
  23. data/lib/startback/event/ext/context.rb +5 -0
  24. data/lib/startback/event/ext/operation.rb +13 -0
  25. data/lib/startback/event.rb +47 -0
  26. data/lib/startback/ext/date_time.rb +9 -0
  27. data/lib/startback/ext/time.rb +9 -0
  28. data/lib/startback/ext.rb +2 -2
  29. data/lib/startback/model.rb +6 -0
  30. data/lib/startback/operation/error_operation.rb +19 -0
  31. data/lib/startback/operation/multi_operation.rb +28 -0
  32. data/lib/startback/operation.rb +78 -0
  33. data/lib/startback/services.rb +11 -0
  34. data/lib/startback/support/data_object.rb +71 -0
  35. data/lib/startback/support/env.rb +41 -0
  36. data/lib/startback/support/fake_logger.rb +18 -0
  37. data/lib/startback/support/hooks.rb +48 -0
  38. data/lib/startback/support/log_formatter.rb +34 -0
  39. data/lib/startback/support/logger.rb +34 -0
  40. data/lib/startback/support/operation_runner.rb +150 -0
  41. data/lib/startback/support/robustness.rb +157 -0
  42. data/lib/startback/support/transaction_manager.rb +25 -0
  43. data/lib/startback/support/transaction_policy.rb +33 -0
  44. data/lib/startback/support/world.rb +54 -0
  45. data/lib/startback/support.rb +26 -0
  46. data/lib/startback/version.rb +8 -0
  47. data/lib/startback/web/api.rb +99 -0
  48. data/lib/startback/web/auto_caching.rb +85 -0
  49. data/lib/startback/web/catch_all.rb +52 -0
  50. data/lib/startback/web/cors_headers.rb +80 -0
  51. data/lib/startback/web/health_check.rb +49 -0
  52. data/lib/startback/web/magic_assets/ng_html_transformer.rb +80 -0
  53. data/lib/startback/web/magic_assets/rake_tasks.rb +64 -0
  54. data/lib/startback/web/magic_assets.rb +98 -0
  55. data/lib/startback/web/middleware.rb +13 -0
  56. data/lib/startback/web/prometheus.rb +16 -0
  57. data/lib/startback/web/shield.rb +58 -0
  58. data/lib/startback.rb +43 -0
  59. data/spec/spec_helper.rb +33 -26
  60. data/spec/unit/audit/test_prometheus.rb +72 -0
  61. data/spec/unit/audit/test_trailer.rb +105 -0
  62. data/spec/unit/caching/test_entity_cache.rb +136 -0
  63. data/spec/unit/context/test_abstraction_factory.rb +64 -0
  64. data/spec/unit/context/test_dup.rb +42 -0
  65. data/spec/unit/context/test_fork.rb +37 -0
  66. data/spec/unit/context/test_h_factory.rb +31 -0
  67. data/spec/unit/context/test_middleware.rb +45 -0
  68. data/spec/unit/context/test_with_world.rb +20 -0
  69. data/spec/unit/context/test_world.rb +17 -0
  70. data/spec/unit/event/bus/memory/test_async.rb +43 -0
  71. data/spec/unit/event/bus/memory/test_sync.rb +43 -0
  72. data/spec/unit/support/hooks/test_after_hook.rb +54 -0
  73. data/spec/unit/support/hooks/test_before_hook.rb +54 -0
  74. data/spec/unit/support/operation_runner/test_around_run.rb +156 -0
  75. data/spec/unit/support/operation_runner/test_before_after_call.rb +48 -0
  76. data/spec/unit/support/test_data_object.rb +156 -0
  77. data/spec/unit/support/test_env.rb +75 -0
  78. data/spec/unit/support/test_robusteness.rb +229 -0
  79. data/spec/unit/support/test_transaction_manager.rb +64 -0
  80. data/spec/unit/support/test_world.rb +72 -0
  81. data/spec/unit/test_event.rb +62 -0
  82. data/spec/unit/test_operation.rb +55 -0
  83. data/spec/unit/test_support.rb +40 -0
  84. data/spec/unit/web/fixtures/assets/app/hello.es6 +4 -0
  85. data/spec/unit/web/fixtures/assets/app/hello.html +1 -0
  86. data/spec/unit/web/fixtures/assets/index.es6 +1 -0
  87. data/spec/unit/web/test_api.rb +82 -0
  88. data/spec/unit/web/test_auto_caching.rb +81 -0
  89. data/spec/unit/web/test_catch_all.rb +77 -0
  90. data/spec/unit/web/test_cors_headers.rb +88 -0
  91. data/spec/unit/web/test_healthcheck.rb +59 -0
  92. data/spec/unit/web/test_magic_assets.rb +82 -0
  93. data/tasks/test.rake +1 -0
  94. metadata +94 -31
  95. data/lib/startback/ext/support/operation_runner.rb +0 -17
  96. data/lib/startback/ext/web/api.rb +0 -12
  97. data/lib/startback/jobs/agent.rb +0 -15
  98. data/lib/startback/jobs/api.rb +0 -12
  99. data/lib/startback/jobs/event/job_created.rb +0 -8
  100. data/lib/startback/jobs/event/job_ran.rb +0 -8
  101. data/lib/startback/jobs/event.rb +0 -8
  102. data/lib/startback/jobs/model/job.rb +0 -35
  103. data/lib/startback/jobs/model.rb +0 -12
  104. data/lib/startback/jobs/operation/create_job.rb +0 -37
  105. data/lib/startback/jobs/operation/run_job.rb +0 -35
  106. data/lib/startback/jobs/operation.rb +0 -8
  107. data/lib/startback/jobs/services.rb +0 -25
  108. data/lib/startback/jobs/support/job_result/embedded.rb +0 -15
  109. data/lib/startback/jobs/support/job_result/not_ready.rb +0 -15
  110. data/lib/startback/jobs/support/job_result/redirect.rb +0 -32
  111. data/lib/startback/jobs/support/job_result.rb +0 -31
  112. data/lib/startback/jobs/support.rb +0 -1
  113. data/lib/startback/jobs.fio +0 -44
  114. data/lib/startback/jobs.rb +0 -23
  115. data/spec/unit/api/test_job_result.rb +0 -121
  116. data/spec/unit/model/test_job.rb +0 -23
  117. data/spec/unit/operation/test_create_job.rb +0 -42
  118. data/spec/unit/operation/test_run_job.rb +0 -37
  119. data/spec/unit/test_finitio_schema.rb +0 -20
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ module Startback
3
+ module Support
4
+ describe TransactionManager do
5
+ subject do
6
+ TransactionManager.new(db).call(nil, op) do
7
+ op.call
8
+ end
9
+ end
10
+
11
+ class FakeDatabase
12
+ def initialize
13
+ @called = false
14
+ end
15
+ attr_reader :called
16
+
17
+ def transaction
18
+ @called = true
19
+ yield
20
+ end
21
+ end
22
+
23
+ let(:db) do
24
+ FakeDatabase.new
25
+ end
26
+
27
+ context 'when called with a default operation' do
28
+ class OperationNotManagingTransactions < Startback::Operation
29
+ def call
30
+ 12
31
+ end
32
+ end
33
+
34
+ let(:op) do
35
+ OperationNotManagingTransactions.new
36
+ end
37
+
38
+ it 'calls db.transaction' do
39
+ expect(subject).to eql(12)
40
+ expect(db.called).to eql(true)
41
+ end
42
+ end
43
+
44
+ context 'when called with an operation that manages the transactions itself' do
45
+ class OperationManagingTransactions < Startback::Operation
46
+ self.transaction_policy = :within_call
47
+
48
+ def call
49
+ 12
50
+ end
51
+ end
52
+
53
+ let(:op) do
54
+ OperationManagingTransactions.new
55
+ end
56
+
57
+ it 'calls db.transaction' do
58
+ expect(subject).to eql(12)
59
+ expect(db.called).to eql(false)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ module Support
5
+ describe World do
6
+
7
+ let(:world) do
8
+ World.new
9
+ end
10
+
11
+ describe 'with' do
12
+ subject do
13
+ world.with(foo: :bar, bar: :baz)
14
+ end
15
+
16
+ it 'returns a new world instance' do
17
+ expect(subject).to be_a(World)
18
+ expect(subject).not_to be(world)
19
+ end
20
+
21
+ it 'gives access to those variables' do
22
+ expect(subject.foo).to eql(:bar)
23
+ expect(subject[:bar]).to eql(:baz)
24
+ end
25
+ end
26
+
27
+ describe 'dup' do
28
+ let(:world) do
29
+ World.new(foo: :bar)
30
+ end
31
+
32
+ subject do
33
+ world.dup
34
+ end
35
+
36
+ it 'returns another instance' do
37
+ expect(subject).to be_a(World)
38
+ expect(subject).not_to be(world)
39
+ end
40
+
41
+ it 'keeps variables' do
42
+ expect(subject.foo).to eql(:bar)
43
+ end
44
+ end
45
+
46
+ describe 'class factory' do
47
+ subject do
48
+ world.factory(:foo) do
49
+ hello
50
+ end
51
+ end
52
+
53
+ def hello
54
+ OpenStruct.new(bar: 12)
55
+ end
56
+
57
+ it 'returns a world instance' do
58
+ expect(subject).to be_a(World)
59
+ expect(subject).not_to be(world)
60
+ end
61
+
62
+ it 'installs the factory' do
63
+ bound = subject.with_scope(self)
64
+ got = bound.foo
65
+ expect(got).to be_a(OpenStruct)
66
+ expect(got.bar).to eql(12)
67
+ expect(bound.foo).to be(got)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ describe Event do
5
+
6
+ subject{
7
+ Event.new("User::Changed", { "foo" => "bar" })
8
+ }
9
+
10
+ it 'presents an ostruct on top of its data' do
11
+ expect(subject.data.foo).to eql("bar")
12
+ end
13
+
14
+ describe "the json information contract" do
15
+
16
+ JSON_SRC = <<-JSON.gsub(/\s+/, "")
17
+ {
18
+ "type": "User::Changed",
19
+ "data": {
20
+ "foo": "bar"
21
+ }
22
+ }
23
+ JSON
24
+
25
+ it 'has a to_json method that works as expected' do
26
+ expect(subject.to_json).to eql(JSON_SRC)
27
+ end
28
+
29
+ it 'has a to_json that dumps the context if any' do
30
+ evt = Event.new("User::Changed", { "foo" => "bar" }, { "baz": "context" })
31
+ expect(evt.to_json).to eql(<<-JSON.gsub(/\s+/, ""))
32
+ {
33
+ "type": "User::Changed",
34
+ "data": {
35
+ "foo": "bar"
36
+ },
37
+ "context": {
38
+ "baz": "context"
39
+ }
40
+ }
41
+ JSON
42
+ end
43
+
44
+
45
+ it 'has a json class method that works as expected' do
46
+ evt = Event.json(JSON_SRC, nil)
47
+ expect(evt).to be_a(Event)
48
+ expect(evt.type).to eql("User::Changed")
49
+ expect(evt.data).to eql(subject.data)
50
+ end
51
+
52
+ it 'accepts an explicit context as second argument' do
53
+ c = SubContext.new.tap{|x| x.foo = 'hello' }
54
+ evt = Event.json(JSON_SRC, c)
55
+ expect(evt.context).not_to be(c)
56
+ expect(evt.context).to be_a(SubContext)
57
+ expect(evt.context.foo).to eql('hello')
58
+ end
59
+ end
60
+
61
+ end
62
+ end # module Startback
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ describe Operation do
5
+
6
+ class FooOp < Operation
7
+
8
+ def initialize(foo = :bar)
9
+ @foo = foo
10
+ end
11
+ attr_accessor :foo
12
+
13
+ def call
14
+ @foo
15
+ end
16
+
17
+ end
18
+
19
+ it 'can be bound, which returns a new operation' do
20
+ foo1 = FooOp.new
21
+ foo1.foo = :bar1
22
+
23
+ foo2 = foo1.bind({ db: :bar })
24
+ expect(foo2.foo).to eql(:bar1)
25
+ expect(foo2.db).to eql(:bar)
26
+ end
27
+
28
+ end
29
+
30
+ describe Operation::MultiOperation do
31
+
32
+ it 'lets chain with +' do
33
+ mop = Operation::MultiOperation.new
34
+ mop2 = (mop + FooOp.new)
35
+
36
+ expect(mop == mop2).to eql(false)
37
+ expect(mop.size).to eql(0)
38
+ expect(mop2.size).to eql(1)
39
+ end
40
+
41
+ it 'calls and collects the result on call' do
42
+ mop = Operation::MultiOperation.new + FooOp.new(:hello) + FooOp.new(:world)
43
+ expect(mop.call).to eql([:hello, :world])
44
+ end
45
+
46
+ it 'binds every sub operation recursively' do
47
+ mop = Operation::MultiOperation.new + FooOp.new(:hello) + FooOp.new(:world)
48
+ mop2 = mop.bind({requester: :bar})
49
+
50
+ expect(mop == mop2).to eql(false)
51
+ expect(mop2.ops.all?{|op| op.requester == :bar })
52
+ end
53
+
54
+ end
55
+ end # module Startback
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ describe Support do
5
+ include Support
6
+
7
+ describe "deep_merge" do
8
+
9
+ it 'works as expected' do
10
+ h1 = {
11
+ :foo => "bar",
12
+ :bar => "unchanged",
13
+ :baz => {
14
+ "hello" => "world",
15
+ "changed" => "yes"
16
+ }
17
+ }
18
+ h2 = {
19
+ :foo => "baz",
20
+ :baz => {
21
+ "eloy" => "tom",
22
+ "changed" => "no"
23
+ }
24
+ }
25
+ expected = {
26
+ :foo => "baz",
27
+ :bar => "unchanged",
28
+ :baz => {
29
+ "hello" => "world",
30
+ "eloy" => "tom",
31
+ "changed" => "no"
32
+ }
33
+ }
34
+ expect(deep_merge(h1, h2)).to eql(expected)
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,4 @@
1
+ let test = (x) => {
2
+ console.log("Hello " + x)
3
+ }
4
+ test("world")
@@ -0,0 +1 @@
1
+ <p>Hello {{who}}</p>
@@ -0,0 +1 @@
1
+ //= require_tree ./app
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+ require 'startback/web/api'
3
+
4
+ module Startback
5
+ module Web
6
+ describe Api do
7
+ include Rack::Test::Methods
8
+
9
+ class JsonDto
10
+ def to(accept, content_type)
11
+ ["application/json", %Q{{"foo":"bar"}}]
12
+ end
13
+ end
14
+
15
+ class PathDto
16
+ def to(accept, content_type)
17
+ ["text/plain", Path.file]
18
+ end
19
+ end
20
+
21
+ class DtoAble
22
+ def initialize(dto)
23
+ @dto = dto
24
+ end
25
+ def to_dto(context)
26
+ @dto
27
+ end
28
+ end
29
+
30
+ class TestedApi < ::Startback::Web::Api
31
+ get '/no-such-one' do
32
+ serve("Something", nil)
33
+ end
34
+
35
+ get '/entity' do
36
+ serve('Entity', {foo: "bar"})
37
+ end
38
+
39
+ get '/path' do
40
+ serve('Path', Path.file)
41
+ end
42
+
43
+ get '/dto-able' do
44
+ serve('DTO', DtoAble.new(JsonDto.new))
45
+ end
46
+
47
+ get '/dto-path' do
48
+ serve('DTO', DtoAble.new(PathDto.new))
49
+ end
50
+ end
51
+
52
+ let(:app) {
53
+ TestedApi
54
+ }
55
+
56
+ it 'convert nil to 404' do
57
+ get '/no-such-one'
58
+ expect(last_response.status).to eql(404)
59
+ end
60
+
61
+ it 'supports serving entities' do
62
+ get '/entity'
63
+ expect(last_response.body).to eql(%Q{{"foo":"bar"}})
64
+ end
65
+
66
+ it 'supports serving paths' do
67
+ get '/path'
68
+ expect(last_response.body).to eql(Path.file.read)
69
+ end
70
+
71
+ it 'supports serving DTO-able objects' do
72
+ get '/dto-able'
73
+ expect(last_response.body).to eql(%Q{{"foo":"bar"}})
74
+ end
75
+
76
+ it 'supports serving DTO-able objects eventually returning paths' do
77
+ get '/dto-path'
78
+ expect(last_response.body).to eql(Path.file.read)
79
+ end
80
+ end
81
+ end # module Web
82
+ end # module Startback
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'startback/web/auto_caching'
3
+
4
+ module Startback
5
+ module Web
6
+ describe AutoCaching do
7
+ include Rack::Test::Methods
8
+
9
+ context 'when used without options' do
10
+ def app
11
+ Rack::Builder.new do
12
+ use AutoCaching
13
+ run ->(env){ [200, {}, ["Hello error"]] }
14
+ end
15
+ end
16
+
17
+ it 'sets the development Cache-Control since this is a test' do
18
+ get '/'
19
+ expect(last_response['Cache-Control']). to eql("no-cache, no-store, max-age=0, must-revalidate")
20
+ end
21
+ end
22
+
23
+ context 'when forcing production' do
24
+ def app
25
+ Rack::Builder.new do
26
+ use AutoCaching, false
27
+ run ->(env){ [200, {}, ["Hello error"]] }
28
+ end
29
+ end
30
+
31
+ it 'sets the production Cache-Control' do
32
+ get '/'
33
+ expect(last_response['Cache-Control']). to eql("public, must-revalidate, max-age=3600, s-max-age=3600")
34
+ end
35
+ end
36
+
37
+ context 'when forcing development headers' do
38
+ def app
39
+ Rack::Builder.new do
40
+ use AutoCaching, development: { "Cache-Control" => "no-cache" }
41
+ run ->(env){ [200, {}, ["Hello error"]] }
42
+ end
43
+ end
44
+
45
+ it 'sets the production Cache-Control' do
46
+ get '/'
47
+ expect(last_response['Cache-Control']). to eql("no-cache")
48
+ end
49
+ end
50
+
51
+ context 'when setting the Cache-Control header only' do
52
+ def app
53
+ Rack::Builder.new do
54
+ use AutoCaching, development: "no-cache"
55
+ run ->(env){ [200, {}, ["Hello error"]] }
56
+ end
57
+ end
58
+
59
+ it 'sets the production Cache-Control' do
60
+ get '/'
61
+ expect(last_response['Cache-Control']). to eql("no-cache")
62
+ end
63
+ end
64
+
65
+ context 'when a Cache-Control header is already set by the app' do
66
+ def app
67
+ Rack::Builder.new do
68
+ use AutoCaching
69
+ run ->(env){ [200, {"Cache-Control" => "priority"}, ["Hello error"]] }
70
+ end
71
+ end
72
+
73
+ it 'sets the production Cache-Control' do
74
+ get '/'
75
+ expect(last_response['Cache-Control']). to eql("priority")
76
+ end
77
+ end
78
+
79
+ end # CatchAll
80
+ end # module Web
81
+ end # module Startback
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require 'singleton'
3
+ require 'startback/web/catch_all'
4
+
5
+ module Startback
6
+ module Web
7
+ describe CatchAll do
8
+ include Rack::Test::Methods
9
+
10
+ context 'when used without context' do
11
+ def app
12
+ Rack::Builder.new do
13
+ use CatchAll
14
+ run ->(env){ raise "Hello error" }
15
+ end
16
+ end
17
+
18
+ it 'returns a 500 with json explanation' do
19
+ get '/'
20
+ expect(last_response.status).to eql(500)
21
+ expect(last_response.content_type).to eql("application/json")
22
+ result = JSON.parse(last_response.body)
23
+ expect(result).to eql({
24
+ "code" => "Startback::Errors::InternalServerError",
25
+ "description" => "An error occured, sorry"
26
+ })
27
+ end
28
+ end
29
+
30
+ context 'when used with a context providing an error handler' do
31
+
32
+ class AnError < StandardError
33
+ end
34
+
35
+ class ErrorHandler
36
+ include Singleton
37
+
38
+ attr_reader :ex
39
+
40
+ def fatal(ex)
41
+ @ex = ex
42
+ end
43
+
44
+ end
45
+
46
+ class MyContextWithErrorHandler < Startback::Context
47
+
48
+ def error_handler
49
+ ErrorHandler.instance
50
+ end
51
+
52
+ end
53
+
54
+ def app
55
+ Rack::Builder.new do
56
+ use Context::Middleware, MyContextWithErrorHandler.new
57
+ use CatchAll
58
+ run ->(env){ raise AnError, "Hello error" }
59
+ end
60
+ end
61
+
62
+ it 'returns a 500 with json explanation' do
63
+ get '/'
64
+ expect(last_response.status).to eql(500)
65
+ expect(last_response.content_type).to eql("application/json")
66
+ result = JSON.parse(last_response.body)
67
+ expect(result).to eql({
68
+ "code" => "Startback::Errors::InternalServerError",
69
+ "description" => "An error occured, sorry"
70
+ })
71
+ expect(ErrorHandler.instance.ex).to be_a(AnError)
72
+ end
73
+ end
74
+
75
+ end # CatchAll
76
+ end # module Web
77
+ end # module Startback
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+ require 'startback/web/cors_headers'
3
+
4
+ module Startback
5
+ module Web
6
+ describe CorsHeaders do
7
+ include Rack::Test::Methods
8
+
9
+ context 'when used without options' do
10
+ def app
11
+ Rack::Builder.new do
12
+ use CorsHeaders
13
+ run ->(env){ [200, {}, ["Hello world"]] }
14
+ end
15
+ end
16
+
17
+ it 'sets the CORS headers to default values' do
18
+ header('Origin', "https://test.com")
19
+ get '/'
20
+ expect(last_response['Access-Control-Allow-Origin']). to eql("*")
21
+ expect(last_response['Access-Control-Allow-Methods']). to eql("OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE")
22
+ expect(last_response.body).to eql("Hello world")
23
+ end
24
+
25
+ it 'strips everything when option' do
26
+ header('Origin', "https://test.com")
27
+ options '/'
28
+ expect(last_response['Access-Control-Allow-Origin']). to eql("*")
29
+ expect(last_response['Access-Control-Allow-Methods']). to eql("OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE")
30
+ expect(last_response.status).to eql(204)
31
+ expect(last_response.body).to eql("")
32
+ end
33
+ end
34
+
35
+ context 'when used with the :bounce option' do
36
+ def app
37
+ Rack::Builder.new do
38
+ use CorsHeaders, bounce: true
39
+ run ->(env){ [200, {}, ["Hello world"]] }
40
+ end
41
+ end
42
+
43
+ it 'sets the CORS Origin header to the caller' do
44
+ header('Origin', "https://test.com")
45
+ get '/'
46
+ expect(last_response['Access-Control-Allow-Origin']). to eql("https://test.com")
47
+ expect(last_response['Access-Control-Allow-Methods']). to eql("OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE")
48
+ expect(last_response.body).to eql("Hello world")
49
+ end
50
+ end
51
+
52
+ context 'when overriding a header' do
53
+ def app
54
+ Rack::Builder.new do
55
+ use CorsHeaders, headers: { 'Access-Control-Allow-Methods' => "POST" }
56
+ run ->(env){ [200, {}, ["Hello world"]] }
57
+ end
58
+ end
59
+
60
+ it 'sets the CORS Origin header to the caller' do
61
+ header('Origin', "https://test.com")
62
+ get '/'
63
+ expect(last_response['Access-Control-Allow-Origin']). to eql("*")
64
+ expect(last_response['Access-Control-Allow-Methods']). to eql("POST")
65
+ expect(last_response.body).to eql("Hello world")
66
+ end
67
+ end
68
+
69
+ context 'when the app sets specific headers' do
70
+ def app
71
+ Rack::Builder.new do
72
+ use CorsHeaders
73
+ run ->(env){ [200, {'Access-Control-Allow-Methods' => "POST"}, ["Hello world"]] }
74
+ end
75
+ end
76
+
77
+ it 'does not override them' do
78
+ header('Origin', "https://test.com")
79
+ get '/'
80
+ expect(last_response['Access-Control-Allow-Origin']). to eql("*")
81
+ expect(last_response['Access-Control-Allow-Methods']). to eql("POST")
82
+ expect(last_response.body).to eql("Hello world")
83
+ end
84
+ end
85
+
86
+ end # CatchAll
87
+ end # module Web
88
+ end # module Startback
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'startback/web/health_check'
3
+
4
+ module Startback
5
+ module Web
6
+ describe HealthCheck do
7
+ include Rack::Test::Methods
8
+
9
+ context 'when used without a block and no failure' do
10
+ def app
11
+ HealthCheck.new
12
+ end
13
+
14
+ it 'returns a 204 when ok' do
15
+ get '/'
16
+ expect(last_response.status).to eql(204)
17
+ expect(last_response.body).to be_empty
18
+ end
19
+ end
20
+
21
+ context 'when used without a block a failure' do
22
+ def app
23
+ app = HealthCheck.new
24
+ def app.check!(env)
25
+ raise "Hello error"
26
+ end
27
+ app
28
+ end
29
+
30
+ it 'raises when ko' do
31
+ expect(->(){ get '/' }).to raise_error("Hello error")
32
+ end
33
+ end
34
+
35
+ context 'when used with a block returning a debug message' do
36
+ def app
37
+ HealthCheck.new{ "Hello world" }
38
+ end
39
+
40
+ it 'returns a 200 with plain text message' do
41
+ get '/'
42
+ expect(last_response.status).to eql(200)
43
+ expect(last_response.body).to eql("Hello world")
44
+ end
45
+ end
46
+
47
+ context 'when used with a block raising an exception' do
48
+ def app
49
+ HealthCheck.new{ raise("Hello error") }
50
+ end
51
+
52
+ it 're-raises it' do
53
+ expect(->(){ get '/' }).to raise_error("Hello error")
54
+ end
55
+ end
56
+
57
+ end
58
+ end # module Web
59
+ end # module Startback