ashikawa-core 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,6 +21,19 @@ describe Ashikawa::Core::Connection do
21
21
  end
22
22
  end
23
23
 
24
+ it 'should include include the x-arango-version header in each request' do
25
+ [:get, :post, :put, :delete].each do |http_verb|
26
+ request_stub.send(http_verb, '/_db/_system/_api/my/path') do |request|
27
+ expect(request[:request_headers][:'X-Arango-Version']).to eq '20200'
28
+ [200, response_headers, JSON.generate({ 'name' => 'dude' })]
29
+ end
30
+
31
+ subject.send_request 'my/path', http_verb => {}
32
+
33
+ request_stub.verify_stubbed_calls
34
+ end
35
+ end
36
+
24
37
  it 'should send a get request' do
25
38
  request_stub.get('/_db/_system/_api/my/path') do
26
39
  [200, response_headers, JSON.generate({ 'name' => 'dude' })]
@@ -205,6 +218,40 @@ describe Ashikawa::Core::Connection do
205
218
  request_stub.verify_stubbed_calls
206
219
  end
207
220
 
221
+ context 'handle 404 in the gharial module' do
222
+ let(:request_url) { '/_db/_system/_api/gharial/vertex/42' }
223
+
224
+ it 'should raise GraphNotFoundException if the graph could not be found' do
225
+ request_stub.get(request_url) do
226
+ [404, response_headers, { 'errorMessage' => 'graph not found' }]
227
+ end
228
+
229
+ expect { subject.send_request 'gharial/vertex/42' }.to raise_error(Ashikawa::Core::GraphNotFoundException)
230
+
231
+ request_stub.verify_stubbed_calls
232
+ end
233
+
234
+ it 'should raise CollectionNotFoundException the collection could not be found' do
235
+ request_stub.get(request_url) do
236
+ [404, response_headers, { 'errorMessage' => 'collection not found' }]
237
+ end
238
+
239
+ expect { subject.send_request 'gharial/vertex/42' }.to raise_error(Ashikawa::Core::CollectionNotFoundException)
240
+
241
+ request_stub.verify_stubbed_calls
242
+ end
243
+
244
+ it 'should raise DocumentNotFoundException the document could not be found' do
245
+ request_stub.get(request_url) do
246
+ [404, response_headers, { 'errorMessage' => 'document not found' }]
247
+ end
248
+
249
+ expect { subject.send_request 'gharial/vertex/42' }.to raise_error(Ashikawa::Core::DocumentNotFoundException)
250
+
251
+ request_stub.verify_stubbed_calls
252
+ end
253
+ end
254
+
208
255
  it 'should raise an exception for unknown pathes' do
209
256
  request_stub.get('/_db/_system/_api/unknown_path/4590/333') do
210
257
  [404, response_headers, '']
@@ -208,5 +208,116 @@ describe Ashikawa::Core::Database do
208
208
 
209
209
  expect(subject.create_transaction(js_function, collections)).to be(transaction)
210
210
  end
