Skip to content

Commit fac3bea

Browse files
committed
Merge pull request #7 from rv816/master
Fixed `class Airtable` definition bug
2 parents 8bfc1b0 + 024b659 commit fac3bea

File tree

4 files changed

+162
-7
lines changed

4 files changed

+162
-7
lines changed

airtable/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from airtable import Airtable
1+
#from airtable import Airtable

airtable/airtable.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1+
import os, json, requests
12
from collections import OrderedDict
2-
import json
3-
import os
4-
import requests
53

64
API_URL = 'https://api.airtable.com/v%s/'
75
API_VERSION = '0'
@@ -37,7 +35,7 @@ def create_payload(data):
3735
return {'fields': data}
3836

3937

40-
class Airtable():
38+
class Airtable:
4139
def __init__(self, base_id, api_key):
4240
self.airtable_url = API_URL % API_VERSION
4341
self.base_url = os.path.join(self.airtable_url, base_id)

airtable/airtable_test.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
import airtable
23
import mock
34
import requests
@@ -126,7 +127,7 @@ def test_get_not_found(self, mock_request):
126127
mock_request.return_value = mock_response
127128
r = self.airtable.get(FAKE_TABLE_NAME, '123')
128129
self.assertEqual(r['error']['code'], 404)
129-
130+
130131
def test_invalid_get(self):
131132
with self.assertRaises(airtable.IsNotString):
132133
self.airtable.get(FAKE_TABLE_NAME, 123)
@@ -152,4 +153,4 @@ def test_invalid_delete(self):
152153
self.airtable.delete(FAKE_TABLE_NAME, 123)
153154

154155
if __name__ == '__main__':
155-
unittest.main()
156+
unittest.main()

test_airtable.py

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
from airtable.airtable import Airtable
2+
from airtable import airtable
3+
import mock
4+
import requests
5+
import unittest
6+
7+
FAKE_TABLE_NAME = 'TableName'
8+
FAKE_BASE_ID = 'app12345'
9+
FAKE_API_KEY = 'fake_api_key'
10+
11+
12+
class TestAirtable(unittest.TestCase):
13+
def setUp(self):
14+
self.base_id = FAKE_BASE_ID
15+
self.api_key = FAKE_API_KEY
16+
self.airtable = Airtable(self.base_id, self.api_key)
17+
18+
def test_build_base_url(self):
19+
self.assertEqual(self.airtable.base_url,
20+
'https://api.airtable.com/v0/app12345')
21+
22+
def test_build_headers(self):
23+
self.assertEqual(self.airtable.headers['Authorization'],
24+
'Bearer fake_api_key')
25+
26+
@mock.patch.object(requests, 'request')
27+
def test_get_all(self, mock_request):
28+
mock_response = mock.MagicMock()
29+
mock_response.status_code = 200
30+
mock_response.json.return_value = {
31+
'records': [
32+
{
33+
'id': 'reccA6yaHKzw5Zlp0',
34+
'fields': {
35+
'Name': 'John',
36+
'Number': '(987) 654-3210'
37+
}
38+
},
39+
{
40+
'id': 'reccg3Kke0QvTDW0H',
41+
'fields': {
42+
'Name': 'Nico',
43+
'Number': '(123) 222-1131'
44+
}
45+
}
46+
],
47+
'offset': 'reccg3Kke0QvTDW0H'
48+
}
49+
mock_request.return_value = mock_response
50+
r = self.airtable.get(FAKE_TABLE_NAME)
51+
self.assertEqual(len(r['records']), 2)
52+
self.assertEqual(r['offset'], 'reccg3Kke0QvTDW0H')
53+
54+
@mock.patch.object(requests, 'request')
55+
def test_order_of_fields_is_preserved(self, mock_request):
56+
mock_response = requests.Response()
57+
mock_response.status_code = 200
58+
59+
# Set the text content of the response to a JSON string so we can test
60+
# how it gets deserialized
61+
mock_response._content = '''{
62+
"records": [
63+
{
64+
"id": "reccA6yaHKzw5Zlp0",
65+
"fields": {
66+
"a": 1,
67+
"b": 2,
68+
"c": 3,
69+
"d": 4,
70+
"e": 5,
71+
"f": 6,
72+
"g": 7,
73+
"h": 8,
74+
"i": 9,
75+
"j": 10,
76+
"k": 11,
77+
"l": 12,
78+
"m": 13
79+
}
80+
},
81+
{
82+
"id": "reccg3Kke0QvTDW0H",
83+
"fields": {
84+
"n": 14,
85+
"o": 15,
86+
"p": 16,
87+
"q": 17,
88+
"r": 18,
89+
"s": 19,
90+
"t": 20,
91+
"u": 21,
92+
"v": 22,
93+
"w": 23,
94+
"x": 24,
95+
"y": 25,
96+
"z": 26
97+
}
98+
}
99+
]
100+
}'''
101+
102+
mock_request.return_value = mock_response
103+
r = self.airtable.get(FAKE_TABLE_NAME)
104+
self.assertEqual(r['records'][0]['fields'].keys(), list(u'abcdefghijklm'))
105+
self.assertEqual(r['records'][1]['fields'].keys(), list(u'nopqrstuvwxyz'))
106+
107+
@mock.patch.object(requests, 'request')
108+
def test_get_by_id(self, mock_request):
109+
fake_id = 'reccA6yaHKzw5Zlp0'
110+
mock_response = mock.MagicMock()
111+
mock_response.status_code = 200
112+
mock_response.json.return_value = {
113+
'id': 'reccA6yaHKzw5Zlp0',
114+
'fields': {
115+
'Name': 'John',
116+
'Number': '(987) 654-3210'
117+
}
118+
}
119+
mock_request.return_value = mock_response
120+
r = self.airtable.get(FAKE_TABLE_NAME, fake_id)
121+
self.assertEqual(r['id'], fake_id)
122+
123+
@mock.patch.object(requests, 'request')
124+
def test_get_not_found(self, mock_request):
125+
mock_response = mock.MagicMock()
126+
mock_response.status_code = 404
127+
mock_request.return_value = mock_response
128+
r = self.airtable.get(FAKE_TABLE_NAME, '123')
129+
self.assertEqual(r['error']['code'], 404)
130+
131+
def test_invalid_get(self):
132+
with self.assertRaises(airtable.IsNotString):
133+
self.airtable.get(FAKE_TABLE_NAME, 123)
134+
self.airtable.get(FAKE_TABLE_NAME, offset=123)
135+
with self.assertRaises(airtable.IsNotInteger):
136+
self.airtable.get(FAKE_TABLE_NAME, limit='1')
137+
138+
@mock.patch.object(requests, 'request')
139+
def test_delete(self, mock_request):
140+
mock_response = mock.MagicMock()
141+
mock_response.status_code = 200
142+
mock_response.json.return_value = {
143+
'deleted': True,
144+
'id': '1234'
145+
}
146+
mock_request.return_value = mock_response
147+
r = self.airtable.delete(FAKE_TABLE_NAME, '1234')
148+
self.assertTrue(r['deleted'])
149+
self.assertEqual(r['id'], '1234')
150+
151+
def test_invalid_delete(self):
152+
with self.assertRaises(airtable.IsNotString):
153+
self.airtable.delete(FAKE_TABLE_NAME, 123)
154+
155+
if __name__ == '__main__':
156+
unittest.main()

0 commit comments

Comments
 (0)