app_rail-airtable 0.1.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% authenticatable_table = @tables.select { |table| table['authenticatable'] == 'True' }&.first -%>
4
+ <% authenticatable_resource = authenticatable_table['name'] if authenticatable_table -%>
5
+ require 'spec_helper'
6
+
7
+ RSpec.describe Server do
8
+ let(:json_response) { JSON.parse(response.body, symbolize_names: true) }
9
+ let(:access_token) { SecureRandom.hex }
10
+ let(:auth_headers) { { 'HTTP_AUTHORIZATION' => "Bearer: #{access_token}" } }
11
+
12
+ def app
13
+ Server
14
+ end
15
+
16
+ <% if authenticatable_resource -%>
17
+ <% auth_model_name = authenticatable_resource.singularize -%>
18
+ <% auth_path_name = authenticatable_resource.snake_case.pluralize -%>
19
+ describe 'POST /<%= auth_path_name %>' do
20
+ let(:params) { { payload: { email: 'test@test.com', password: 'Secret000' } } }
21
+ let(:response) { post "/<%= auth_path_name %>", params.to_json }
22
+ let(:mock_resource) { double(<%= auth_model_name %>) }
23
+
24
+ before { allow_any_instance_of(<%= auth_model_name %>).to receive(:create) { mock_resource } }
25
+
26
+ it { expect(response.status).to eq 201 }
27
+ it { expect(json_response[:oauth_session][:access_token]).to_not be_nil }
28
+ end
29
+
30
+ describe 'POST /sessions' do
31
+ let(:params) { { username: 'test@test.com', password: 'Secret000' } }
32
+ let(:response) { post "/sessions", params }
33
+
34
+ context 'ok' do
35
+ let(:oauth_session) { { access_token: SecureRandom.hex } }
36
+
37
+ before { allow(<%= auth_model_name %>).to receive(:create_session_as_json).with({ email: params[:username], password: params[:password] }) { oauth_session } }
38
+
39
+ it { expect(response.status).to eq 200 }
40
+ it { expect(json_response[:access_token]).to_not be_nil }
41
+ end
42
+
43
+ context 'invalid' do
44
+ before { allow(<%= auth_model_name %>).to receive(:create_session_as_json).with({ email: params[:username], password: params[:password] }) { nil } }
45
+
46
+ it { expect(response.status).to eq 401 }
47
+ it { expect(response.body).to eq '' }
48
+ end
49
+ end
50
+
51
+ <% @tables.each do |table| -%>
52
+ <% next if table['name'] == authenticatable_resource -%>
53
+ <% model_name = table['name'].singularize -%>
54
+ <% path_name = table['name'].snake_case.pluralize -%>
55
+ describe 'GET /<%= path_name %>' do
56
+ let(:params) { {} }
57
+ let(:response) { get '/<%= path_name %>', params.to_json, auth_headers}
58
+ let(:mock_auth_resource) { double(<%= auth_model_name %>) }
59
+ let(:mock_resource) { double(<%= model_name %>, id: '1') }
60
+ let(:resource_to_json) { { id: '1' } }
61
+
62
+ before do
63
+ allow(<%= auth_model_name %>).to receive(:find_by_access_token).with(access_token) { mock_auth_resource }
64
+ allow(<%= model_name %>).to receive(:all) { [mock_resource] }
65
+ allow(mock_resource).to receive(:ar_list_item_as_json) { resource_to_json }
66
+ end
67
+
68
+ it { expect(response.status).to eq 200 }
69
+ it { expect(json_response).to eq [resource_to_json] }
70
+ end
71
+
72
+ describe 'PUT /<%= path_name %>/:id"' do
73
+ let(:params) { <%= fields_as_params_examples(table['fields']) %> }
74
+ let(:response) { put "/<%= path_name %>/#{id}", params.to_json, headers }
75
+ let(:mock_auth_resource) { instance_double(<%= auth_model_name %>) }
76
+ let(:mock_resource) { instance_double(<%= model_name %>, id: id) }
77
+ let(:resource_to_json) { { id: id } }
78
+ let(:headers) { auth_headers.merge('CONTENT_TYPE' => 'application/json') }
79
+ let(:id) { '1' }
80
+
81
+ before do
82
+ allow(<%= auth_model_name %>).to receive(:find_by_access_token).with(access_token) { mock_auth_resource }
83
+ allow(<%= model_name %>).to receive(:find).with(id) { mock_resource }
84
+ allow(mock_resource).to receive(:update_as_json).with(current_user: mock_auth_resource, params: { 'id' => '1' }.merge(params)) { resource_to_json }
85
+ end
86
+
87
+ it { expect(response.status).to eq 200 }
88
+ it { expect(json_response).to eq resource_to_json }
89
+ end
90
+ <% end -%>
91
+ <% else -%>
92
+ <% @tables.each do |table| -%>
93
+ <% model_name = table['name'].singularize -%>
94
+ <% path_name = table['name'].snake_case.pluralize -%>
95
+ describe 'GET /<%= path_name %>' do
96
+ let(:params) { {} }
97
+ let(:response) { get '/<%= path_name %>', params.to_json, auth_headers}
98
+ let(:mock_resource) { double(<%= model_name %>, id: '1') }
99
+ let(:resource_to_json) { { id: '1' } }
100
+
101
+ before do
102
+ allow(<%= model_name %>).to receive(:all) { [mock_resource] }
103
+ allow(mock_resource).to receive(:ar_list_item_as_json) { resource_to_json }
104
+ end
105
+
106
+ it { expect(response.status).to eq 200 }
107
+ it { expect(json_response).to eq [resource_to_json] }
108
+ end
109
+
110
+ describe 'PUT /<%= path_name %>/:id"' do
111
+ let(:params) { <%= fields_as_params_examples(table['fields']) %> }
112
+ let(:response) { put "/<%= path_name %>/#{id}", params.to_json, headers }
113
+ let(:mock_resource) { instance_double(<%= model_name %>, id: id) }
114
+ let(:resource_to_json) { { id: id } }
115
+ let(:headers) { auth_headers.merge('CONTENT_TYPE' => 'application/json') }
116
+ let(:id) { '1' }
117
+
118
+ before do
119
+ allow(<%= model_name %>).to receive(:find).with(id) { mock_resource }
120
+ allow(mock_resource).to receive(:update_as_json).with(current_user: mock_auth_resource, params: { 'id' => '1' }.merge(params)) { resource_to_json }
121
+ end
122
+
123
+ it { expect(response.status).to eq 200 }
124
+ it { expect(json_response).to eq resource_to_json }
125
+ end
126
+ <% end -%>
127
+ <% end -%>
128
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
6
+ # this file to always be loaded, without a need to explicitly require it in any
7
+ # files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need
15
+ # it.
16
+ #
17
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
18
+
19
+ # Dummy ENV Setup
20
+ ENV['AIRTABLE_API_KEY'] = 'keyABC123'
21
+ ENV['AIRTABLE_BASE_ID'] = 'appABC123'
22
+ ENV['RACK_ENV'] = 'test'
23
+
24
+ require 'rack/test'
25
+ require 'app_rail/airtable'
26
+ require 'byebug'
27
+
28
+ require './lib/server'
29
+
30
+ RSpec.configure do |config|
31
+ # rspec-expectations config goes here. You can use an alternate
32
+ # assertion/expectation library such as wrong or the stdlib/minitest
33
+ # assertions if you prefer.
34
+ config.expect_with :rspec do |expectations|
35
+ # This option will default to `true` in RSpec 4. It makes the `description`
36
+ # and `failure_message` of custom matchers include text for helper methods
37
+ # defined using `chain`, e.g.:
38
+ # be_bigger_than(2).and_smaller_than(4).description
39
+ # # => "be bigger than 2 and smaller than 4"
40
+ # ...rather than:
41
+ # # => "be bigger than 2"
42
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
43
+ end
44
+
45
+ # rspec-mocks config goes here. You can use an alternate test double
46
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
47
+ config.mock_with :rspec do |mocks|
48
+ # Prevents you from mocking or stubbing a method that does not exist on
49
+ # a real object. This is generally recommended, and will default to
50
+ # `true` in RSpec 4.
51
+ mocks.verify_partial_doubles = true
52
+ end
53
+
54
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
55
+ # have no way to turn it off -- the option exists only for backwards
56
+ # compatibility in RSpec 3). It causes shared context metadata to be
57
+ # inherited by the metadata hash of host groups and examples, rather than
58
+ # triggering implicit auto-inclusion in groups with matching metadata.
59
+ config.shared_context_metadata_behavior = :apply_to_host_groups
60
+
61
+ # The settings below are suggested to provide a good initial experience
62
+ # with RSpec, but feel free to customize to your heart's content.
63
+ # # This allows you to limit a spec run to individual examples or groups
64
+ # # you care about by tagging them with `:focus` metadata. When nothing
65
+ # # is tagged with `:focus`, all examples get run. RSpec also provides
66
+ # # aliases for `it`, `describe`, and `context` that include `:focus`
67
+ # # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
68
+ # config.filter_run_when_matching :focus
69
+ #
70
+ # # Allows RSpec to persist some state between runs in order to support
71
+ # # the `--only-failures` and `--next-failure` CLI options. We recommend
72
+ # # you configure your source control system to ignore this file.
73
+ # config.example_status_persistence_file_path = "spec/examples.txt"
74
+ #
75
+ # # Limits the available syntax to the non-monkey patched syntax that is
76
+ # # recommended. For more details, see:
77
+ # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
78
+ # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
79
+ # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
80
+ # config.disable_monkey_patching!
81
+ #
82
+ # # This setting enables warnings. It's recommended, but in some cases may
83
+ # # be too noisy due to issues in dependencies.
84
+ # config.warnings = true
85
+ #
86
+ # # Many RSpec users commonly either run the entire suite or an individual
87
+ # # file, and it's useful to allow more verbose output when running an
88
+ # # individual spec file.
89
+ # if config.files_to_run.one?
90
+ # # Use the documentation formatter for detailed output,
91
+ # # unless a formatter has already been configured
92
+ # # (e.g. via a command-line flag).
93
+ # config.default_formatter = "doc"
94
+ # end
95
+ #
96
+ # # Print the 10 slowest examples and example groups at the
97
+ # # end of the spec run, to help surface which specs are running
98
+ # # particularly slow.
99
+ # config.profile_examples = 10
100
+ #
101
+ # # Run specs in random order to surface order dependencies. If you find an
102
+ # # order dependency and want to debug it, you can fix the order by providing
103
+ # # the seed, which is printed after each run.
104
+ # # --seed 1234
105
+ # config.order = :random
106
+ #
107
+ # # Seed global randomization in this process using the `--seed` CLI option.
108
+ # # Setting this allows you to use `--seed` to deterministically reproduce
109
+ # # test failures related to randomization by passing the same `--seed` value
110
+ # # as the one that triggered the failure.
111
+ # Kernel.srand config.seed
112
+
113
+ config.include Rack::Test::Methods
114
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app_rail-airtable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brooke-Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-15 00:00:00.000000000 Z
11
+ date: 2022-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,76 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: airrecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: app_rail-steps
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bcrypt
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: faraday
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.2'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: faraday-net_http_persistent
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
27
97
  - !ruby/object:Gem::Dependency
