app_rail-airtable 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2222da161b570e211092bd349e148d95a4101bfb927ec04af296b6bf3037adf
4
- data.tar.gz: 8d040716239e2321007c4f4d534002f42ba0f5ee8995739be252365911949330
3
+ metadata.gz: 5154709a34596c961227e058380aa927b7643df717e67289a6158b43f65b2213
4
+ data.tar.gz: 39b53b565d80d517aedc654f04b21f7d64189c4b0b62bd30ec1ea53252e9c1bb
5
5
  SHA512:
6
- metadata.gz: b3844eb828e7aefe01844aedd2d934c72d9956d32e68f2f37747513d65947912b453e7f02f5ff7efae502fec6a9fbf66996d603ceabfe6c3fe352a6d628c5433
7
- data.tar.gz: 142a3e8d514df35ffd9d52d3904ae370c3be998437115aad786d4770c3664fd933dd337468441c665e7e32eb85a5a66b0bb849447254934f09b1ee13e7f06533
6
+ metadata.gz: 68bfcd69273296c2eca597bf4bceb3bfefdd41f153d94a020f96e2604e8dcf7426359ea74e4ddcab6197a7ecf3f319dbefe204af1f9471b31cd83d921afaa87c
7
+ data.tar.gz: 23ce7443a261f2eb431c42f2904d1b7d31a98c843adb3e601c6d2cc6610a02d15597e4b65bef49dffb4d599df17a07b97bb0550d66b5f4eb122c66141b94a6ab
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # 0.4.0
2
+
3
+ ### Breaking changes
4
+ * `AppRail::Airtable::Sinatra` `.resources` and `.authenticable_resources` `only` argument defaults to `[:index, :show, :create, :update]` instead of `[:index, :show, :create]`
5
+
6
+ ### New features
7
+ * Add `Authenticatable#initialize` method to initialize an Airrecord record without persisting it to airtable
8
+ * Add `update` route (`PUT`), which points to the corresponding model method `self.update_as_json`
9
+
data/Gemfile.lock CHANGED
@@ -1,62 +1,47 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- app_rail-airtable (0.3.5)
4
+ app_rail-airtable (0.4.0)
5
5
  activesupport
6
6
  airrecord
7
7
  bcrypt
8
+ faraday (~> 2.2)
9
+ faraday-net_http_persistent (~> 2.0)
8
10
  sinatra
9
11
  thor
10
12
 
11
13
  GEM
12
14
  remote: https://rubygems.org/
13
15
  specs:
14
- activesupport (7.0.1)
16
+ activesupport (7.0.2.2)
15
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
16
18
  i18n (>= 1.6, < 2)
17
19
  minitest (>= 5.1)
18
20
  tzinfo (~> 2.0)
19
- airrecord (1.0.7)
20
- faraday (>= 0.10, < 2.0)
21
+ airrecord (1.0.8)
22
+ faraday (>= 0.10, < 3.0)
21
23
  net-http-persistent
22
24
  bcrypt (3.1.16)
23
25
  byebug (11.1.3)
24
26
  concurrent-ruby (1.1.9)
25
27
  connection_pool (2.2.5)
26
28
  diff-lcs (1.4.4)
27
- faraday (1.9.3)
28
- faraday-em_http (~> 1.0)
29
- faraday-em_synchrony (~> 1.0)
30
- faraday-excon (~> 1.1)
31
- faraday-httpclient (~> 1.0)
32
- faraday-multipart (~> 1.0)
33
- faraday-net_http (~> 1.0)
34
- faraday-net_http_persistent (~> 1.0)
35
- faraday-patron (~> 1.0)
36
- faraday-rack (~> 1.0)
37
- faraday-retry (~> 1.0)
29
+ faraday (2.2.0)
30
+ faraday-net_http (~> 2.0)
38
31
  ruby2_keywords (>= 0.0.4)