211
+
212
+ context 'managing graphs' do
213
+ let(:raw_graph) { double('RawGraph') }
214
+ let(:gharial_response) { double('GharialResponse') }
215
+ let(:graph) { instance_double(Ashikawa::Core::Graph) }
216
+
217
+ before do
218
+ allow(gharial_response).to receive(:[]).with('graph').and_return(raw_graph)
219
+ end
220
+
221
+ it 'should fetch a single graph if it exists' do
222
+ expect(connection).to receive(:send_request)
223
+ .with('gharial/my_awesome_graph')
224
+ .and_return(gharial_response)
225
+
226
+ expect(Ashikawa::Core::Graph).to receive(:new)
227
+ .with(subject, raw_graph)
228
+ .and_return(graph)
229
+
230
+ expect(subject.graph('my_awesome_graph')).to eq graph
231
+ end
232
+
233
+ it "should create a single graph if it doesn't exist" do
234
+ expect(connection).to receive(:send_request).with('gharial/my_awesome_graph') do
235
+ raise Ashikawa::Core::GraphNotFoundException
236
+ end
237
+
238
+ expect(subject).to receive(:create_graph).with('my_awesome_graph').and_return(graph)
239
+
240
+ expect(subject.graph('my_awesome_graph')).to eq graph
241
+ end
242
+
243
+ it 'should create a graph' do
244
+ expect(connection).to receive(:send_request)
245
+ .with('gharial', post: { name: 'my_awesome_graph' })
246
+ .and_return(gharial_response)
247
+
248
+ expect(Ashikawa::Core::Graph).to receive(:new)
249
+ .with(subject, raw_graph)
250
+ .and_return(graph)
251
+
252
+ expect(subject.create_graph('my_awesome_graph')).to eq graph
253
+ end
254
+
255
+ it 'should create a single graph with list of edge_definitions' do
256
+ create_params = {
257
+ name: 'my_awesome_graph',
258
+ edgeDefinitions: [
259
+ { collection: 'visited', from: ['ponies'], to: ['places'] }
260
+ ]
261
+ }
262
+ expect(connection).to receive(:send_request)
263
+ .with('gharial', post: create_params)
264
+ .and_return(gharial_response)
265
+
266
+ expect(Ashikawa::Core::Graph).to receive(:new)
267
+ .with(subject, raw_graph)
268
+ .and_return(graph)
269
+
270
+ options = {
271
+ edge_definitions: [
272
+ {
273
+ collection: 'visited',
274
+ from: ['ponies'],
275
+ to: ['places']
276
+ }
277
+ ]
278
+ }
279
+
280
+ expect(subject.create_graph('my_awesome_graph', options)).to eq graph
281
+ end
282
+
283
+ it 'should create a single graph with list of orphan_collections' do
284
+ create_params = {
285
+ name: 'my_awesome_graph',
286
+ orphanCollections: ['i_am_alone']
287
+ }
288
+ expect(connection).to receive(:send_request)
289
+ .with('gharial', post: create_params)
290
+ .and_return(gharial_response)
291
+
292
+ expect(Ashikawa::Core::Graph).to receive(:new)
293
+ .with(subject, raw_graph)
294
+ .and_return(graph)
295
+
296
+ options = {
297
+ orphan_collections: ['i_am_alone']
298
+ }
299
+
300
+ expect(subject.create_graph('my_awesome_graph', options)).to eq graph
301
+
302
+ end
303
+
304
+ it 'should fetch a list of all graphs in the database' do
305
+ raw_list_of_graphs = double('ListOfGraphs')
306
+ allow(raw_list_of_graphs).to receive(:[])
307
+ .with('graphs')
308
+ .and_return([raw_graph])
309
+
310
+ expect(connection).to receive(:send_request)
311
+ .with('gharial')
312
+ .and_return(raw_list_of_graphs)
313
+
314
+ expect(Ashikawa::Core::Graph).to receive(:new)
315
+ .with(subject, raw_graph)
316
+ .and_return(graph)
317
+
318
+ expect(subject.graphs).to eq [graph]
319
+ end
320
+ end
321
+
211
322
  end
212
323
  end
@@ -57,6 +57,22 @@ describe Ashikawa::Core::Document do
57
57
  end
58
58
  end
59
59
 
60
+ describe 'initialized with a garaph' do
61
+ let(:graph) { double('Ashikawa::Core::Graph', name: 'my-graph') }
62
+ let(:additional_data_with_graph) { { graph: graph, more_info: more_info } }
63
+ subject { Ashikawa::Core::Document.new(database, raw_data, additional_data_with_graph) }
64
+
65
+ its(['more_info']) { should eq(more_info) }
66
+ its(:graph) { should eq(graph) }
67
+
68
+ it 'should send requests through the graph module' do
69
+ expect(database).to receive(:send_request)
70
+ .with("gharial/my-graph/vertex/#{id}", {})
71
+
72
+ subject.send(:send_request_for_document, {})
73
+ end
74
+ end
75
+
60
76
  describe 'initialized document with ID' do