28
98
  name: sinatra
29
99
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +109,7 @@ dependencies:
39
109
  - !ruby/object:Gem::Version
40
110
  version: '0'
41
111
  - !ruby/object:Gem::Dependency
42
- name: airrecord
112
+ name: thor
43
113
  requirement: !ruby/object:Gem::Requirement
44
114
  requirements:
45
115
  - - ">="
@@ -53,7 +123,7 @@ dependencies:
53
123
  - !ruby/object:Gem::Version
54
124
  version: '0'
55
125
  - !ruby/object:Gem::Dependency
56
- name: rspec
126
+ name: rack-test
57
127
  requirement: !ruby/object:Gem::Requirement
58
128
  requirements:
59
129
  - - ">="
@@ -67,7 +137,7 @@ dependencies:
67
137
  - !ruby/object:Gem::Version
68
138
  version: '0'
69
139
  - !ruby/object:Gem::Dependency
70
- name: rack-test
140
+ name: rspec
71
141
  requirement: !ruby/object:Gem::Requirement
72
142
  requirements:
73
143
  - - ">="
@@ -83,7 +153,8 @@ dependencies:
83
153
  description:
84
154
  email:
85
155
  - matt@futureworkshops.com
86
- executables: []
156
+ executables:
157
+ - ara_generator
87
158
  extensions: []
