yax-fauna 3.0.1
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 +7 -0
- data/CHANGELOG +51 -0
- data/Gemfile +6 -0
- data/LICENSE +12 -0
- data/README.md +148 -0
- data/Rakefile +13 -0
- data/fauna.gemspec +26 -0
- data/lib/fauna.rb +25 -0
- data/lib/fauna/client.rb +253 -0
- data/lib/fauna/client_logger.rb +52 -0
- data/lib/fauna/context.rb +81 -0
- data/lib/fauna/deprecate.rb +29 -0
- data/lib/fauna/errors.rb +235 -0
- data/lib/fauna/json.rb +99 -0
- data/lib/fauna/objects.rb +147 -0
- data/lib/fauna/page.rb +374 -0
- data/lib/fauna/query.rb +899 -0
- data/lib/fauna/request_result.rb +58 -0
- data/lib/fauna/util.rb +50 -0
- data/lib/fauna/version.rb +4 -0
- data/spec/bytes_spec.rb +36 -0
- data/spec/client_logger_spec.rb +73 -0
- data/spec/client_spec.rb +127 -0
- data/spec/context_spec.rb +84 -0
- data/spec/errors_spec.rb +185 -0
- data/spec/fauna_helper.rb +102 -0
- data/spec/json_spec.rb +161 -0
- data/spec/page_spec.rb +357 -0
- data/spec/query_spec.rb +1104 -0
- data/spec/queryv_spec.rb +25 -0
- data/spec/ref_spec.rb +99 -0
- data/spec/setref_spec.rb +23 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/util_spec.rb +19 -0
- metadata +181 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module Fauna
|
2
|
+
# The result of a request. Provided to observers and included within errors.
|
3
|
+
class RequestResult
|
4
|
+
# The Client.
|
5
|
+
attr_reader :client
|
6
|
+
# HTTP method. Either +:get+, +:post+, +:put+, +:patch+, or +:delete+
|
7
|
+
attr_reader :method
|
8
|
+
# Path that was queried. Relative to client's domain.
|
9
|
+
attr_reader :path
|
10
|
+
# URL query. +nil+ except for +GET+ requests.
|
11
|
+
attr_reader :query
|
12
|
+
# Request data.
|
13
|
+
attr_reader :request_content
|
14
|
+
# String value returned by the server.
|
15
|
+
attr_reader :response_raw
|
16
|
+
##
|
17
|
+
# Parsed value returned by the server.
|
18
|
+
# Includes "resource" wrapper hash, or may be an "errors" hash instead.
|
19
|
+
# In the case of a JSON parse error, this will be nil.
|
20
|
+
attr_reader :response_content
|
21
|
+
# HTTP status code.
|
22
|
+
attr_reader :status_code
|
23
|
+
# A hash of headers.
|
24
|
+
attr_reader :response_headers
|
25
|
+
# Time the request started.
|
26
|
+
attr_reader :start_time
|
27
|
+
# Time the response was received.
|
28
|
+
attr_reader :end_time
|
29
|
+
|
30
|
+
def initialize(
|
31
|
+
client,
|
32
|
+
method, path, query, request_content,
|
33
|
+
response_raw, response_content, status_code, response_headers,
|
34
|
+
start_time, end_time) # :nodoc:
|
35
|
+
@client = client
|
36
|
+
@method = method
|
37
|
+
@path = path
|
38
|
+
@query = query
|
39
|
+
@request_content = request_content
|
40
|
+
@response_raw = response_raw
|
41
|
+
@response_content = response_content
|
42
|
+
@status_code = status_code
|
43
|
+
@response_headers = response_headers
|
44
|
+
@start_time = start_time
|
45
|
+
@end_time = end_time
|
46
|
+
end
|
47
|
+
|
48
|
+
# Real time spent performing the request.
|
49
|
+
def time_taken
|
50
|
+
end_time - start_time
|
51
|
+
end
|
52
|
+
|
53
|
+
# Credentials used by the client.
|
54
|
+
def auth
|
55
|
+
client.credentials
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/fauna/util.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module Fauna
|
2
|
+
##
|
3
|
+
# Converts microseconds to a Time object.
|
4
|
+
#
|
5
|
+
# +microseconds+:: Time in microseconds.
|
6
|
+
def self.time_from_usecs(microseconds)
|
7
|
+
Time.at(microseconds / 1_000_000, microseconds % 1_000_000)
|
8
|
+
end
|
9
|
+
|
10
|
+
##
|
11
|
+
# Converts a Time object to microseconds.
|
12
|
+
#
|
13
|
+
# +time+:: A Time object.
|
14
|
+
def self.usecs_from_time(time)
|
15
|
+
time.to_i * 1_000_000 + time.usec
|
16
|
+
end
|
17
|
+
|
18
|
+
class DSLContext # :nodoc:
|
19
|
+
def self.eval_dsl(dsl, *args, &blk)
|
20
|
+
ctx = eval('self', blk.binding)
|
21
|
+
dsl.instance_variable_set(:@__ctx__, ctx)
|
22
|
+
|
23
|
+
ctx.instance_variables.each do |iv|
|
24
|
+
dsl.instance_variable_set(iv, ctx.instance_variable_get(iv))
|
25
|
+
end
|
26
|
+
|
27
|
+
dsl.instance_exec(*args, &blk)
|
28
|
+
|
29
|
+
ensure
|
30
|
+
dsl.instance_variables.each do |iv|
|
31
|
+
if iv.to_sym != :@__ctx__
|
32
|
+
ctx.instance_variable_set(iv, dsl.instance_variable_get(iv))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
NON_PROXIED_METHODS = Set.new %w(__send__ object_id __id__ == equal?
|
38
|
+
! != instance_exec instance_variables
|
39
|
+
instance_variable_get instance_variable_set
|
40
|
+
).map(&:to_sym)
|
41
|
+
|
42
|
+
instance_methods.each do |method|
|
43
|
+
undef_method(method) unless NON_PROXIED_METHODS.include?(method.to_sym)
|
44
|
+
end
|
45
|
+
|
46
|
+
def method_missing(method, *args, &block)
|
47
|
+
@__ctx__.send(method, *args, &block)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/spec/bytes_spec.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
RSpec.describe Fauna::Bytes do
|
2
|
+
describe '#initalize' do
|
3
|
+
it 'creates from bytes' do
|
4
|
+
raw = random_bytes
|
5
|
+
expect(Fauna::Bytes.new(raw).bytes).to eq(raw)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#from_base64' do
|
10
|
+
it 'creates from base64' do
|
11
|
+
raw = random_bytes
|
12
|
+
encoded = Base64.urlsafe_encode64(raw)
|
13
|
+
|
14
|
+
expect(Fauna::Bytes.from_base64(encoded).bytes).to eq(raw)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#==' do
|
19
|
+
it 'equals same bytes' do
|
20
|
+
raw = random_bytes
|
21
|
+
bytes = Fauna::Bytes.new(raw)
|
22
|
+
|
23
|
+
expect(bytes).to eq(Fauna::Bytes.new(raw))
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not equal different bytes' do
|
27
|
+
expect(Fauna::Bytes.new(random_bytes)).not_to eq(Fauna::Bytes.new(random_bytes))
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'does not equal other type' do
|
31
|
+
raw = random_bytes
|
32
|
+
|
33
|
+
expect(Fauna::Bytes.new(raw)).not_to eq(raw)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
RSpec.describe Fauna::ClientLogger do
|
2
|
+
before(:all) do
|
3
|
+
create_test_db
|
4
|
+
@test_class = client.query { create_class(name: 'logger_test') }[:ref]
|
5
|
+
end
|
6
|
+
|
7
|
+
after(:all) do
|
8
|
+
destroy_test_db
|
9
|
+
end
|
10
|
+
|
11
|
+
# Captures logger output from wrapped client and splits it into lines
|
12
|
+
def capture_log
|
13
|
+
lines = nil
|
14
|
+
observer = Fauna::ClientLogger.logger { |log| lines = log.split("\n") }
|
15
|
+
|
16
|
+
yield get_client(secret: @server_secret, observer: observer)
|
17
|
+
|
18
|
+
lambda { lines.shift }
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'logs response' do
|
22
|
+
reader = capture_log do |client|
|
23
|
+
expect(client.ping).to eq('Scope write is OK')
|
24
|
+
end
|
25
|
+
|
26
|
+
expect(reader.call).to eq('Fauna GET /ping')
|
27
|
+
expect(reader.call).to match(/^ Credentials:/)
|
28
|
+
expect(reader.call).to eq(' Response headers: {')
|
29
|
+
|
30
|
+
# Skip through headers
|
31
|
+
loop do
|
32
|
+
line = reader.call
|
33
|
+
unless line.start_with? ' '
|
34
|
+
expect(line).to eq(' }')
|
35
|
+
break
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
expect(reader.call).to eq(' Response JSON: {')
|
40
|
+
expect(reader.call).to eq(' "resource": "Scope write is OK"')
|
41
|
+
expect(reader.call).to eq(' }')
|
42
|
+
expect(reader.call).to match(/^ Response \(200\): Network latency \d+ms$/)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'logs request content' do
|
46
|
+
value = random_number
|
47
|
+
reader = capture_log do |client|
|
48
|
+
client.query data: { a: value }
|
49
|
+
end
|
50
|
+
|
51
|
+
expect(reader.call).to eq("Fauna POST /")
|
52
|
+
expect(reader.call).to match(/^ Credentials:/)
|
53
|
+
expect(reader.call).to eq(' Request JSON: {')
|
54
|
+
expect(reader.call).to eq(' "object": {')
|
55
|
+
expect(reader.call).to eq(' "data": {')
|
56
|
+
expect(reader.call).to eq(' "object": {')
|
57
|
+
expect(reader.call).to eq(" \"a\": #{value}")
|
58
|
+
expect(reader.call).to eq(' }')
|
59
|
+
expect(reader.call).to eq(' }')
|
60
|
+
expect(reader.call).to eq(' }')
|
61
|
+
expect(reader.call).to eq(' }')
|
62
|
+
# Ignore the rest
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'logs request query' do
|
66
|
+
reader = capture_log do |client|
|
67
|
+
client.ping scope: 'global'
|
68
|
+
end
|
69
|
+
|
70
|
+
expect(reader.call).to eq("Fauna GET /ping?scope=global")
|
71
|
+
# Ignore the rest
|
72
|
+
end
|
73
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
RSpec.describe Fauna::Client do
|
2
|
+
before(:all) do
|
3
|
+
create_test_db
|
4
|
+
@test_class = client.query { create_class(name: 'client_test') }[:ref]
|
5
|
+
end
|
6
|
+
|
7
|
+
after(:all) do
|
8
|
+
destroy_test_db
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'connection' do
|
12
|
+
# Compress string with gzip
|
13
|
+
def gzipped(str)
|
14
|
+
out = ''
|
15
|
+
StringIO.open out do |io|
|
16
|
+
writer = Zlib::GzipWriter.new io
|
17
|
+
writer.write str
|
18
|
+
writer.flush
|
19
|
+
writer.close
|
20
|
+
end
|
21
|
+
out
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'decodes gzip response' do
|
25
|
+
response = gzipped '{"resource": 1}'
|
26
|
+
test_client = stub_client(:post, '/', response, 'Content-Encoding' => 'gzip')
|
27
|
+
expect(test_client.query('tests/decode')).to be(1)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'decodes deflate response' do
|
31
|
+
response = Zlib::Deflate.deflate '{"resource": 1}'
|
32
|
+
test_client = stub_client(:post, '/', response, 'Content-Encoding' => 'deflate')
|
33
|
+
expect(test_client.query('tests/decode')).to be(1)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'serialization' do
|
38
|
+
it 'decodes ref' do
|
39
|
+
ref = Fauna::Ref.new(random_number, Fauna::Ref.new(random_string, Fauna::Native.classes))
|
40
|
+
test_client = stub_client(:post, '/', to_json(resource: ref))
|
41
|
+
|
42
|
+
response = test_client.query('tests/ref')
|
43
|
+
expect(response).to be_a(Fauna::Ref)
|
44
|
+
expect(response).to eq(ref)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'decodes set' do
|
48
|
+
set = Fauna::SetRef.new(match: Fauna::Ref.new(random_string, Fauna::Native.indexes), terms: random_string)
|
49
|
+
test_client = stub_client(:post, '/', to_json(resource: set))
|
50
|
+
|
51
|
+
response = test_client.query('tests/set')
|
52
|
+
expect(response).to be_a(Fauna::SetRef)
|
53
|
+
expect(response).to eq(set)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'decodes obj' do
|
57
|
+
data = { random_string.to_sym => random_string }
|
58
|
+
obj = { :@obj => data }
|
59
|
+
test_client = stub_client(:post, '/', to_json(resource: obj))
|
60
|
+
|
61
|
+
response = test_client.query('tests/obj')
|
62
|
+
expect(response).to be_a(Hash)
|
63
|
+
expect(response).to eq(data)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'decodes ts' do
|
67
|
+
ts = Time.at(0).utc
|
68
|
+
test_client = stub_client(:post, '/', to_json(resource: ts))
|
69
|
+
|
70
|
+
response = test_client.query('tests/ts')
|
71
|
+
expect(response).to be_a(Time)
|
72
|
+
expect(response).to eq(ts)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'decodes date' do
|
76
|
+
date = Date.new(1970, 1, 1)
|
77
|
+
test_client = stub_client(:post, '/', to_json(resource: date))
|
78
|
+
|
79
|
+
response = test_client.query('tests/date')
|
80
|
+
expect(response).to be_a(Date)
|
81
|
+
expect(response).to eq(date)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#with_secret' do
|
86
|
+
it 'creates client with secret' do
|
87
|
+
old_secret = random_string
|
88
|
+
new_secret = random_string
|
89
|
+
|
90
|
+
old_client = get_client(secret: old_secret)
|
91
|
+
new_client = old_client.with_secret(new_secret)
|
92
|
+
|
93
|
+
expect(old_client.credentials).to eq([old_secret])
|
94
|
+
expect(new_client.credentials).to eq([new_secret])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#query' do
|
99
|
+
it 'performs query from expression' do
|
100
|
+
value = random_number
|
101
|
+
|
102
|
+
instance = client.query { create(@test_class, data: { a: value }) }
|
103
|
+
|
104
|
+
expect(instance[:ref].class_).to eq(@test_class)
|
105
|
+
expect(instance[:data][:a]).to eq(value)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'performs query from block' do
|
109
|
+
value = random_number
|
110
|
+
|
111
|
+
instance = client.query { create @test_class, data: { a: value } }
|
112
|
+
|
113
|
+
expect(instance[:ref].class_).to eq(@test_class)
|
114
|
+
expect(instance[:data][:a]).to eq(value)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#ping' do
|
119
|
+
it 'performs ping' do
|
120
|
+
expect(client.ping).to eq('Scope write is OK')
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'performs ping with scope' do
|
124
|
+
expect(client.ping(scope: 'node')).to eq('Scope node is OK')
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
RSpec.describe Fauna::Context do
|
2
|
+
before(:all) do
|
3
|
+
create_test_db
|
4
|
+
@test_class = client.query { create_class(name: 'context_test') }[:ref]
|
5
|
+
end
|
6
|
+
|
7
|
+
after(:all) do
|
8
|
+
destroy_test_db
|
9
|
+
end
|
10
|
+
|
11
|
+
around do |ex|
|
12
|
+
# Ensure context is not shared between tests
|
13
|
+
Fauna::Context.reset
|
14
|
+
ex.run
|
15
|
+
Fauna::Context.reset
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#query' do
|
19
|
+
it 'performs query' do
|
20
|
+
Fauna::Context.block(client) do
|
21
|
+
expect(Fauna::Context.query { add 1, 1 }).to eq(2)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#paginate' do
|
27
|
+
it 'performs paginate' do
|
28
|
+
Fauna::Context.block(client) do
|
29
|
+
expect(Fauna::Context.paginate(Fauna::Query.expr { ref('classes') }).data).to eq([@test_class])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#push' do
|
35
|
+
it 'pushes new client' do
|
36
|
+
new = Fauna::Client.new
|
37
|
+
|
38
|
+
Fauna::Context.push(new)
|
39
|
+
expect(Fauna::Context.client).to be(new)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#pop' do
|
44
|
+
it 'pops active client' do
|
45
|
+
outer = Fauna::Client.new
|
46
|
+
inner = Fauna::Client.new
|
47
|
+
|
48
|
+
Fauna::Context.push(outer)
|
49
|
+
Fauna::Context.push(inner)
|
50
|
+
|
51
|
+
expect(Fauna::Context.pop).to be(inner)
|
52
|
+
expect(Fauna::Context.client).to be(outer)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#reset' do
|
57
|
+
it 'resets stack' do
|
58
|
+
initial = Fauna::Client.new
|
59
|
+
outer = Fauna::Client.new
|
60
|
+
inner = Fauna::Client.new
|
61
|
+
|
62
|
+
Fauna::Context.push(initial)
|
63
|
+
Fauna::Context.push(outer)
|
64
|
+
Fauna::Context.push(inner)
|
65
|
+
|
66
|
+
Fauna::Context.reset
|
67
|
+
expect { Fauna::Context.client }.to raise_error(Fauna::NoContextError)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#block' do
|
72
|
+
it 'changes client within block' do
|
73
|
+
outer = Fauna::Client.new
|
74
|
+
inner = Fauna::Client.new
|
75
|
+
Fauna::Context.push(outer)
|
76
|
+
|
77
|
+
expect(Fauna::Context.client).to be(outer)
|
78
|
+
Fauna::Context.block(inner) do
|
79
|
+
expect(Fauna::Context.client).to be(inner)
|
80
|
+
end
|
81
|
+
expect(Fauna::Context.client).to be(outer)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/spec/errors_spec.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
RSpec.describe 'Fauna Errors' do
|
2
|
+
RSpec::Matchers.define :raise_fauna_error do |exception, code, position = nil|
|
3
|
+
match do |block|
|
4
|
+
expect(&block).to raise_error(exception) do |ex|
|
5
|
+
expect(ex.errors.length).to be(1)
|
6
|
+
error = ex.errors.first
|
7
|
+
expect(error.code).to eq(code)
|
8
|
+
expect(error.position).to eq(position)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def supports_block_expectations?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:all) do
|
18
|
+
create_test_db
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:all) do
|
22
|
+
destroy_test_db
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create client with stub adapter responding to / with the given status and response
|
26
|
+
def stub_post(status_code, response)
|
27
|
+
stubs = Faraday::Adapter::Test::Stubs.new
|
28
|
+
stubs.post '/' do
|
29
|
+
[status_code, {}, response]
|
30
|
+
end
|
31
|
+
Fauna::Client.new(adapter: [:test, stubs])
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create client with stub adapter responding to / with the given exception
|
35
|
+
def stub_error(exception)
|
36
|
+
stubs = Faraday::Adapter::Test::Stubs.new
|
37
|
+
stubs.post '/' do
|
38
|
+
fail exception
|
39
|
+
end
|
40
|
+
Fauna::Client.new(adapter: [:test, stubs])
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'sets request result' do
|
44
|
+
expect { client.query { add 1, :two } }.to raise_error do |err|
|
45
|
+
expect(err).to be_a(Fauna::BadRequest)
|
46
|
+
expect(err.request_result.request_content).to eq(Fauna::Query.add [1, :two])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'parses query errors' do
|
51
|
+
expect { client.query { add 1, :two } }.to raise_fauna_error(Fauna::BadRequest, 'invalid argument', [:add, 1])
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'parses invalid data' do
|
55
|
+
expect { client.query { create ref('classes'), name: 123 } }.to raise_error(Fauna::BadRequest) do |err|
|
56
|
+
expect(err.errors.length).to eq(1)
|
57
|
+
error = err.errors.first
|
58
|
+
|
59
|
+
expect(error.code).to eq('validation failed')
|
60
|
+
expect(error.position).to eq([])
|
61
|
+
expect(error.failures.length).to eq(1)
|
62
|
+
failure = error.failures.first
|
63
|
+
|
64
|
+
expect(failure.code).to eq('invalid type')
|
65
|
+
expect(failure.field).to eq([:name])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe Fauna::ErrorData do
|
70
|
+
it 'handles inspect' do
|
71
|
+
err = Fauna::ErrorData.new 'code', 'desc', nil, nil
|
72
|
+
expect(err.inspect).to eq('ErrorData("code", "desc", nil, nil)')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'handles inspect with failures' do
|
76
|
+
failure = Fauna::Failure.new 'code', 'desc', [:a, :b]
|
77
|
+
err = Fauna::ErrorData.new 'code', 'desc', [:pos], [failure]
|
78
|
+
expect(err.inspect).to eq('ErrorData("code", "desc", [:pos], [Failure("code", "desc", [:a, :b])])')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe Fauna::BadRequest do
|
83
|
+
it 'is handled' do
|
84
|
+
expect { client.query { add 1, 'string' } }.to raise_error(Fauna::BadRequest)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe Fauna::Unauthorized do
|
89
|
+
it 'is handled' do
|
90
|
+
bad_client = get_client secret: 'bad_key'
|
91
|
+
expect { bad_client.query { get @db_ref } }.to raise_error(Fauna::Unauthorized)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe Fauna::PermissionDenied do
|
96
|
+
it 'is handled' do
|
97
|
+
key = root_client.query { create ref('keys'), database: @db_ref, role: :client }
|
98
|
+
|
99
|
+
expect { get_client(secret: key[:secret]).query { paginate ref('databases') } }.to raise_fauna_error(
|
100
|
+
Fauna::PermissionDenied, 'permission denied', [:paginate])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe Fauna::NotFound do
|
105
|
+
it 'is handled' do
|
106
|
+
expect { client.query { delete Fauna::Ref.new('classes') } }.to raise_fauna_error(Fauna::NotFound, 'instance not found', [])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe Fauna::InternalError do
|
111
|
+
it 'is handled' do
|
112
|
+
stub_client = stub_post 500,
|
113
|
+
'{"errors": [{"code": "internal server error", "description": "sample text", "stacktrace": []}]}'
|
114
|
+
|
115
|
+
expect { stub_client.query '' }.to raise_fauna_error(Fauna::InternalError, 'internal server error')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe Fauna::UnavailableError do
|
120
|
+
it 'handles fauna 503' do
|
121
|
+
stub_client = stub_post 503, '{"errors": [{"code": "unavailable", "description": "on vacation"}]}'
|
122
|
+
expect { stub_client.query '' }.to raise_fauna_error(Fauna::UnavailableError, 'unavailable')
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'handles upstream 502' do
|
126
|
+
stub_client = stub_post 502, 'Bad gateway'
|
127
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Bad gateway')
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'handles upstream 503' do
|
131
|
+
stub_client = stub_post 503, 'Unable to reach server'
|
132
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Unable to reach server')
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'handles upstream 504' do
|
136
|
+
stub_client = stub_post 504, 'Server timeout'
|
137
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Server timeout')
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'handles upstream json 503' do
|
141
|
+
stub_client = stub_post 503, '{ "error" : "service unavailable" }'
|
142
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, '{ "error" : "service unavailable" }')
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'handles timeout error' do
|
146
|
+
stub_client = stub_error Faraday::TimeoutError.new('timeout')
|
147
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Faraday::TimeoutError: timeout')
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'handles connection error' do
|
151
|
+
stub_client = stub_error Faraday::ConnectionFailed.new('connection refused')
|
152
|
+
expect { stub_client.query '' }.to raise_error(Fauna::UnavailableError, 'Faraday::ConnectionFailed: connection refused')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe Fauna::UnexpectedError do
|
157
|
+
it 'raised for json error' do
|
158
|
+
expect { stub_post(200, 'I like fine wine').query('') }.to raise_error(Fauna::UnexpectedError, /json/i) do |err|
|
159
|
+
rr = err.request_result
|
160
|
+
expect(rr.response_content).to be_nil
|
161
|
+
expect(rr.response_raw).to eq('I like fine wine')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'raised for missing resource' do
|
166
|
+
expect { stub_post(200, '{"notaresource": 1}').query('') }.to raise_error(Fauna::UnexpectedError, /expected key/)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'raised for unexpected code' do
|
170
|
+
expect { stub_post(1337, '{"errors": []}').query('') }.to raise_error(Fauna::UnexpectedError, /status code/)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'raised for bad errors format' do
|
174
|
+
expect { stub_post(500, '{"errors": true}').query('') }.to raise_error(Fauna::UnexpectedError, /unexpected format/)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'raised for empty errors' do
|
178
|
+
expect { stub_post(500, '{"errors": []}').query('') }.to raise_error(Fauna::UnexpectedError, /blank/)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'raised for parsing error' do
|
182
|
+
expect { stub_error(Faraday::ParsingError.new('parse error')).query('') }.to raise_error(Fauna::UnexpectedError, /parse error/)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|