61
77
  subject { Ashikawa::Core::Document.new(database, raw_data) }
62
78
 
@@ -0,0 +1,105 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'unit/spec_helper'
3
+ require 'ashikawa-core/edge_collection'
4
+ require 'ashikawa-core/document'
5
+ require 'ashikawa-core/graph'
6
+ require 'ashikawa-core/database'
7
+
8
+ describe Ashikawa::Core::EdgeCollection do
9
+ let(:database) { instance_double('Ashikawa::Core::Database') }
10
+ let(:raw_collection) do
11
+ {
12
+ 'id' => '60768679',
13
+ 'name' => 'relation',
14
+ 'status' => 3,
15
+ 'type' => 3,
16
+ 'error' => false,
17
+ 'code' => 200
18
+ }
19
+ end
20
+ let(:graph) { instance_double('Ashikawa::Core::Graph', name: 'my_graph') }
21
+ let(:new_edge) { instance_double('Ashikawa::Core::Edge') }
22
+ let(:raw_edge) { double('RawEdge') }
23
+ let(:post_response) { { 'edge' => { '_key' => '123' } } }
24
+
25
+ context 'an initialized edge collection' do
26
+ subject { Ashikawa::Core::EdgeCollection.new(database, raw_collection, graph) }
27
+
28
+ it 'should be a subclass of Collection' do
29
+ expect(subject).to be_kind_of Ashikawa::Core::Collection
30
+ end
31
+
32
+ it 'should have a reference to its graph' do
33
+ expect(subject.graph).to eq graph
34
+ end
35
+
36
+ context 'adding edges' do
37
+ let(:this_document) { instance_double('Ashikawa::Core::Document', id: 'this_document_id') }
38
+ let(:that_document) { instance_double('Ashikawa::Core::Document', id: 'that_document_id') }
39
+
40
+ before do
41
+ allow(subject).to receive(:send_request)
42
+ .with('gharial/my_graph/edge/relation/', post: { _from: 'this_document_id', _to: 'that_document_id' })
43
+ .and_return(post_response)
44
+
45
+ allow(subject).to receive(:fetch)
46
+ .with('123')
47
+ .and_return(new_edge)
48
+ end
49
+
50
+ it 'should add a directed relation between to vertices' do
51
+ expect(subject).to receive(:send_request)
52
+ .with('gharial/my_graph/edge/relation/', post: { _from: 'this_document_id', _to: 'that_document_id' })
53
+ .and_return(post_response)
54
+
55
+ subject.add(from: this_document, to: that_document)
56
+ end
57
+
58
+ it 'should return the edge documents' do
59
+ created_edges = subject.add(from: this_document, to: that_document)
60
+
61
+ expect(created_edges).to eq new_edge
62
+ end
63
+ end
64
+
65
+ context 'removing edges by example' do
66
+ let(:this_document) { instance_double('Ashikawa::Core::Document', id: 'this_document_id') }
67
+ let(:that_document) { instance_double('Ashikawa::Core::Document', id: 'that_document_id') }
68
+ let(:query) { double('Query') }
69
+ let(:aql_string) do
70
+ <<-AQL.gsub(/^[ \t]*/, '')
71
+ FOR e IN @@edge_collection
72
+ FILTER e._from == @from && e._to == @to
73
+ REMOVE e._key IN @@edge_collection
74
+ AQL
75
+ end
76
+ let(:bind_vars) { { :'@edge_collection' => 'relation', :from => 'this_document_id', :to => 'that_document_id' } }
77
+
78
+ before do
79
+ allow(database).to receive(:query).and_return(query)
80
+ end
81
+
82
+ it 'should remove the edges' do
83
+ expect(query).to receive(:execute)
84
+ .with(aql_string, bind_vars: bind_vars)
85
+
86
+ subject.remove(from: this_document, to: that_document)
87
+ end
88
+ end
89
+
90
+ it 'should overwrite #send_request_for_this_collection to use gharial' do
91
+ expect(subject).to receive(:send_request)
92
+ .with('gharial/my_graph/edge/relation/edge_key', {})
93
+
94
+ subject.send(:send_request_for_this_collection, 'edge_key')
95
+ end
96
+
97
+ it 'should overwrite the #build_content_class to create edges with the graph attached' do
98
+ expect(Ashikawa::Core::Edge).to receive(:new)
99
+ .with(database, raw_edge, graph: graph)
100
+ .and_return(new_edge)
101
+
102
+ subject.build_content_class(raw_edge)
103
+ end
104
+ end
105
+ end
@@ -55,6 +55,13 @@ describe Ashikawa::Core::Edge do
55
55
  subject['last_name'] = new_last_name