39
- faraday-em_http (1.0.0)
40
- faraday-em_synchrony (1.0.0)
41
- faraday-excon (1.1.0)
42
- faraday-httpclient (1.0.1)
43
- faraday-multipart (1.0.3)
44
- multipart-post (>= 1.2, < 3)
45
- faraday-net_http (1.0.1)
46
- faraday-net_http_persistent (1.2.0)
47
- faraday-patron (1.0.0)
48
- faraday-rack (1.0.0)
49
- faraday-retry (1.0.3)
50
- i18n (1.8.11)
32
+ faraday-net_http (2.0.1)
33
+ faraday-net_http_persistent (2.0.1)
34
+ faraday-net_http
35
+ net-http-persistent (~> 4.0)
36
+ i18n (1.10.0)
51
37
  concurrent-ruby (~> 1.0)
52
38
  minitest (5.15.0)
53
- multipart-post (2.1.1)
54
39
  mustermann (1.1.1)
55
40
  ruby2_keywords (~> 0.0.1)
56
41
  net-http-persistent (4.0.1)
57
42
  connection_pool (~> 2.2)
58
43
  rack (2.2.3)
59
- rack-protection (2.1.0)
44
+ rack-protection (2.2.0)
60
45
  rack
61
46
  rack-test (1.1.0)
62
47
  rack (>= 1.0, < 3)
@@ -75,10 +60,10 @@ GEM
75
60
  rspec-support (~> 3.10.0)
76
61
  rspec-support (3.10.2)
77
62
  ruby2_keywords (0.0.5)
78
- sinatra (2.1.0)
63
+ sinatra (2.2.0)
79
64
  mustermann (~> 1.0)
80
65
  rack (~> 2.2)
81
- rack-protection (= 2.1.0)
66
+ rack-protection (= 2.2.0)
82
67
  tilt (~> 2.0)
83
68
  thor (1.1.0)
84
69
  tilt (2.0.10)
data/README.md CHANGED
@@ -2,10 +2,6 @@
2
2
 