88
159
  extra_rdoc_files: []
89
160
  files:
@@ -91,18 +162,36 @@ files:
91
162
  - ".gitignore"
92
163
  - ".rspec"
93
164
  - ".travis.yml"
165
+ - CHANGELOG.md
94
166
  - Gemfile
95
167
  - Gemfile.lock
96
168
  - LICENSE.txt
97
169
  - README.md
98
170
  - Rakefile
99
171
  - app_rail-airtable.gemspec
172
+ - bin/ara_generator
100
173
  - bin/console
101
174
  - bin/setup
175
+ - examples/schemas/daily_logs.json
176
+ - examples/schemas/locations.json
177
+ - examples/schemas/users.json
102
178
  - lib/app_rail/airtable.rb
103
179
  - lib/app_rail/airtable/application_record.rb
180
+ - lib/app_rail/airtable/authenticatable.rb
181
+ - lib/app_rail/airtable/authentication_helpers.rb
182
+ - lib/app_rail/airtable/generator.rb
104
183
  - lib/app_rail/airtable/sinatra.rb
184
+ - lib/app_rail/airtable/string_ext.rb
105
185
  - lib/app_rail/airtable/version.rb
186
+ - templates/project/.env.tt
187
+ - templates/project/.gitignore
188
+ - templates/project/Gemfile
189
+ - templates/project/app.json
190
+ - templates/project/boot.rb
191
+ - templates/project/config.ru
192
+ - templates/project/lib/server.rb.tt
193
+ - templates/project/spec/server_spec.rb.tt
194
+ - templates/project/spec/spec_helper.rb
106
195
  homepage: https://github.com/FutureWorkshops/app_rail-airtable
107
196
  licenses:
108
197
  - MIT
@@ -124,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
213
  - !ruby/object:Gem::Version
125
214
  version: '0'
126
215
  requirements: []
127
- rubygems_version: 3.1.6
216
+ rubygems_version: 3.3.7
128
217
  signing_key:
129
218
  specification_version: 4
130
219
  summary: Gem to help building App Rail servers using Airtable as a backend