56
56
  subject.save
57
57
  end
58
+
59
+ it 'should send requests to the edge endpoint' do
60
+ expect(database).to receive(:send_request)
61
+ .with("edge/#{id}", {})
62
+
63
+ subject.send(:send_request_for_document, {})
64
+ end
58
65
  end
59
66
 
60
67
  describe 'initializing edge with additional data' do
@@ -63,5 +70,21 @@ describe Ashikawa::Core::Edge do
63
70
  subject { Ashikawa::Core::Edge.new(database, raw_data, additional_data) }
64
71
 
65
72
  its(['more_info']) { should eq(more_info) }
73
+
74
+ context 'initializing with a graph' do
75
+ let(:graph) { double('Ashikawa::Core::Graph', name: 'my-graph') }
76
+ let(:additional_data_with_graph) { { graph: graph, more_info: more_info } }
77
+ subject { Ashikawa::Core::Edge.new(database, raw_data, additional_data_with_graph) }
78
+
79
+ its(['more_info']) { should eq(more_info) }
80
+ its(:graph) { should eq(graph) }
81
+
82
+ it 'should send requests through the graph module' do
83
+ expect(database).to receive(:send_request)
84
+ .with("gharial/my-graph/edge/#{id}", {})
85
+
86
+ subject.send(:send_request_for_document, {})
87
+ end
88
+ end
66
89
  end
67
90
  end
@@ -1,4 +1,6 @@
1
1
  # -*- encoding : utf-8 -*-
2
+ require 'unit/spec_helper'
3
+
2
4
  require 'ashikawa-core/exceptions/no_collection_provided'
3
5
  require 'ashikawa-core/exceptions/client_error'
4
6
  require 'ashikawa-core/exceptions/client_error/authentication_failed'
@@ -6,7 +8,9 @@ require 'ashikawa-core/exceptions/client_error/bad_syntax'
6
8
  require 'ashikawa-core/exceptions/client_error/resource_not_found'
7
9
  require 'ashikawa-core/exceptions/client_error/resource_not_found/document_not_found'
8
10
  require 'ashikawa-core/exceptions/client_error/resource_not_found/collection_not_found'
11
+ require 'ashikawa-core/exceptions/client_error/resource_not_found/collection_not_in_graph'
9
12
  require 'ashikawa-core/exceptions/client_error/resource_not_found/index_not_found'
13
+ require 'ashikawa-core/exceptions/client_error/resource_not_found/graph_not_found'
10
14
  require 'ashikawa-core/exceptions/server_error'
11
15
  require 'ashikawa-core/exceptions/server_error/json_error'
12
16
 
@@ -48,6 +52,14 @@ describe Ashikawa::Core::IndexNotFoundException do
48
52
  its(:to_s) { should include 'does not exist' }
49
53
  end
50
54
 
55
+ describe Ashikawa::Core::GraphNotFoundException do
56
+ its(:to_s) { should include 'does not exist' }
57
+ end
58
+
59
+ describe Ashikawa::Core::CollectionNotInGraphException do
60
+ its(:to_s) { should include 'not been added to the graph yet' }
61
+ end
62
+
51
63
  describe Ashikawa::Core::ServerError do
52
64
  let(:error_message) { 'The server is misbehaving' }
53
65
  subject { Ashikawa::Core::ServerError.new(error_message) }
@@ -11,6 +11,7 @@ describe Ashikawa::Core::FaradayFactory do
11
11
  before do
