app_rail-airtable 0.3.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []