airrecord 0.1.1 → 0.1.2

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
  SHA1:
3
- metadata.gz: 6cb016c7f7bfa6d6e5affe3432faedf8cebf92a2
4
- data.tar.gz: eff4bdb0fb4d85cbeaf2ca1dcf82f9c5523e6050
3
+ metadata.gz: 6488c3737cb574a3e1e5e1cbc1d5ae665482c364
4
+ data.tar.gz: 8ebba576595589c7d8e9c6558d9e2032d6953507
5
5
  SHA512:
6
- metadata.gz: f2d60c1447b99e57037782bdd36ec9b93a058b5d0d713b10a8646cc41285d94ca4ccdced574d048b8c720c910fd4beeb020905e110df432b2f0062444e965f75
7
- data.tar.gz: 3055b1ad8dd62efd1a28b07d11ace7e06b0411f082021f3ac6c5da7e1d0f986d84ca08874e2fcd8e217de21f1eec8025034216dc2e91739ee6fff73a418b4438
6
+ metadata.gz: 16a9ffc9fc7ec8a69061e7b26041410c3fcdba2bd2bb1b21f3034cc9f3f60a88dd0b8370118ed167595ba3e4a7aa51780987e74d6176d737736989c0c966fbb4
7
+ data.tar.gz: 998c84a7691409db02f09bb65479e7ebfe1e9a33b820dec3da333083751f4ca0031e892708e438dc63097bf4b39847c5b4143ccb631d3ed70ec76742996319a4
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
  vendor/
11
11
  test/fixtures
12
12
  .byebug_history
13
+ *.gem
data/.travis.yml CHANGED
@@ -1,5 +1,4 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.2.3
5
- before_install: gem install bundler -v 1.12.5
4
+ - 2.3.3
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2017 Simon Eskildsen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md CHANGED
@@ -9,6 +9,11 @@ inviting inspiration from ActiveRecord's API.
9
9
  gem 'airrecord'
10
10
  ```
11
11
 
12
+ This library is provided to enforce a mental model of a database, as described
13
+ in [this post](http://sirupsen.com/minimum-viable-airtable/). Furthermore as an
14
+ alternative to the [official
15
+ library](https://github.com/airtable/airtable-ruby).
16
+
12
17
  ## Examples
13
18
 
14
19
  There's a simple API that allows more ad-hoc querying of Airtable:
@@ -70,3 +75,10 @@ tea = Tea.find(tea.id)
70
75
  puts tea[:hot_brews].first[:rating]
71
76
  # => "3 - Fine"
72
77
  ```
78
+
79
+ ## Contributing
80
+
81
+ Contributions will be happily accepted in the form of Github Pull Requests!
82
+
83
+ * Please ensure CI is passing before submitting your pull request for review.
84
+ * Please provide tests that fail without your change.
@@ -1,3 +1,3 @@
1
1
  module Airrecord
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: airrecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Eskildsen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-21 00:00:00.000000000 Z
11
+ date: 2017-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -103,8 +103,8 @@ extra_rdoc_files: []
103
103
  files:
104
104
  - ".gitignore"
105
105
  - ".travis.yml"
106
- - ":w"
107
106
  - Gemfile
107
+ - LICENSE
108
108
  - README.md
109
109
  - Rakefile
110
110
  - airrecord.gemspec
@@ -131,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
131
  version: '0'
132
132
  requirements: []
133
133
  rubyforge_project:
134
- rubygems_version: 2.4.5.1
134
+ rubygems_version: 2.6.10
135
135
  signing_key:
136
136
  specification_version: 4
137
137
  summary: Airtable client