12
12
  allow(Faraday).to receive(:new).with(api_string).and_yield(config_block)
13
13
  allow(config_block).to receive(:request).with(:json)
14
+ allow(config_block).to receive(:request).with(:x_arango_version)
14
15
  allow(config_block).to receive(:response).with(:error_response)
15
16
  allow(config_block).to receive(:response).with(:json)
16
17
  allow(config_block).to receive(:adapter).with(Faraday.default_adapter)
@@ -0,0 +1,270 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'unit/spec_helper'
3
+ require 'ashikawa-core/graph'
4
+ require 'ashikawa-core/document'
5
+ require 'ashikawa-core/database'
6
+
7
+ describe Ashikawa::Core::Graph do
8
+ let(:database) { instance_double('Ashikawa::Core::Database') }
9
+ let(:raw_graph) { double('RawGraph').as_null_object }
10
+ let(:edge_definition) do
11
+ {
12
+ 'collection' => 'friends',
13
+ 'from' => %w(ponies),
14
+ 'to' => %w(dragons ponies)
15
+ }
16
+ end
17
+
18
+ def collection_double(name)
19
+ instance_double('Ashikawa::Core::VertexCollection', name: name.to_s)
20
+ end
21
+
22
+ def edge_collection_double(name)
23
+ instance_double('Ashikawa::Core::EdgeCollection', name: name.to_s)
24
+ end
25
+
26
+ context 'an initialized graph' do
27
+ subject { Ashikawa::Core::Graph.new(database, raw_graph) }
28
+
29
+ before do
30
+ allow(raw_graph).to receive(:[]).with('name').and_return('my_graph')
31
+ allow(raw_graph).to receive(:[]).with('_rev').and_return('A113')
32
+ allow(raw_graph).to receive(:fetch).with('orphanCollections').and_return(['orphan'])
33
+ allow(raw_graph).to receive(:fetch).with('edgeDefinitions').and_return([edge_definition])
34
+ end
35
+
36
+ its(:database) { should eq database }
37
+ its(:name) { should eq 'my_graph' }
38
+ its(:revision) { should eq 'A113' }
39
+ its(:edge_definitions) { should eq [edge_definition] }
40
+
41
+ it 'should delegate send_request to the database' do
42
+ expect(database).to receive(:send_request).with('gharial/my_graph')
43
+
44
+ subject.send_request 'gharial/my_graph'
45
+ end
46
+
47
+ it 'should extract the name from the _key if no name was provided' do
48
+ allow(raw_graph).to receive(:[]).with('name').and_return(nil)
49
+ allow(raw_graph).to receive(:[]).with('_key').and_return('my_graph')
50
+ expect(subject.name).to eq 'my_graph'
51
+ end
52
+
53
+ context 'finding neighbors' do
54
+ let(:some_document) { instance_double('Ashikawa::Core::Document', key: 'somekey') }
55
+ let(:query) { double('Query') }
56
+ let(:cursor) { double('Cursor') }
57
+
58
+ before do
59
+ allow(database).to receive(:query).and_return(query)
60
+ end
61
+
62
+ it 'should return the cursor for the query' do
63
+ allow(query).to receive(:execute)
64
+ .and_return(cursor)
65
+
66
+ expect(subject.neighbors(some_document)).to eq cursor
67
+ end
68
+
69
+ it 'should run a neighbors AQL for all edge collections' do
70
+ aql_string = <<-AQL.gsub(/^[ \t]*/, '')
71
+ FOR n IN GRAPH_NEIGHBORS(@graph, { _key:@vertex_key }, {})
72
+ RETURN n.vertex
73
+ AQL
74
+ bind_vars = { graph: 'my_graph', vertex_key: 'somekey' }
75
+
76
+ expect(query).to receive(:execute)
77
+ .with(aql_string, bind_vars: bind_vars)
78
+
79
+ subject.neighbors(some_document)
80
+ end
81
+
82
+ it 'should run a neighbors AQL for a specific edge collection' do
83
+ aql_string = <<-AQL.gsub(/^[ \t]*/, '')
84
+ FOR n IN GRAPH_NEIGHBORS(@graph, { _key:@vertex_key }, {edgeCollectionRestriction: @edge_collection})
85
+ RETURN n.vertex
86
+ AQL
87
+ bind_vars = { edge_collection: ['my-edges'], graph: 'my_graph', vertex_key: 'somekey' }
88
+
89
+ expect(query).to receive(:execute)
90
+ .with(aql_string, bind_vars: bind_vars)
91
+
92
+ subject.neighbors(some_document, edges: ['my-edges'])
93
+ end
94
+ end
95
+
96
+ context 'delete the graph' do
97
+ it 'should delete just the graph' do
98
+ expect(database).to receive(:send_request).with('gharial/my_graph', delete: { dropCollections: false })
99
+
100
+ subject.delete
101
+ end
102
+
103
+ it 'should delete the graph including all collections' do
104
+ expect(database).to receive(:send_request).with('gharial/my_graph', delete: { dropCollections: true })
105
+
106
+ subject.delete(drop_collections: true)
107
+ end
108
+ end
109
+
110
+ context 'vertex collections' do
111
+ let(:raw_vertex_collection) { double('RawVertexCollection') }
112
+
113
+ its(:vertex_collection_names) { should match_array %w(ponies dragons orphan) }
114
+
115
+ it 'should have a list of vertex collections' do
116
+ expected_vertex_collection = [
117
+ collection_double(:ponies),
118
+ collection_double(:orphan),
119
+ collection_double(:dragons)
120
+ ]
121
+ allow(subject).to receive(:vertex_collection).and_return(*expected_vertex_collection)
122
+
123
+ expect(subject.vertex_collections).to match_array expected_vertex_collection
124
+ end
125
+
126
+ it 'should know if a collection has already been added to the list of vertices' do
127
+ allow(subject).to receive(:vertex_collection_names).and_return(['ponies'])
128
+
129
+ expect(subject.has_vertex_collection?('dragons')).to be_falsy
130
+ expect(subject.has_vertex_collection?('ponies')).to be_truthy
131
+ end
132
+
133
+ context 'fetching a single collection' do
134
+ let(:existing_vertex_collection) { instance_double('Ashikawa::Core::VertexCollection') }
135
+
136
+ before do
137
+ allow(database).to receive(:send_request)
138
+ .with('collection/places')
139
+ .and_return(raw_vertex_collection)
140
+
141
+ allow(Ashikawa::Core::VertexCollection).to receive(:new)
142
+ .with(database, raw_vertex_collection, subject)
143
+ .and_return(existing_vertex_collection)
144
+ end
145
+
146
+ it 'should get a single vertex collection' do
147
+ places_collection = subject.vertex_collection 'places'
148
+ expect(places_collection).to eq existing_vertex_collection
149
+ end
150
+ end
151
+
152
+ context 'adding a collection' do
153
+ let(:updated_raw_graph) { double('UpdatedRawGraph') }
154
+ let(:new_vertex_collection) { instance_double('Ashikawa::Core::VertexCollection') }
155
+
156
+ before do
157
+ allow(updated_raw_graph).to receive(:[]).with('name').and_return('my_graph')
158
+ allow(updated_raw_graph).to receive(:[]).with('_rev')
159
+ allow(updated_raw_graph).to receive(:fetch).with('orphanCollections').and_return(['books'])
160
+ allow(updated_raw_graph).to receive(:fetch).with('edgeDefinitions').and_return([edge_definition])
161
+
162
+ allow(database).to receive(:send_request)
163
+ .with('gharial/my_graph/vertex', post: { collection: 'books' })
164
+ .and_return({ 'graph' => updated_raw_graph })
165
+
166
+ allow(database).to receive(:send_request)
167
+ .with('collection/books')
168
+ .and_return(raw_vertex_collection)
169
+
170
+ allow(Ashikawa::Core::VertexCollection).to receive(:new)
171
+ .with(database, raw_vertex_collection, subject)
172
+ .and_return(new_vertex_collection)
173
+ end
174
+
175
+ it 'should add the new collection to the vertex collections of the graph' do
176
+ books_collection = collection_double(:books)
177
+ allow(subject).to receive(:vertex_collection).and_return(books_collection)
178
+
179
+ subject.add_vertex_collection 'books'
180
+
181
+ expect(subject.vertex_collections).to include books_collection
182
+ end
183
+
184
+ it 'should return the newly created collection' do
185
+ expect(subject.add_vertex_collection('books')).to eq new_vertex_collection
186
+ end
187
+ end
188
+ end
189
+
190
+ context 'edge collections' do
191
+ let(:raw_edge_collection) { double('RawEdgeCollection') }
192
+
193
+ its(:edge_collection_names) { should match_array %w(friends) }
194
+
195
+ it 'should have a list of edge collections' do
196
+ expected_edge_collections = [edge_collection_double(:friends)]
197
+ allow(subject).to receive(:edge_collection).and_return(*expected_edge_collections)
198
+
199
+ expect(subject.edge_collections).to match_array expected_edge_collections
200
+ end
201
+
202
+ context 'fetching a single edge collections' do
203
+ let(:existing_edge_collection) { instance_double('Ashikawa::Core::EdgeCollection') }
204
+
205
+ before do
206
+ allow(database).to receive(:send_request)
207
+ .with('collection/friends')
208
+ .and_return(raw_edge_collection)
209
+
210
+ allow(Ashikawa::Core::EdgeCollection).to receive(:new)
211
+ .with(database, raw_edge_collection, subject)
212
+ .and_return(existing_edge_collection)
213
+ end
214
+
215
+ it 'should return a single edge collection' do
216
+ friends_colection = subject.edge_collection :friends
217
+ expect(friends_colection).to eq existing_edge_collection
218
+ end
219
+ end
220
+
221
+ context 'adding a definition' do
222
+ let(:updated_raw_graph) { double('UpdatedRawGraph') }
223
+ let(:new_edge_collection) { instance_double('Ashikawa::Core::EdgeCollection') }
224
+ let(:new_edge_definition) do
225
+ {
226
+ 'collection' => 'authorship',
227
+ 'from' => ['author'],
228
+ 'to' => ['books']
229
+ }
230
+ end
231
+
232
+ before do
233
+ allow(updated_raw_graph).to receive(:[]).with('name').and_return('my_graph')
234
+ allow(updated_raw_graph).to receive(:[]).with('_rev')
235
+ allow(updated_raw_graph).to receive(:fetch).with('orphanCollections').and_return(['orphans'])
236
+ allow(updated_raw_graph).to receive(:fetch).with('edgeDefinitions').and_return([edge_definition])
237
+
238
+ allow(database).to receive(:send_request)
239
+ .with('gharial/my_graph/edge', post: { collection: :authorship, from: [:author], to: [:books] })
240
+ .and_return({ 'graph' => updated_raw_graph })
241
+
242
+ allow(subject).to receive(:edge_collection).and_return(new_edge_collection)
243
+ end
244
+
245
+ it 'should define the name and direction' do
246
+ expect(database).to receive(:send_request)
247
+ .with('gharial/my_graph/edge', post: { collection: :authorship, from: [:author], to: [:books] })
248
+ .and_return({ 'graph' => updated_raw_graph })
249
+
250
+ subject.add_edge_definition(:authorship, from: [:author], to: [:books])
251
+ end
252
+
253
+ it 'should add the definition to the collection edge collections' do
254
+ allow(updated_raw_graph).to receive(:fetch).with('edgeDefinitions').and_return([
255
+ edge_definition,
256
+ new_edge_definition
257
+ ])
258
+
259
+ subject.add_edge_definition(:authorship, from: [:author], to: [:books])
260
+
261
+ expect(subject.edge_collections).to include new_edge_collection
262
+ end
263
+
264
+ it 'should return the edge collection' do
265
+ expect(subject.add_edge_definition(:authorship, from: [:author], to: [:books])).to eq new_edge_collection
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end