ff-tbl-macros 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Dockerfile +13 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +117 -0
- data/MIT-LICENSE +18 -0
- data/README.md +147 -0
- data/lib/ff-tbl-macros.rb +29 -0
- data/lib/macros/auth.rb +9 -0
- data/lib/macros/auth/authenticate.rb +24 -0
- data/lib/macros/auth/sign_in.rb +43 -0
- data/lib/macros/auth/sign_out.rb +48 -0
- data/lib/macros/base.rb +37 -0
- data/lib/macros/contract.rb +8 -0
- data/lib/macros/contract/extract_params.rb +25 -0
- data/lib/macros/contract/prepopulate.rb +16 -0
- data/lib/macros/ctx.rb +9 -0
- data/lib/macros/ctx/copy.rb +18 -0
- data/lib/macros/ctx/inspect.rb +28 -0
- data/lib/macros/ctx/validate_presence.rb +20 -0
- data/lib/macros/current_user.rb +7 -0
- data/lib/macros/current_user/set.rb +25 -0
- data/lib/macros/error.rb +7 -0
- data/lib/macros/error/set_from_contract.rb +19 -0
- data/lib/macros/model.rb +10 -0
- data/lib/macros/model/build.rb +32 -0
- data/lib/macros/model/copy.rb +17 -0
- data/lib/macros/model/destroy.rb +18 -0
- data/lib/macros/model/persist.rb +21 -0
- data/lib/macros/search.rb +7 -0
- data/lib/macros/search/query.rb +34 -0
- data/lib/macros/verify_params.rb +7 -0
- data/lib/macros/verify_params/date.rb +17 -0
- data/lib/macros/version.rb +6 -0
- data/spec/lib/auth/authenticate_spec.rb +21 -0
- data/spec/lib/auth/sign_in_spec.rb +37 -0
- data/spec/lib/auth/sign_out_spec.rb +37 -0
- data/spec/lib/auth_spec.rb +15 -0
- data/spec/lib/contract/extract_params_spec.rb +35 -0
- data/spec/lib/contract/prepopulate_spec.rb +27 -0
- data/spec/lib/contract_spec.rb +14 -0
- data/spec/lib/ctx/copy_spec.rb +27 -0
- data/spec/lib/ctx/inspect_spec.rb +26 -0
- data/spec/lib/ctx/validate_presence_spec.rb +20 -0
- data/spec/lib/ctx_spec.rb +19 -0
- data/spec/lib/current_user.rb +7 -0
- data/spec/lib/current_user/set_spec.rb +24 -0
- data/spec/lib/error/set_from_contract_spec.rb +27 -0
- data/spec/lib/error_spec.rb +7 -0
- data/spec/lib/ff_tbl_macros_spec.rb +11 -0
- data/spec/lib/model/build_spec.rb +53 -0
- data/spec/lib/model/copy_spec.rb +26 -0
- data/spec/lib/model/destroy_spec.rb +13 -0
- data/spec/lib/model/persist_spec.rb +45 -0
- data/spec/lib/model_spec.rb +21 -0
- data/spec/lib/search/query_spec.rb +23 -0
- data/spec/lib/search_spec.rb +9 -0
- data/spec/lib/verify_params/date_spec.rb +22 -0
- data/spec/lib/verify_params_spec.rb +9 -0
- data/spec/spec_helper.rb +38 -0
- metadata +169 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Auth::SignIn do
|
4
|
+
include Warden::Test::Mock
|
5
|
+
|
6
|
+
subject(:sign_in_step) { described_class.new }
|
7
|
+
|
8
|
+
let(:user) { mock_model('User') }
|
9
|
+
let(:scope) { :user }
|
10
|
+
let(:ctx) { { model: user, warden: warden } }
|
11
|
+
|
12
|
+
before do
|
13
|
+
fake_class = Class.new
|
14
|
+
dm = stub_const('Devise::Mapping', fake_class, transfer_nested_constants: true)
|
15
|
+
allow(dm).to receive(:find_scope!).with(user).and_return(scope)
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'user not signed in' do
|
19
|
+
it 'expects to sign in' do
|
20
|
+
sign_in_step.call(ctx, model: user, warden: warden)
|
21
|
+
|
22
|
+
expect(ctx[:current_user]).to eql user
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'user already signed in' do
|
27
|
+
before do
|
28
|
+
warden.set_user(user, scope: scope)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'expects to keep user signed in' do
|
32
|
+
sign_in_step.call(ctx, model: user, warden: warden)
|
33
|
+
|
34
|
+
expect(ctx[:current_user]).to eql user
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Auth::SignOut do
|
4
|
+
include Warden::Test::Mock
|
5
|
+
|
6
|
+
subject(:sign_out_step) { described_class.new }
|
7
|
+
|
8
|
+
let(:user) { mock_model('User') }
|
9
|
+
let(:scope) { :user }
|
10
|
+
let(:ctx) { { warden: warden } }
|
11
|
+
|
12
|
+
before do
|
13
|
+
fake_class = Class.new
|
14
|
+
dm = stub_const('Devise::Mapping', fake_class, transfer_nested_constants: true)
|
15
|
+
allow(dm).to receive(:find_scope!).with(scope).and_return(scope)
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'user signed in' do
|
19
|
+
before do
|
20
|
+
warden.set_user(user, scope: scope)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'expects to sign out user' do
|
24
|
+
sign_out_step.call(ctx, warden: warden)
|
25
|
+
|
26
|
+
expect(ctx[:current_user]).to be nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'user not signed in' do
|
31
|
+
it 'expects to keep user signed out' do
|
32
|
+
sign_out_step.call(ctx, warden: warden)
|
33
|
+
|
34
|
+
expect(ctx[:current_user]).to be nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Auth do
|
4
|
+
describe '#Authenticate()' do
|
5
|
+
it { expect(described_class::Authenticate()).to be_a described_class::Authenticate }
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#SignIn()' do
|
9
|
+
it { expect(described_class::SignIn()).to be_a described_class::SignIn }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#SignOut()' do
|
13
|
+
it { expect(described_class::SignOut()).to be_a described_class::SignOut }
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Contract::ExtractParams do
|
4
|
+
subject(:extract_params_step) { described_class.new(params) }
|
5
|
+
|
6
|
+
let(:params) { { from: from } }
|
7
|
+
|
8
|
+
class self::UserForm < Reform::Form # rubocop:disable Style/ClassAndModuleChildren
|
9
|
+
property :password
|
10
|
+
|
11
|
+
def build_errors; end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:user) { stub_model(User) }
|
15
|
+
let(:contract) { self.class::UserForm.new(user) }
|
16
|
+
let(:scope) { :user }
|
17
|
+
let(:password) { '$3cr3t' }
|
18
|
+
let(:from) { :scope }
|
19
|
+
let(:ctx) { { scope: :user, params: { user: { password: password } } } }
|
20
|
+
|
21
|
+
it 'expects to set params in contract' do
|
22
|
+
extract_params_step.call(ctx, params: params)
|
23
|
+
|
24
|
+
expect(ctx['contract.default.params'][:password]).to eql password
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'from key does not exist' do
|
28
|
+
let(:from) { :scoped_to }
|
29
|
+
|
30
|
+
it 'expects to fail and do not set any params in contract' do
|
31
|
+
expect(extract_params_step.call(ctx, params: params)).to eql false
|
32
|
+
expect(ctx['contract.default.params']).to be nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Contract::Prepopulate do
|
4
|
+
subject(:prepopulate_step) { described_class.new(options_key: options_key) }
|
5
|
+
|
6
|
+
class self::AlbumForm < Reform::Form # rubocop:disable Style/ClassAndModuleChildren
|
7
|
+
property :title
|
8
|
+
|
9
|
+
def build_errors; end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:album) { mock_model('Album', title: title) }
|
13
|
+
let(:contract) { self.class::AlbumForm.new(album) }
|
14
|
+
|
15
|
+
let(:ctx) { { 'contract.default' => contract, options_key => { title: new_title } } }
|
16
|
+
|
17
|
+
let(:options_key) { :params }
|
18
|
+
|
19
|
+
let(:title) { 'Lorem' }
|
20
|
+
let(:new_title) { 'Ipsum' }
|
21
|
+
|
22
|
+
it 'expects to prepopulate contract' do
|
23
|
+
expect(ctx['contract.default']).to receive(:prepopulate!).with(title: new_title)
|
24
|
+
|
25
|
+
prepopulate_step.call(ctx)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Contract do
|
4
|
+
describe '#Prepopulate()' do
|
5
|
+
let(:options_key) { :foo }
|
6
|
+
|
7
|
+
it { expect(described_class::Prepopulate(options_key: options_key)).to be_a described_class::Prepopulate }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#ExtractParams()' do
|
11
|
+
let(:from) { :scope }
|
12
|
+
it { expect(described_class::ExtractParams(from: from)).to be_a described_class::ExtractParams }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Ctx::Copy do
|
4
|
+
subject(:copy_step) { described_class.new(origin_key, destination_key) }
|
5
|
+
|
6
|
+
let(:origin_key) { :foo }
|
7
|
+
let(:destination_key) { :bar }
|
8
|
+
let(:value) { :lorem }
|
9
|
+
|
10
|
+
let(:ctx) { { origin_key => value } }
|
11
|
+
|
12
|
+
it 'expects to copy origin value to destination one in ctx' do
|
13
|
+
copy_step.call(ctx)
|
14
|
+
|
15
|
+
expect(ctx[destination_key]).to eq value
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'source key not present in ctx' do
|
19
|
+
let(:ctx) { { dolor: :se } }
|
20
|
+
|
21
|
+
it 'expects to keep destination value to be nil' do
|
22
|
+
copy_step.call(ctx)
|
23
|
+
|
24
|
+
expect(ctx[destination_key]).to be nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Ctx::Inspect do
|
4
|
+
subject(:inspect_step) { described_class.new(key: key) }
|
5
|
+
|
6
|
+
let(:key) { :foo }
|
7
|
+
let(:value) { { lorem: :ipsum } }
|
8
|
+
|
9
|
+
let(:ctx) { { foo: value, dolor: :se } }
|
10
|
+
|
11
|
+
it 'expects to print only specified pair key and value' do
|
12
|
+
inspect_step.call(ctx)
|
13
|
+
|
14
|
+
expect { print(key => value) }.to output.to_stdout
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'key not passed' do
|
18
|
+
let(:key) { nil }
|
19
|
+
|
20
|
+
it 'expects to print whole ctx' do
|
21
|
+
inspect_step.call(ctx)
|
22
|
+
|
23
|
+
expect { print(ctx) }.to output.to_stdout
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Ctx::ValidatePresence do
|
4
|
+
subject(:validate_presence_step) { described_class.new(key) }
|
5
|
+
|
6
|
+
let(:key) { :foo }
|
7
|
+
let(:ctx) { { foo: 'Lorem' } }
|
8
|
+
|
9
|
+
it 'expects to pass' do
|
10
|
+
expect(validate_presence_step.call(ctx)).to be true
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'key does not exist' do
|
14
|
+
let(:key) { :bar }
|
15
|
+
|
16
|
+
it 'expects to fail' do
|
17
|
+
expect(validate_presence_step.call(ctx)).to be false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Ctx do
|
4
|
+
let(:key) { :lorem }
|
5
|
+
|
6
|
+
describe '#Copy()' do
|
7
|
+
let(:destination_key) { :bar }
|
8
|
+
|
9
|
+
it { expect(described_class::Copy(key, destination_key)).to be_a described_class::Copy }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#Inspect()' do
|
13
|
+
it { expect(described_class::Inspect(key: key)).to be_a described_class::Inspect }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#ValidatePresence()' do
|
17
|
+
it { expect(described_class::ValidatePresence(key: key)).to be_a described_class::ValidatePresence }
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::CurrentUser::Set do
|
4
|
+
subject(:set_step) { described_class.new }
|
5
|
+
|
6
|
+
let(:user) { mock_model('User') }
|
7
|
+
let(:ctx) { { model: user } }
|
8
|
+
|
9
|
+
it 'should set current user in ctx' do
|
10
|
+
set_step.call(ctx)
|
11
|
+
|
12
|
+
expect(ctx[:current_user]).to eql user
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'model key does not exists in the context' do
|
16
|
+
let(:ctx) { { admin: user } }
|
17
|
+
|
18
|
+
it 'should not set current user in ctx' do
|
19
|
+
set_step.call(ctx)
|
20
|
+
|
21
|
+
expect(ctx[:current_user]).to be nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Error::SetFromContract do
|
4
|
+
subject(:step) { described_class.new }
|
5
|
+
|
6
|
+
let(:ctx) do
|
7
|
+
{ 'contract.default' => RecursiveOpenStruct.new(errors: { messages: { email: ["can't be blank"] } }) }
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should set error messages in context' do
|
11
|
+
result = step.call(ctx)
|
12
|
+
|
13
|
+
expect(result).to be true
|
14
|
+
expect(ctx[:error_messages][:email]).to include "can't be blank"
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'contract errors not set' do
|
18
|
+
let(:ctx) { { 'contract.default' => RecursiveOpenStruct.new } }
|
19
|
+
|
20
|
+
it 'should not set any error messages' do
|
21
|
+
result = step.call(ctx)
|
22
|
+
|
23
|
+
expect(result).to be false
|
24
|
+
expect(ctx[:error_messages]).to be nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Model::Build do
|
4
|
+
subject(:build_step) { described_class.new(params) }
|
5
|
+
|
6
|
+
let(:params) { { from: from } }
|
7
|
+
let(:scope) { :foobar }
|
8
|
+
let(:from) { :scope }
|
9
|
+
let(:ctx) { { scope: scope } }
|
10
|
+
|
11
|
+
before do
|
12
|
+
mock_model('Foobar')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should build model' do
|
16
|
+
build_step.call(ctx)
|
17
|
+
|
18
|
+
expect(ctx[:model].class.name).to eql 'Foobar'
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'respond to passed in params' do
|
22
|
+
let(:params) { { from: from, respond_to: :loremised_by_id } }
|
23
|
+
|
24
|
+
context 'model responds to specified method' do
|
25
|
+
before do
|
26
|
+
allow_any_instance_of(Foobar).to receive(:loremised_by_id).and_return(rand)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should build model' do
|
30
|
+
build_step.call(ctx)
|
31
|
+
|
32
|
+
expect(ctx[:model].class).to eql Foobar
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'model do not respond to specified method' do
|
37
|
+
it 'should fail' do
|
38
|
+
expect(build_step.call(ctx)).to be false
|
39
|
+
|
40
|
+
expect(ctx[:model]).to be nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'key does not exist in ctx' do
|
46
|
+
let(:ctx) { {} }
|
47
|
+
|
48
|
+
it 'should fail' do
|
49
|
+
expect(build_step.call(ctx)).to be false
|
50
|
+
expect(ctx[:model]).to be nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Model::Copy do
|
4
|
+
let(:user) { mock_model('User') }
|
5
|
+
|
6
|
+
let(:ctx) { { current_user: user } }
|
7
|
+
let(:ctx_key) { :current_user }
|
8
|
+
|
9
|
+
subject(:copy_step) { described_class.new(ctx_key) }
|
10
|
+
|
11
|
+
it 'expects to copy current user to ctx model' do
|
12
|
+
copy_step.call(ctx)
|
13
|
+
|
14
|
+
expect(ctx[:model]).to eq user
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'source does not exist' do
|
18
|
+
let(:ctx_key) { :administrator }
|
19
|
+
|
20
|
+
it 'expects ctx model to keep nil' do
|
21
|
+
copy_step.call(ctx)
|
22
|
+
|
23
|
+
expect(ctx[:model]).to be nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Macros::Model::Destroy do
|
4
|
+
subject(:destroy_step) { described_class.new }
|
5
|
+
|
6
|
+
let(:ctx) { { model: user } }
|
7
|
+
let(:user) { mock_model('User', destroy: true, destroyed?: true) }
|
8
|
+
|
9
|
+
it 'expect to destroy model' do
|
10
|
+
destroy_step.call(ctx, model: user)
|
11
|
+
expect(ctx[:model].destroyed?).to be true
|
12
|
+
end
|
13
|
+
end
|