task_helper 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +30 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +317 -0
- data/Rakefile +4 -0
- data/lib/task_helper/api/cache.rb +28 -0
- data/lib/task_helper/api/call.rb +48 -0
- data/lib/task_helper/api.rb +23 -0
- data/lib/task_helper/base.rb +55 -0
- data/lib/task_helper/database.rb +30 -0
- data/lib/task_helper/field.rb +20 -0
- data/lib/task_helper/form.rb +57 -0
- data/lib/task_helper/record.rb +29 -0
- data/lib/task_helper/version.rb +3 -0
- data/lib/task_helper.rb +15 -0
- data/lib/tasks/spec_setup.rake +41 -0
- data/spec/lib/task_helper/api/cache_spec.rb +73 -0
- data/spec/lib/task_helper/api/call_spec.rb +136 -0
- data/spec/lib/task_helper/api_spec.rb +45 -0
- data/spec/lib/task_helper/database_spec.rb +91 -0
- data/spec/lib/task_helper/field_spec.rb +50 -0
- data/spec/lib/task_helper/form_spec.rb +141 -0
- data/spec/lib/task_helper/record_spec.rb +73 -0
- data/spec/lib/task_helper/version_spec.rb +5 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/fake_mth.rb +74 -0
- data/spec/support/fixture_parser.rb +67 -0
- data/spec/support/fixtures/.keep +0 -0
- data/task_helper.gemspec +27 -0
- metadata +173 -0
data/lib/task_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
require 'task_helper/version'
|
4
|
+
require 'task_helper/api/call'
|
5
|
+
require 'task_helper/api/cache'
|
6
|
+
require 'task_helper/api'
|
7
|
+
require 'task_helper/base'
|
8
|
+
require 'task_helper/record'
|
9
|
+
require 'task_helper/field'
|
10
|
+
require 'task_helper/form'
|
11
|
+
require 'task_helper/database'
|
12
|
+
|
13
|
+
module TaskHelper
|
14
|
+
# Your code goes here...
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
namespace :spec do
|
2
|
+
task :setup, [:api_key] do |t, args|
|
3
|
+
TaskHelper::API.rest_api_key = args[:api_key]
|
4
|
+
|
5
|
+
File.open('spec/support/fixtures/databases.json', 'w') do |f|
|
6
|
+
f.write(JSON.pretty_generate(TaskHelper::API.get(route: 'apps.json')))
|
7
|
+
end
|
8
|
+
|
9
|
+
TaskHelper::API.get(route: 'apps.json')['databases'].each do |db|
|
10
|
+
db_dir = "spec/support/fixtures/databases/#{db['id']}"
|
11
|
+
db_route = "apps/#{db['id']}"
|
12
|
+
forms_route = "#{db_route}/entities"
|
13
|
+
FileUtils.mkdir_p(db_dir)
|
14
|
+
File.open("#{db_dir}/forms.json", 'w') do |f|
|
15
|
+
f.write(JSON.pretty_generate(TaskHelper::API.get(route: "#{forms_route}.json")))
|
16
|
+
end
|
17
|
+
|
18
|
+
TaskHelper::API.get(route: "apps/#{db['id']}/entities.json")['forms'].each do |form|
|
19
|
+
form_dir = "#{db_dir}/forms/#{form['id']}"
|
20
|
+
fields_route = "#{forms_route}/#{form['id']}/properties"
|
21
|
+
FileUtils.mkdir_p(form_dir)
|
22
|
+
File.open("#{form_dir}/fields.json", 'w') do |f|
|
23
|
+
f.write(JSON.pretty_generate(TaskHelper::API.get(route: "#{fields_route}.json")))
|
24
|
+
end
|
25
|
+
|
26
|
+
if TaskHelper::API.get(route: "#{fields_route}.json")['fields'].any?
|
27
|
+
records_route = "#{db_route}/dtypes/entity/#{form['id']}"
|
28
|
+
records_dir = "#{form_dir}/records"
|
29
|
+
FileUtils.mkdir_p(records_dir)
|
30
|
+
page_count = db['dtypes_count'].to_i / form['per_page'].to_i + 1
|
31
|
+
(1..page_count).each do |page|
|
32
|
+
File.open("#{records_dir}/#{page}.json", 'w') do |f|
|
33
|
+
f.write(JSON.pretty_generate(TaskHelper::API
|
34
|
+
.get(route: "#{records_route}.json", params: { page: page })))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
describe TaskHelper::API::Cache do
|
2
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
3
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
4
|
+
|
5
|
+
subject { described_class.new(limit: 2) }
|
6
|
+
|
7
|
+
describe '#get' do
|
8
|
+
context 'call already cached' do
|
9
|
+
it 'should query the existing call' do
|
10
|
+
call1 = TaskHelper::API::Call.new(route: 'hello')
|
11
|
+
call2 = TaskHelper::API::Call.new(route: 'hello')
|
12
|
+
expect(TaskHelper::API::Call).to receive(:new).with(route: 'hello')
|
13
|
+
.twice.and_return(call1, call2)
|
14
|
+
expect(call1).to receive(:run).twice
|
15
|
+
subject.get(route: 'hello')
|
16
|
+
subject.get(route: 'hello')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'call not yet cached' do
|
21
|
+
it 'should query a new call' do
|
22
|
+
call1 = TaskHelper::API::Call.new(route: 'hello')
|
23
|
+
call2 = TaskHelper::API::Call.new(route: 'goodbye')
|
24
|
+
expect(call1).to receive(:run).once
|
25
|
+
expect(call2).to receive(:run).once
|
26
|
+
expect(TaskHelper::API::Call).to receive(:new).once.ordered
|
27
|
+
.with(route: 'hello').and_return(call1)
|
28
|
+
expect(TaskHelper::API::Call).to receive(:new).once.ordered
|
29
|
+
.with(route: 'goodbye').and_return(call2)
|
30
|
+
subject.get(route: 'hello')
|
31
|
+
subject.get(route: 'goodbye')
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should cache the new call' do
|
35
|
+
call1 = TaskHelper::API::Call.new(route: 'hello')
|
36
|
+
call2 = TaskHelper::API::Call.new(route: 'goodbye')
|
37
|
+
call3 = TaskHelper::API::Call.new(route: 'goodbye')
|
38
|
+
expect(call1).to receive(:run).once
|
39
|
+
expect(call2).to receive(:run).twice
|
40
|
+
expect(TaskHelper::API::Call).to receive(:new).once.ordered
|
41
|
+
.with(route: 'hello').and_return(call1)
|
42
|
+
expect(TaskHelper::API::Call).to receive(:new).twice.ordered
|
43
|
+
.with(route: 'goodbye').and_return(call2, call3)
|
44
|
+
subject.get(route: 'hello')
|
45
|
+
subject.get(route: 'goodbye')
|
46
|
+
subject.get(route: 'goodbye')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should remove older calls if the limit is reached' do
|
50
|
+
call1 = TaskHelper::API::Call.new(route: 'hello')
|
51
|
+
call2 = TaskHelper::API::Call.new(route: 'goodbye')
|
52
|
+
call3 = TaskHelper::API::Call.new(route: 'foobar')
|
53
|
+
call4 = TaskHelper::API::Call.new(route: 'hello')
|
54
|
+
expect(call1).to receive(:run).once
|
55
|
+
expect(call2).to receive(:run).once
|
56
|
+
expect(call3).to receive(:run).once
|
57
|
+
expect(call4).to receive(:run).once
|
58
|
+
expect(TaskHelper::API::Call).to receive(:new).once.ordered
|
59
|
+
.with(route: 'hello').and_return(call1)
|
60
|
+
expect(TaskHelper::API::Call).to receive(:new).once.ordered
|
61
|
+
.with(route: 'goodbye').and_return(call2)
|
62
|
+
expect(TaskHelper::API::Call).to receive(:new).once.ordered
|
63
|
+
.with(route: 'foobar').and_return(call3)
|
64
|
+
expect(TaskHelper::API::Call).to receive(:new).once.ordered
|
65
|
+
.with(route: 'hello').and_return(call4)
|
66
|
+
subject.get(route: 'hello')
|
67
|
+
subject.get(route: 'goodbye')
|
68
|
+
subject.get(route: 'foobar')
|
69
|
+
subject.get(route: 'hello')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
describe TaskHelper::API::Call do
|
2
|
+
let(:key) { { rest_api_key: 'foobar' } }
|
3
|
+
let(:response) { double(parsed_response: [{ 'a' => 1 }]) }
|
4
|
+
|
5
|
+
it 'should define a reader for time' do
|
6
|
+
t = Time.now
|
7
|
+
args = { route: 'hello', params: key, time: t }
|
8
|
+
expect(described_class.new(args).time).to eq(t)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.new' do
|
12
|
+
context 'given an api key' do
|
13
|
+
subject { described_class.new(route: 'hello', params: key) }
|
14
|
+
|
15
|
+
it 'should not raise a missing key error' do
|
16
|
+
expect { subject }.not_to raise_exception
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should replace the default key' do
|
20
|
+
TaskHelper::API.rest_api_key = 'hello'
|
21
|
+
expect(HTTParty).to receive(:get)
|
22
|
+
.with(anything, query: key).and_return(response)
|
23
|
+
subject.run
|
24
|
+
TaskHelper::API.rest_api_key = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'without an api key' do
|
29
|
+
subject { described_class.new(route: 'hello') }
|
30
|
+
|
31
|
+
it 'should attempt to use the default' do
|
32
|
+
TaskHelper::API.rest_api_key = 'hello'
|
33
|
+
expect(HTTParty).to receive(:get)
|
34
|
+
.with(anything, query: { rest_api_key: 'hello' }).and_return(response)
|
35
|
+
subject.run
|
36
|
+
TaskHelper::API.rest_api_key = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should raise an exception if no default is set' do
|
40
|
+
expect { subject }.to raise_exception(TaskHelper::API::Call::MissingAPIKey)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#run' do
|
46
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
47
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
48
|
+
|
49
|
+
subject { described_class.new(route: 'hello') }
|
50
|
+
|
51
|
+
it 'should reset the time' do
|
52
|
+
expect { subject.run }.to change { subject.time }
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should make a request to the given route at mytaskhelper.com' do
|
56
|
+
expect(HTTParty).to receive(:get)
|
57
|
+
.with('https://mytaskhelper.com/hello', query: { rest_api_key: 'foobar' })
|
58
|
+
.and_return(response)
|
59
|
+
subject.run
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'call has expired' do
|
63
|
+
it 'should resend the request' do
|
64
|
+
params = { route: 'hello', timeout: 0 }
|
65
|
+
call = described_class.new(params)
|
66
|
+
expect(HTTParty).to receive(:get).twice.and_return(response)
|
67
|
+
call.run
|
68
|
+
call.run
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'call has not expired' do
|
73
|
+
context 'request has been cached' do
|
74
|
+
it 'should return the cached response' do
|
75
|
+
expect(HTTParty).to receive(:get).once.and_return(response)
|
76
|
+
result = subject.run
|
77
|
+
expect(subject.run).to eq(result)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'request has not been chached' do
|
82
|
+
it 'should retrieve the response' do
|
83
|
+
expect(HTTParty).to receive(:get).once.and_return(response)
|
84
|
+
expect(subject.run).to eq(response.parsed_response)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#expired?' do
|
91
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
92
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
93
|
+
|
94
|
+
context 'request timed out' do
|
95
|
+
it 'shoud return false' do
|
96
|
+
args = { route: 'hello', timeout: 0, time: Time.now - 5 }
|
97
|
+
expect(described_class.new(args).expired?).to be(true)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'request not timed out' do
|
102
|
+
it 'shoud return false' do
|
103
|
+
args = { route: 'hello', timeout: 100, time: Time.now - 5 }
|
104
|
+
expect(described_class.new(args).expired?).to be(false)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#==' do
|
110
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
111
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
112
|
+
|
113
|
+
subject { described_class.new(route: 'hello', params: { a: 1 }) }
|
114
|
+
|
115
|
+
context 'route does not match' do
|
116
|
+
it 'should return false' do
|
117
|
+
expect(subject == described_class.new(route: 'hi'))
|
118
|
+
.to be(false)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'args do not match' do
|
123
|
+
it 'should return false' do
|
124
|
+
expect(subject == described_class.new(route: 'hello', params: { b: 2 }))
|
125
|
+
.to be(false)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'route and args match' do
|
130
|
+
it 'should return true' do
|
131
|
+
expect(subject == described_class.new(route: 'hello', params: { a: 1 }))
|
132
|
+
.to be(true)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe TaskHelper::API do
|
2
|
+
subject { TaskHelper::API }
|
3
|
+
|
4
|
+
it 'should define a singleton accessor for "rest_api_key"' do
|
5
|
+
expect(subject.rest_api_key).to eq(nil)
|
6
|
+
expect { subject.rest_api_key = 'foobar' }
|
7
|
+
.to change { subject.rest_api_key }.from(nil).to('foobar')
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '.get' do
|
11
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
12
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
13
|
+
|
14
|
+
it 'should forward to the cache' do
|
15
|
+
expect_any_instance_of(TaskHelper::API::Cache).to receive(:get)
|
16
|
+
.with(route: 'hello')
|
17
|
+
subject.get(route: 'hello')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.set_cache' do
|
22
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
23
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
24
|
+
|
25
|
+
it 'should reset the cache to a new instance with the given arguments' do
|
26
|
+
cache = TaskHelper::API::Cache.new(limit: 2)
|
27
|
+
expect(TaskHelper::API::Cache).to receive(:new).with(limit: 2)
|
28
|
+
.and_return(cache)
|
29
|
+
subject.set_cache(limit: 2)
|
30
|
+
expect(cache).to receive(:get).with(route: 'hello')
|
31
|
+
subject.get(route: 'hello')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.extended' do
|
36
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
37
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
38
|
+
|
39
|
+
it 'should set the cache for the class' do
|
40
|
+
test = Class.new
|
41
|
+
expect(test).to receive(:set_cache)
|
42
|
+
test.extend(subject)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
describe TaskHelper::Database do
|
2
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
3
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
4
|
+
|
5
|
+
describe '.all' do
|
6
|
+
it 'should return an array of databases' do
|
7
|
+
expect(described_class.all.first).to be_a(described_class)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should return databases corresponding to the API response' do
|
11
|
+
expect(described_class.all.map(&:to_h).to_json)
|
12
|
+
.to eq(FixtureParser.databases.to_json)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.find_by' do
|
17
|
+
it 'should return the corresponding database if found' do
|
18
|
+
db = described_class.all.sample
|
19
|
+
expect(described_class.find_by(name: db.name)).to eq(db)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should return nil if no database found' do
|
23
|
+
expect(described_class.find_by(name: 'odiasoutee')).to be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '.find_by_name' do
|
28
|
+
it 'should return the corresponding database if found' do
|
29
|
+
db = described_class.all.sample
|
30
|
+
expect(described_class.find_by_name(db.name)).to eq(db)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should return nil if no database found' do
|
34
|
+
expect(described_class.find_by_name('odiasoutee')).to be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '.find' do
|
39
|
+
it 'should return the corresponding database if found' do
|
40
|
+
db = described_class.all.sample
|
41
|
+
expect(described_class.find(db.id)).to eq(db)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should retrun nil if the database is not found' do
|
45
|
+
expect(described_class.find('hasdof')).to be_nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'data members' do
|
50
|
+
described_class.data_members.each do |m|
|
51
|
+
describe "##{m}" do
|
52
|
+
it "should return the value of #{m}" do
|
53
|
+
db = described_class.new(FixtureParser.databases.sample)
|
54
|
+
data = FixtureParser.pretty(:database, db.id)
|
55
|
+
expect(db.public_send(m)).to eq(data.send(m))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#created_at' do
|
62
|
+
it 'should return the parsed time of created_at' do
|
63
|
+
db = described_class.all.sample
|
64
|
+
db_hash = FixtureParser.database(db.id)
|
65
|
+
expect(db.created_at).to eq(Time.parse(db_hash['created_at']))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#updated_at' do
|
70
|
+
it 'should return the parsed time of updated_at' do
|
71
|
+
db = described_class.all.sample
|
72
|
+
db_hash = FixtureParser.database(db.id)
|
73
|
+
expect(db.updated_at).to eq(Time.parse(db_hash['updated_at']))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#forms' do
|
78
|
+
it 'should return all forms associated with the database' do
|
79
|
+
db = described_class.all.sample
|
80
|
+
forms = FixtureParser.pretty(:forms, db.id)
|
81
|
+
expect(db.forms.all? { |f| f.kind_of?(TaskHelper::Form) }).to be(true)
|
82
|
+
expect(db.forms).to match_array(forms)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should pre-load the form's database attribute" do
|
86
|
+
db = described_class.all.sample
|
87
|
+
expect(described_class).not_to receive(:find)
|
88
|
+
db.forms.first.database
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
describe TaskHelper::Field do
|
2
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
3
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
4
|
+
|
5
|
+
describe '.new' do
|
6
|
+
it 'should pass all params except form to super' do
|
7
|
+
form = TaskHelper::Form.all.first
|
8
|
+
field = described_class.new(name: 'foobar', form: form,
|
9
|
+
'entity_id' => form.id)
|
10
|
+
expect(field.name).to eq('foobar')
|
11
|
+
expect(field.entity_id).to eq(form.id)
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'given an optional form' do
|
15
|
+
it 'should store the form' do
|
16
|
+
form = TaskHelper::Form.all.first
|
17
|
+
expect(TaskHelper::Form).not_to receive(:find)
|
18
|
+
field = described_class.new(form: form)
|
19
|
+
expect(field.form).to eq(form)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'without optional form' do
|
24
|
+
it 'should fetch the form when needed' do
|
25
|
+
expect(TaskHelper::Form).to receive(:find).at_least(1)
|
26
|
+
described_class.new.form
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#form' do
|
32
|
+
it 'should return the associated form' do
|
33
|
+
field = described_class.new(FixtureParser.fields.sample)
|
34
|
+
expect(field.form).to be_a(TaskHelper::Form)
|
35
|
+
expect(field.form.id).to eq(field.entity_id)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'data members' do
|
40
|
+
described_class.data_members.each do |m|
|
41
|
+
describe "##{m}" do
|
42
|
+
it "should return the value of #{m}" do
|
43
|
+
field = described_class.new(FixtureParser.fields.sample)
|
44
|
+
data = FixtureParser.pretty(:field, field.id, field.entity_id)
|
45
|
+
expect(field.public_send(m)).to eq(data.send(m))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
describe TaskHelper::Form do
|
2
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
3
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
4
|
+
|
5
|
+
describe '.new' do
|
6
|
+
it 'should pass all params except database to super' do
|
7
|
+
db = TaskHelper::Database.all.sample
|
8
|
+
form = described_class.new(app_id: db.id, database: db,
|
9
|
+
'name' => 'foobar')
|
10
|
+
expect(form.app_id).to eq(db.id)
|
11
|
+
expect(form.name).to eq('foobar')
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'given an optional database' do
|
15
|
+
it 'should store the database' do
|
16
|
+
db = TaskHelper::Database.all.sample
|
17
|
+
expect(TaskHelper::Database).not_to receive(:find)
|
18
|
+
form = described_class.new(database: db)
|
19
|
+
expect(form.database).to eq(db)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'without optional database' do
|
24
|
+
it 'should fetch the database when needed' do
|
25
|
+
expect(TaskHelper::Database).to receive(:find)
|
26
|
+
described_class.new.database
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.all' do
|
32
|
+
it 'should return all forms for all databases' do
|
33
|
+
forms = FixtureParser.pretty(:forms)
|
34
|
+
expect(described_class.all.all? { |f| f.kind_of?(described_class) })
|
35
|
+
.to be(true)
|
36
|
+
expect(described_class.all).to match_array(forms)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should use a Lazy Enumerator' do
|
40
|
+
expect(described_class.all).to be_an(Enumerator::Lazy)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.find' do
|
45
|
+
it 'should return the corresponding form if found' do
|
46
|
+
form = FixtureParser.pretty(:forms).sample
|
47
|
+
result = described_class.find(database: form.app_id, form: form.id)
|
48
|
+
expect(result).to be_a(described_class)
|
49
|
+
expect(result).to eq(form)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should retrun nil if the form is not found' do
|
53
|
+
expect(described_class.find(database: 'hasdof', form: 'hasdof'))
|
54
|
+
.to be_nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '.find_by' do
|
59
|
+
it 'should return the corresponding form if found' do
|
60
|
+
form = FixtureParser.pretty(:forms).sample
|
61
|
+
db = FixtureParser.pretty(:database, form.app_id)
|
62
|
+
result = described_class.find_by(database_name: db.name,
|
63
|
+
form_name: form.name)
|
64
|
+
expect(result).to be_a(described_class)
|
65
|
+
expect(result).to eq(form)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should retrun nil if the form is not found' do
|
69
|
+
expect(described_class.find_by(database_name: 'hasdof',
|
70
|
+
form_name: 'hasdof')).to be_nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#database' do
|
75
|
+
it 'should return the database associated with the form' do
|
76
|
+
form = described_class.new(FixtureParser.forms.sample)
|
77
|
+
expect(form.database).to be_a(TaskHelper::Database)
|
78
|
+
expect(form.database.id).to eq(form.app_id)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#fields' do
|
83
|
+
it 'should return the associated fields' do
|
84
|
+
form = described_class.new(FixtureParser.forms.sample)
|
85
|
+
expect(form.fields.all? { |f| f.kind_of?(TaskHelper::Field) }).to be(true)
|
86
|
+
expect(form.fields.all? { |f| f.entity_id == form.id }).to be(true)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should pre-load the fields' form attribute" do
|
90
|
+
form = described_class.all.first
|
91
|
+
expect(described_class).not_to receive(:find)
|
92
|
+
form.fields.first.form
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#records' do
|
97
|
+
context 'form has no fields' do
|
98
|
+
it 'should return nil' do
|
99
|
+
if form = described_class.all.find { |f| f.fields.none? }
|
100
|
+
expect(form.records).to be(nil)
|
101
|
+
else
|
102
|
+
expect(TaskHelper::Field).to receive(:get).and_return('fields' => [])
|
103
|
+
expect(described_class.new.records).to be(nil)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'form has at least one field' do
|
109
|
+
it 'should return a lazy enumerator containing the associated records' do
|
110
|
+
if form = described_class.all.find { |f| f.fields.any? }
|
111
|
+
expect(form.records).to be_a(Enumerator::Lazy)
|
112
|
+
expect(form.records.first).to be_a(TaskHelper::Record)
|
113
|
+
expect(form.records.first.entity_id).to eq(form.id)
|
114
|
+
else
|
115
|
+
raise 'No forms with fields found'.inspect
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should pre-load the records' form attribute" do
|
120
|
+
if form = described_class.all.find { |f| f.fields.any? }
|
121
|
+
expect(described_class).not_to receive(:find)
|
122
|
+
form.records.first.form
|
123
|
+
else
|
124
|
+
raise 'No forms with fields found'.inspect
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'data members' do
|
131
|
+
described_class.data_members.each do |m|
|
132
|
+
describe "##{m}" do
|
133
|
+
it "should return the value of #{m}" do
|
134
|
+
form = described_class.new(FixtureParser.forms.sample)
|
135
|
+
data = FixtureParser.pretty(:form, form.id, form.database.id)
|
136
|
+
expect(form.public_send(m)).to eq(data.send(m))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
describe TaskHelper::Record do
|
2
|
+
before(:all) { TaskHelper::API.rest_api_key = 'foobar' }
|
3
|
+
after(:all) { TaskHelper::API.rest_api_key = nil }
|
4
|
+
|
5
|
+
let(:form) { TaskHelper::Form.all.find(:form_with_fields_needed) { |f| f.fields.any? } }
|
6
|
+
let(:data) { FixtureParser.pretty(:records, form.id, form.app_id).sample }
|
7
|
+
subject { described_class.new(data.to_h) }
|
8
|
+
|
9
|
+
describe '.new' do
|
10
|
+
it 'should pass all params except form to super' do
|
11
|
+
form = TaskHelper::Form.all.first
|
12
|
+
record = described_class.new(app_id: form.app_id, form: form,
|
13
|
+
'entity_id' => form.id)
|
14
|
+
expect(record.app_id).to eq(form.app_id)
|
15
|
+
expect(record.entity_id).to eq(form.id)
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'given an optional form' do
|
19
|
+
it 'should store the form' do
|
20
|
+
form = TaskHelper::Form.all.first
|
21
|
+
expect(TaskHelper::Form).not_to receive(:find)
|
22
|
+
record = described_class.new(form: form)
|
23
|
+
expect(record.form).to eq(form)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'without optional form' do
|
28
|
+
it 'should fetch the form when needed' do
|
29
|
+
expect(TaskHelper::Form).to receive(:find).at_least(1)
|
30
|
+
described_class.new.form
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#form' do
|
36
|
+
it 'should return the associated form' do
|
37
|
+
expect(subject.form).to eq(form)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#fields' do
|
42
|
+
it 'should return the fields of the associated form' do
|
43
|
+
expect(subject.fields).to match_array(form.fields)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#[]' do
|
48
|
+
it 'should return the value of the field with the given name' do
|
49
|
+
field = form.fields.sample
|
50
|
+
expect(subject[field.name]).to eq(subject.values[field.id])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#pretty_values' do
|
55
|
+
it 'should return the values hashed by field name' do
|
56
|
+
result = subject.values.each_with_object({}) do |(k, v), r|
|
57
|
+
field = form.fields.find { |f| f.id == k }
|
58
|
+
r[field.name] = v
|
59
|
+
end
|
60
|
+
expect(subject.pretty_values).to eq(result)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'data members' do
|
65
|
+
described_class.data_members.each do |m|
|
66
|
+
describe "##{m}" do
|
67
|
+
it "should return the value of #{m}" do
|
68
|
+
expect(subject.public_send(m)).to eq(data.public_send(m))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|