3
3
  App Rail Airtable is a micro-framework based on Sinatra and [Airrecord](https://github.com/sirupsen/airrecord) which faciliates use of Airtable as a backend for App Rail Apps. You can deploy a template repo to Heroku for fast start.
4
4
 
5
- ## Quick Start
6
-
7
- Visit [App Rail Airtable Template](https://github.com/FutureWorkshops/AppRailAirtableTemplate) and follow instructions.
8
-
9
5
  ## Installation
10
6
 
11
7
  Add this line to your application's Gemfile:
@@ -16,7 +12,7 @@ gem 'app_rail-airtable'
16
12
 
17
13
  ## Usage
18
14
 
19
- App Rail Airtable has two important concepts, models and servers. The [App Rail Petshop](https://github.com/FutureWorkshops/ar-petshop-airtable) provides useful examples.
15
+ App Rail Airtable has two important concepts, models and servers.
20
16
 
21
17
  ### Models
22
18
  App Rail Airtable makes the following assumptions
@@ -32,6 +28,7 @@ To provide support for routes, models can implement
32
28
  * ar_list_item (index)
33
29
  * ar_stack (show)
34
30
  * self.create_as_json (create)
31
+ * self.update_as_json (update)
35
32
 
36
33
  In order to support authentication you should create a class (normally `User`) and inherit from `AppRail::Airtable::AuthenticationRecord`. Your table needs `Email`, `Password Hash` and `Access Token` columns.
37
34
 
@@ -45,10 +42,47 @@ Creates routes that map to a table. It delegates from the route to a model metho
45
42
  * `index` to `ar_list_item`
46
43
  * `show` to `ar_stack`
47
44
  * `create` to `self.create_as_json`
45
+ * `update` to `self.update_as_json`
48
46
 
49
47
  **authenticable_resources(name, , only:)**
50
48
  Acts as `resources` but also takes a block of routes. Those nested routes will all call the `authenticate!` helper method before running. The `authenticate!` helper will call a lookup helper `find_authenticatable_resource(access_token:)` with the bearer token found in the `HTTP_AUTHORIZATION` header, which should be used to look up the correct object or return nil if none is found (resulting in a 401 response).
51
49
 
50
+ ### Generator
51
+
52
+ ```bash
53
+ bin/ara_generator <output_directory> <airtable_api_key> <airtable_base_id> [<json_schema>]
54
+ ```
55
+
56
+ #### Example
57
+
58
+ ```bash
59
+ bin/ara_generator ./test key1234567890 appwertyuiop '{"tables": [{"name": "DailyLogs", "fields": [{"name": "Date", "type": "date"}, {"name": "Score", "type": "integer"}], "associations": [{"name": "User", "type": "belongs_to", "model": "User"}], "ar_class_methods": [{"name": "ar_list_item", "properties": [{"type": "text", "value": "date"}, {"type": "detail_text", "value": "score"}]}], "ar_instance_methods": [{"name": "ar_stack_item", "properties": [{"type": "text", "label": "Date", "value": "date"}, {"type": "button", "label": "Score", "value": "score", "modalWorkflow": "", "style": "primary", "onSuccess": "forward", "sfSymbolName": ""}]}]}, {"name": "Users", "fields": [{"name": "Email", "type": "string"}, {"name": "Password Hash", "type": "string"}, {"name": "Access Token", "type": "string"}], "associations": [{"name": "DailyLogs", "type": "has_many", "model": "DailyLog"}], "authenticatable": "True"}]}'
60
+ ```
61
+
62
+ You can find more examples of schemas in [/examples/schemas](/examples/schemas)
63
+
64
+ ## Debugging
65
+
66
+ ### Listing Existing Routes
67
+ To get a complete list of the available routes in your Sinatra application, run the following code snippet:
68
+ ```ruby
69
+ Server.routes.map do |method, routes|
70
+ routes.map { |r| r.first.to_s }.map do |route|
71
+ "#{method.rjust(7, ' ')} #{route}"
72
+ end
73
+ end.flatten.sort.each do |route|
74
+ puts route
75
+ end
76
+ ```
77
+ Output:
78
+ ```
79
+ GET /mock_items
80
+ GET /mock_items/:id
81
+ PUT /mock_items/:id
82
+ HEAD /mock_items
83
+ HEAD /mock_items/:id
84
+ POST /mock_items
85
+ ```
52
86
  ## License
53
87
 
54
88
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -27,6 +27,8 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency 'activesupport'
28
28
  spec.add_dependency 'sinatra'
29
29
  spec.add_dependency 'airrecord'
30
+ spec.add_dependency 'faraday', '~> 2.2'
31
+ spec.add_dependency 'faraday-net_http_persistent', '~> 2.0' # workaround to make Faraday work after upgrading to 2.2.0
30
32
  spec.add_dependency 'thor'
31
33
  spec.add_dependency 'bcrypt'
32
34
 
@@ -0,0 +1,86 @@
1
+ {
2
+ "tables": [
3
+ {
4
+ "name": "DailyLogs",
5
+ "fields": [
6
+ {
7
+ "name": "Date",
8
+ "type": "date"
9
+ },
10
+ {
11
+ "name": "Score",
12
+ "type": "integer"
13
+ }
14
+ ],
15
+ "associations": [
16
+ {
17
+ "name": "User",
18
+ "type": "belongs_to",
19
+ "model": "User"
20
+ }
21
+ ],
22
+ "ar_class_methods": [
23
+ {
24
+ "name": "ar_list_item",
25
+ "properties": [
26
+ {
27
+ "type": "text",
28
+ "value": "date"
29
+ },
30
+ {
31
+ "type": "detail_text",
32
+ "value": "score"
33
+ }
34
+ ]
35
+ }
36
+ ],
37
+ "ar_instance_methods": [
38
+ {
39
+ "name": "ar_stack_item",
40
+ "properties": [
41
+ {
42
+ "type": "text",
43
+ "label": "Date",
44
+ "value": "date"
45
+ },
46
+ {
47
+ "type": "button",
48
+ "label": "Score",
49
+ "value": "score",
50
+ "modalWorkflow": "",
51
+ "style": "primary",
52
+ "onSuccess": "forward",
53
+ "sfSymbolName": ""
54
+ }
55
+ ]
56
+ }
57
+ ],
58
+ "authenticatable": "True"
59
+ },
60
+ {
61
+ "name": "Users",
62
+ "fields": [
63
+ {
64
+ "name": "Email",
65
+ "type": "string"
66
+ },
67
+ {
68
+ "name": "Password Hash",
69
+ "type": "string"
70
+ },
71
+ {
72
+ "name": "Access Token",
73
+ "type": "string"
74
+ }
75
+ ],
76
+ "associations": [
77
+ {
78
+ "name": "DailyLogs",
79
+ "type": "has_many",
80
+ "model": "DailyLog"
81
+ }
82
+ ],
83
+ "authenticatable": "True"
84
+ }
85
+ ]
86
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "tables": [
3
+ {
4
+ "name": "DailyLogs",
5
+ "fields": [
6
+ {
7
+ "name": "Date",
8
+ "type": "date"
9
+ },
10
+ {
11
+ "name": "Score",
12
+ "type": "integer"
13
+ }
14
+ ],
15
+ "associations": [
16
+ {
17
+ "name": "User",
18
+ "type": "belongs_to",
19
+ "model": "User"
20
+ }
21
+ ],
22
+ "ar_class_methods": [
23
+ {
24
+ "name": "ar_list_item",
25
+ "properties": [
26
+ {
27
+ "type": "text",
28
+ "value": "date"
29
+ },
30
+ {
31
+ "type": "detail_text",
32
+ "value": "score"
33
+ }
34
+ ]
35
+ }
36
+ ],
37
+ "ar_instance_methods": [
38
+ {
39
+ "name": "ar_stack_item",
40
+ "properties": [
41
+ {
42
+ "type": "text",
43
+ "label": "Date",
44
+ "value": "date"
45
+ },
46
+ {
47
+ "type": "button",
48
+ "label": "Score",
49
+ "value": "score",
50
+ "modalWorkflow": "",
51
+ "style": "primary",
52
+ "onSuccess": "forward",
53
+ "sfSymbolName": ""
54
+ }
55
+ ]
56
+ }
57
+ ]
58
+ },
59
+ {
60
+ "name": "Users",
61
+ "fields": [
62
+ {
63
+ "name": "Email",
64
+ "type": "string"
65
+ },
66
+ {
67
+ "name": "Password Hash",
68
+ "type": "string"
69
+ },
70
+ {
71
+ "name": "Access Token",
72
+ "type": "string"
73
+ }
74
+ ],
75
+ "associations": [
76
+ {
77
+ "name": "DailyLogs",
78
+ "type": "has_many",
79
+ "model": "DailyLog"
80
+ }
81
+ ],
82
+ "authenticatable": "True"
83
+ }
84
+ ]
85
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "tables": [
3
+ {
4
+ "name": "Users",
5
+ "fields": [
6
+ {
7
+ "name": "Forename",
8
+ "type": "string"
9
+ },
10
+ {
11
+ "name": "Surname",
12
+ "type": "string"
13
+ },
14
+ {
15
+ "name": "NHS Number",
16
+ "type": "integer"
17
+ },
18
+ {
19
+ "name": "Date of Birth",
20
+ "type": "date"
21
+ },
22
+ {
23
+ "name": "Vaccine",
24
+ "type": "string"
25
+ }
26
+ ],
27
+ "associations": [
28
+ {
29
+ "name": "Vaccination Appointments",
30
+ "type": "has_many",
31
+ "model": "VaccinationAppointment"
32
+ }
33
+ ],
34
+ "ar_class_methods": [
35
+ {
36
+ "name": "ar_list_item",
37
+ "properties": [
38
+ {
39
+ "type": "text",
40
+ "value": "forename"
41
+ },
42
+ {
43
+ "type": "detail_text",
44
+ "value": "surname"
45
+ }
46
+ ]
47
+ }
48
+ ]
49
+ }
50
+ ]
51
+ }
@@ -8,11 +8,12 @@ module AppRail
8
8
 
9
9
  def self.included(klass)
10
10
  klass.extend(ClassMethods)
11
+ klass.prepend(InstanceMethods) # prepends `initialize` instance method in order to take precedence over Airrecord::Table#initialize
11
12
  end
12
13
 
13
14
  module ClassMethods
14
15
  def create(email:, password:)
15
- user = User.new("Email" => email, "Password Hash" => password_hash(password), "Access Token" => next_access_token)
16
+ user = new("Email" => email, "Password Hash" => password_hash(password), "Access Token" => next_access_token)
16
17
  user.create
17
18
  user
18
19
  end
@@ -28,7 +29,7 @@ module AppRail
28
29
 
29
30
  def find_by_email_and_password(email, password)
30
31
  user = all(filter: "{Email} = \"#{email}\"").first
31
- user.valid_password?(password) ? user : nil
32
+ user&.valid_password?(password) ? user : nil
32
33
  end
33
34
 
34
35
  def find_by_access_token(access_token)
@@ -43,7 +44,17 @@ module AppRail
43
44
  SecureRandom.hex
44
45
  end
45
46
  end
46
-
47
+
48
+ module InstanceMethods
49
+ def initialize(*args)
50
+ if (kwargs = args.first) && kwargs.is_a?(Hash) && kwargs.size == 2 && kwargs.key?(:email) && kwargs.key?(:password)
51
+ super("Email" => kwargs[:email], "Password Hash" => self.class.password_hash(kwargs[:password]), "Access Token" => self.class.next_access_token)
52
+ else
53
+ super
54
+ end
55
+ end
56
+ end
57
+
47
58
  def valid_password?(password)
48
59
  BCrypt::Password.new(password_hash) == password
49
60
  end
@@ -13,7 +13,7 @@ module AppRail
13
13
  argument :output_directory
14
14
  argument :api_key
15
15
  argument :base_id
16
- argument :schema
16
+ argument :schema, required: false
17
17
 
18
18
  def self.source_root
19
19
  File.join(File.dirname(__FILE__), '..', '..', '..')
@@ -41,7 +41,7 @@ module AppRail
41
41
  end
42
42
 
43
43
  def tables
44
- @tables ||= JSON.parse(schema)['tables']
44
+ @tables ||= schema ? JSON.parse(schema)['tables'] : []
45
45
  end
46
46
 
47
47
  def find_table(table_name)
@@ -55,6 +55,21 @@ module AppRail
55
55
  raise "ERROR! The key \"#{key}\" is not present in the schema definition."
56
56
  end
57
57
  end
58
+
59
+ def fields_as_params_examples(fields)
60
+ fields.each_with_object({}) do |field, hsh|
61
+ hsh[field['name']] = case field['type']
62
+ when 'date'
63
+ '01/01/2022'
64
+ when 'string', 'text'
65
+ 'MyString'
66
+ when 'integer'
67
+ 10
68
+ else
69
+ 'MyString'
70
+ end
71
+ end
72
+ end
58
73
  end
59
74
  end
60
75
  end
@@ -37,7 +37,7 @@ module AppRail
37
37
  end
38
38
  end
39
39
 
40
- def self.authenticatable_resources(name, only: [:index, :show, :create])
40
+ def self.authenticatable_resources(name, only: [:index, :show, :create, :update])
41
41
 
42
42
  # If authentication is used then include the correct helpers
43
43
  # Allowing the routes to use `authenticate!` and `current_user`
@@ -51,12 +51,13 @@ module AppRail
51
51
  @@authenticated_route = false
52
52
  end
53
53
 
54
- def self.resources(name, only: [:index, :show, :create])
54
+ def self.resources(name, only: [:index, :show, :create, :update])
55
55
  only = [only] if only.is_a?(Symbol)
56
-
56
+
57
57
  index_route(name, authenticated_route?) if only.include?(:index)
58
58
  show_route(name, authenticated_route?) if only.include?(:show)
59
59
  create_route(name, authenticated_route?) if only.include?(:create)
60
+ update_route(name, authenticated_route?) if only.include?(:update)
60
61
  end
61
62
 
62
63
  def self.index_route(name, authenticated_route)
@@ -80,7 +81,16 @@ module AppRail
80
81
  [201, as_json.to_json]
81
82
  end
82
83
  end
83
-
84
+
85
+ def self.update_route(name, authenticated_route)
86
+ put "/#{name.to_s}/:id" do
87
+ authenticate! if authenticated_route
88
+ record = name.classify_constantize.find(params['id'])
89
+ as_json = record.update_as_json(current_user: authenticated_route ? current_user : nil, params: params_and_body_as_json)
90
+ [200, as_json.to_json]
91
+ end
92
+ end
93
+
84
94
  def self.authenticated_route?
85
95
  @@authenticated_route
86
96
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AppRail
2
4
  module Airtable
3
- VERSION = "0.3.5"
5
+ VERSION = '0.4.0'
4
6
  end
5
7
  end
@@ -5,7 +5,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
5
 
6
6
  ruby '2.7.4'
7
7
 
8
- gem 'app_rail-airtable', '~> 0.3.3'
8
+ gem 'app_rail-airtable', '~> 0.4.0'
9
9
 
10
10
  group :development do
11
11
  gem 'dotenv'
@@ -10,7 +10,7 @@ GEM
10
10
  airrecord (1.0.7)
11
11
  faraday (>= 0.10, < 2.0)
12
12
  net-http-persistent
13
- app_rail-airtable (0.3.3)
13
+ app_rail-airtable (0.4.0)
14
14
  activesupport
15
15
  airrecord
16
16
  bcrypt
@@ -83,7 +83,7 @@ PLATFORMS
83
83
  ruby
84
84
 
85
85
  DEPENDENCIES
86
- app_rail-airtable (~> 0.3.3)
86
+ app_rail-airtable (~> 0.4.0)
87
87
  byebug
88
88
  dotenv
89
89
  rack-test
@@ -25,6 +25,12 @@ class <%= table['name'].singularize %> < AppRail::Airtable::ApplicationRecord
25
25
  record = <%= table['name'].singularize %>.create(email: params["payload"]["email"], password: params["payload"]["password"])
26
26
  { response: { id: record.id }, oauth_session: record.oauth_session}
27
27
  end
28
+
29
+ def update_as_json(params:, current_user:)
30
+ params['payload'].each { |attr, v| public_send("#{attr}=", v) }
31
+ save
32
+ { response: { id: id }, oauth_session: oauth_session }
33
+ end
28
34
  <% end -%>
29
35
  end
30
36
 
@@ -69,6 +69,24 @@ RSpec.describe Server do
69
69
  it { expect(json_response).to eq [resource_to_json] }
70
70
  end
71
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
72
90
  <% end -%>
73
91
  <% else -%>
74
92
  <% @tables.each do |table| -%>
@@ -89,6 +107,22 @@ RSpec.describe Server do
89
107
  it { expect(json_response).to eq [resource_to_json] }
90
108
  end
91
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
92
126
  <% end -%>
93
127
  <% end -%>
94
128
  end
@@ -21,6 +21,7 @@ ENV['RACK_ENV'] = 'test'
21
21
 
22
22
  require "rack/test"
23
23
  require "app_rail/airtable"
24
+ require "byebug"
24
25
 
25
26
  require './lib/server'
26
27
 
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.3.5
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brooke-Smith
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-24 00:00:00.000000000 Z
11
+ date: 2022-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faraday
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: faraday-net_http_persistent
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: thor
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +136,7 @@ dependencies:
108
136
  - - ">="
109
137
  - !ruby/object:Gem::Version
110
138
  version: '0'
111
- description:
139
+ description:
112
140
  email:
113
141
  - matt@futureworkshops.com
114
142
  executables:
@@ -120,6 +148,7 @@ files:
120
148
  - ".gitignore"
121
149
  - ".rspec"
122
150
  - ".travis.yml"
151
+ - CHANGELOG.md
123
152
  - Gemfile
124
153
  - Gemfile.lock
125
154
  - LICENSE.txt
@@ -129,6 +158,9 @@ files:
129
158
  - bin/ara_generator
130
159
  - bin/console
131
160
  - bin/setup
161
+ - examples/schemas/daily_logs.json
162
+ - examples/schemas/locations.json
163
+ - examples/schemas/users.json
132
164
  - lib/app_rail/airtable.rb
133
165
  - lib/app_rail/airtable/application_record.rb
134
166
  - lib/app_rail/airtable/authenticatable.rb
@@ -152,7 +184,7 @@ licenses:
152
184
  metadata:
153
185
  homepage_uri: https://github.com/FutureWorkshops/app_rail-airtable
154
186
  source_code_uri: https://github.com/FutureWorkshops/app_rail-airtable
155
- post_install_message:
187
+ post_install_message:
156
188
  rdoc_options: []
157
189
  require_paths:
158
190
  - lib
@@ -167,8 +199,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
199
  - !ruby/object:Gem::Version
168
200
  version: '0'
169
201
  requirements: []
170
- rubygems_version: 3.1.6
171
- signing_key:
202
+ rubygems_version: 3.3.6
203
+ signing_key:
172
204
  specification_version: 4
173
205
  summary: Gem to help building App Rail servers using Airtable as a backend
174
206
  test_files: []