data/:w DELETED
@@ -1,341 +0,0 @@
1
- require 'securerandom'
2
- require 'test_helper'
3
-
4
- class AirtableTest < Minitest::Test
5
- def setup
6
- @table = Airtable.table("key6Zk9xjvoRQG1FO", "appxIxY6d7lz4yHZG", "table1")
7
-
8
- @stubs = Faraday::Adapter::Test::Stubs.new
9
- @table.client.connection = Faraday.new { |builder|
10
- builder.adapter :test, @stubs
11
- }
12
-
13
- stub_request([{"Name": "omg", "Notes": "hello world", " Something else\n" => "hi"}, {"Name": "more", "Notes": "walrus"}])
14
- end
15
-
16
- def test_retrieve_records
17
- assert_instance_of Array, @table.records
18
- end
19
-
20
- def test_filter_records
21
- stub_request([{"Name": "yes"}, {"Name": "no"}])
22
-
23
- records = @table.records(filter: "Name")
24
- assert_equal "yes", records[0][:name]
25
- end
26
-
27
- def test_sort_records
28
- stub_request([{"Name": "a"}, {"Name": "b"}])
29
-
30
- records = @table.records(sort: { Name: 'asc' })
31
- assert_equal "a", records[0][:name]
32
- assert_equal "b", records[1][:name]
33
- end
34
-
35
- def test_view_records
36
- stub_request([{"Name": "a"}, {"Name": "a"}])
37
-
38
- records = @table.records(view: 'A')
39
- assert_equal "a", records[0][:name]
40
- assert_equal "a", records[1][:name]
41
- end
42
-
43
- def test_follow_pagination_by_default
44
- stub_request([{"Name": "1"}, {"Name": "2"}], offset: 'dasfuhiu')
45
- stub_request([{"Name": "3"}, {"Name": "4"}], offset: 'odjafio', clear: false)
46
- stub_request([{"Name": "5"}, {"Name": "6"}], clear: false)
47
-
48
- records = @table.records
49
- assert_equal 6, records.size
50
- end
51
-
52
- def test_dont_follow_pagination_if_disabled
53
- stub_request([{"Name": "1"}, {"Name": "2"}], offset: 'dasfuhiu')
54
- stub_request([{"Name": "3"}, {"Name": "4"}], offset: 'odjafio', clear: false)
55
- stub_request([{"Name": "5"}, {"Name": "6"}], clear: false)
56
-
57
- records = @table.records(paginate: false)
58
- assert_equal 2, records.size
59
- end
60
-
61
- def test_index_by_normalized_name
62
- assert_equal "omg", first_record[:name]
63
- end
64
-
65
- def test_index_by_column_name
66
- assert_equal "omg", first_record["Name"]
67
- end
68
-
69
- def test_cleans_bad_keys
70
- assert_equal "hi", first_record[:something_else]
71
- end
72
-
73
- def test_id
74
- assert_instance_of String, first_record.id
75
- end
76
-
77
- def test_created_at
78
- assert_instance_of Time, first_record.created_at
79
- end
80
-
81
- def test_error_response
82
- stub_error_request(type: "TABLE_NOT_FOUND", message: "Could not find table", table: "unknown")
83
-
84
- assert_raises Airtable::Error do
85
- Airtable.table("key6Zk9xjvoRQG1FO", "appxIxY6d7lz4yHZG", "unknown").records
86
- end
87
- end
88
-
89
- def test_change_value
90
- record = first_record
91
- record[:name] = "testest"
92
- assert_equal "testest", record[:name]
93
- end
94
-
95
- def test_change_value_on_column_name
96
- record = first_record
97
- record["Name"] = "testest"
98
- assert_equal "testest", record[:name]
99
- end
100
-
101
- def test_change_value_and_update
102
- record = first_record
103
-
104
- record[:name] = "new_name"
105
- stub_patch_request(record, ["Name"])
106
-
107
- assert record.save
108
- end
109
-
110
- def test_change_value_then_save_again_should_noop
111
- record = first_record
112
-
113
- record[:name] = "new_name"
114
- stub_patch_request(record, ["Name"])
115
-
116
- assert record.save
117
- assert record.save
118
- end
119
-
120
- def test_updates_fields_to_newest_values_after_update
121
- record = first_record
122
-
123
- record[:name] = "new_name"
124
- stub_patch_request(record, ["Name"], return_body: record.fields.merge("Notes" => "new animal"))
125
-
126
- assert record.save
127
- assert_equal "new_name", record[:name]
128
- assert_equal "new animal", record[:notes]
129
- end
130
-
131
- def test_update_failure
132
- record = first_record
133
-
134
- record[:name] = "new_name"
135
- stub_patch_request(record, ["Name"], return_body: { error: { type: "oh noes", message: 'yes' } }, status: 401)
136
-
137
- assert_raises Airtable::Error do
138
- record.save
139
- end
140
- end
141
-
142
- def test_update_failure_then_succeed
143
- record = first_record
144
-
145
- record[:name] = "new_name"
146
- stub_patch_request(record, ["Name"], return_body: { error: { type: "oh noes", message: 'yes' } }, status: 401)
147
-
148
- assert_raises Airtable::Error do
149
- record.save
150
- end
151
-
152
- stub_patch_request(record, ["Name"])
153
- assert record.save
154
- end
155
-
156
- def test_update_raises_if_new_record
157
- record = @table.build_record(Name: "omg")
158
-
159
- assert_raises Airtable::Error do
160
- record.save
161
- end
162
- end
163
-
164
- def test_existing_record_is_not_new
165
- refute first_record.new_record?
166
- end
167
-
168
- def test_build_new_record
169
- record = @table.build_record(Name: "omg")
170
-
171
- refute record.id
172
- refute record.created_at
173
- assert record.new_record?
174
- end
175
-
176
- def test_create_new_record
177
- record = @table.build_record(Name: "omg")
178
-
179
- stub_post_request(record)
180
-
181
- assert record.create
182
- end
183
-
184
- def test_create_existing_record_fails
185
- record = @table.build_record(Name: "omg")
186
-
187
- stub_post_request(record)
188
-
189
- assert record.create
190
-
191
- assert_raises Airtable::Error do
192
- record.create
193
- end
194
- end
195
-
196
- def test_create_handles_error
197
- record = @table.build_record(Name: "omg")
198
-
199
- stub_post_request(record, status: 401, return_body: { error: { type: "omg", message: "wow" }})
200
-
201
- assert_raises Airtable::Error do
202
- record.create
203
- end
204
- end
205
-
206
- def test_find
207
- record = @table.build_record(Name: "walrus")
208
-
209
- stub_find_request(record, id: "iodfajsofja")
210
-
211
- record = @table.find("iodfajsofja")
212
- assert_equal "walrus", record[:name]
213
- end
214
-
215
- def test_find_handles_error
216
- stub_find_request(nil, return_body: { error: { type: "not found", message: "not found" } }, id: "noep", status: 404)
217
-
218
- assert_raises Airtable::Error do
219
- @table.find("noep")
220
- end
221
- end
222
-
223
- def test_destroy_new_record_fails
224
- record = @table.build_record(Name: "walrus")
225
-
226
- assert_raises Airtable::Error do
227
- record.destroy
228
- end
229
- end
230
-
231
- def test_destroy_record
232
- record = first_record
233
- stub_delete_request(record.id)
234
- assert record.destroy
235
- end
236
-
237
- def test_fail_destroy_record
238
- record = first_record
239
- stub_delete_request(record.id, status: 404, response_body: { error: { type: "not found", message: "whatever" } }.to_json)
240
-
241
- assert_raises Airtable::Error do
242
- record.destroy
243
- end
244
- end
245
-
246
- def test_error_handles_errors_without_body
247
- record = first_record
248
-
249
- stub_delete_request(record.id, status: 500)
250
-
251
- assert_raises Airtable::Error do
252
- record.destroy
253
- end
254
- end
255
-
256
- private
257
-
258
- def first_record
259
- @table.records.first
260
- end
261
-
262
- def stub_delete_request(id, table: @table, status: 202, response_body: "")
263
- @stubs.delete("/v0/#{@table.base_key}/#{@table.table_name}/#{id}") do |env|
264
- [status, {}, response_body]
265
- end
266
- end
267
-
268
- def stub_post_request(record, table: @table, status: 200, headers: {}, return_body: nil)
269
- return_body ||= {
270
- id: SecureRandom.hex(16),
271
- fields: record.fields,
272
- createdTime: Time.now,
273
- }
274
- return_body = return_body.to_json
275
-
276
- request_body = { fields: record.fields }.to_json
277
-
278
- @stubs.post("/v0/#{@table.base_key}/#{@table.table_name}", request_body) do |env|
279
- [status, headers, return_body]
280
- end
281
- end
282
-
283
- def stub_patch_request(record, updated_keys, table: @table1, status: 200, headers: {}, return_body: nil)
284
- return_body ||= record.fields
285
- return_body = return_body.to_json
286
-
287
- request_body = {
288
- fields: Hash[updated_keys.map { |key|
289
- [key, record.fields[key]]
290
- }]
291
- }.to_json
292
-
293
- @stubs.patch("/v0/#{@table.base_key}/#{@table.table_name}/#{record.id}", request_body) do |env|
294
- [status, headers, return_body]
295
- end
296
- end
297
-
298
- # TODO: Problem, can't stub on params.
299
- def stub_request(records, table: @table, status: 200, headers: {}, offset: nil, clear: true)
300
- @stubs.instance_variable_set(:@stack, {}) if clear
301
-
302
- body = {
303
- records: records.map { |record|
304
- {
305
- id: SecureRandom.hex(16),
306
- fields: record,
307
- createdTime: Time.now,
308
- }
309
- },
310
- offset: offset,
311
- }.to_json
312
-
313
- @stubs.get("/v0/#{@table.base_key}/#{@table.table_name}") do |env|
314
- [status, headers, body]
315
- end
316
- end
317
-
318
- def stub_find_request(record = nil, table: @table, status: 200, headers: {}, return_body: nil, id: nil)
319
- return_body ||= record.fields
320
- return_body = return_body.to_json
321
-
322
- id ||= record.id
323
-
324
- @stubs.get("/v0/#{@table.base_key}/#{@table.table_name}/#{id}") do |env|
325
- [status, headers, return_body]
326
- end
327
- end
328
-
329
- def stub_error_request(type:, message:, status: 401, headers: {}, table: @table)
330
- body = {
331
- error: {
332
- type: type,
333
- message: message,
334
- }
335
- }.to_json
336
-
337
- @stubs.get("/v0/#{@table.base_key}/#{@table.table_name}") do |env|
338
- [status, headers, body]
339
- end
340
- end
341
- end