ashikawa-core 0.6.0 → 0.7.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.
Files changed (68) hide show
  1. data/.rspec +0 -1
  2. data/.travis.yml +2 -0
  3. data/CONTRIBUTING.md +14 -29
  4. data/Gemfile.devtools +9 -10
  5. data/README.md +30 -9
  6. data/Rakefile +1 -1
  7. data/ashikawa-core.gemspec +9 -8
  8. data/config/flay.yml +2 -2
  9. data/config/flog.yml +1 -1
  10. data/config/roodi.yml +4 -5
  11. data/config/site.reek +40 -16
  12. data/config/yardstick.yml +1 -1
  13. data/lib/ashikawa-core/collection.rb +109 -22
  14. data/lib/ashikawa-core/connection.rb +42 -110
  15. data/lib/ashikawa-core/cursor.rb +13 -6
  16. data/lib/ashikawa-core/database.rb +67 -17
  17. data/lib/ashikawa-core/document.rb +41 -10
  18. data/lib/ashikawa-core/edge.rb +50 -0
  19. data/lib/ashikawa-core/exceptions/client_error/bad_syntax.rb +24 -0
  20. data/lib/ashikawa-core/exceptions/{collection_not_found.rb → client_error/resource_not_found/collection_not_found.rb} +3 -1
  21. data/lib/ashikawa-core/exceptions/{document_not_found.rb → client_error/resource_not_found/document_not_found.rb} +3 -1
  22. data/lib/ashikawa-core/exceptions/{index_not_found.rb → client_error/resource_not_found/index_not_found.rb} +3 -1
  23. data/lib/ashikawa-core/exceptions/client_error/resource_not_found.rb +25 -0
  24. data/lib/ashikawa-core/exceptions/client_error.rb +23 -0
  25. data/lib/ashikawa-core/exceptions/server_error/json_error.rb +25 -0
  26. data/lib/ashikawa-core/exceptions/server_error.rb +23 -0
  27. data/lib/ashikawa-core/figure.rb +59 -2
  28. data/lib/ashikawa-core/index.rb +23 -7
  29. data/lib/ashikawa-core/query.rb +10 -10
  30. data/lib/ashikawa-core/request_preprocessor.rb +49 -0
  31. data/lib/ashikawa-core/response_preprocessor.rb +111 -0
  32. data/lib/ashikawa-core/version.rb +1 -1
  33. data/lib/ashikawa-core.rb +0 -1
  34. data/spec/acceptance/basic_spec.rb +61 -22
  35. data/spec/acceptance/index_spec.rb +11 -4
  36. data/spec/acceptance/query_spec.rb +4 -1
  37. data/spec/acceptance/spec_helper.rb +0 -2
  38. data/spec/acceptance_auth/spec_helper.rb +0 -2
  39. data/spec/fixtures/collections/60768679-count.json +13 -0
  40. data/spec/fixtures/collections/60768679-figures.json +35 -0
  41. data/spec/fixtures/collections/60768679-properties-volatile.json +12 -0
  42. data/spec/fixtures/collections/60768679-properties.json +12 -0
  43. data/spec/fixtures/collections/{4588.json → 60768679.json} +2 -2
  44. data/spec/fixtures/collections/all.json +5 -5
  45. data/spec/fixtures/cursor/26011191-2.json +1 -1
  46. data/spec/fixtures/cursor/26011191.json +1 -1
  47. data/spec/fixtures/documents/example_1-137249191.json +6 -0
  48. data/spec/fixtures/documents/new-example_1-137249191.json +6 -0
  49. data/spec/setup/arangodb.sh +1 -1
  50. data/spec/unit/collection_spec.rb +117 -42
  51. data/spec/unit/connection_spec.rb +161 -61
  52. data/spec/unit/cursor_spec.rb +39 -12
  53. data/spec/unit/database_spec.rb +119 -19
  54. data/spec/unit/document_spec.rb +4 -2
  55. data/spec/unit/edge_spec.rb +54 -0
  56. data/spec/unit/exception_spec.rb +36 -8
  57. data/spec/unit/figure_spec.rb +37 -11
  58. data/spec/unit/index_spec.rb +1 -1
  59. data/spec/unit/query_spec.rb +18 -18
  60. data/spec/unit/spec_helper.rb +4 -13
  61. data/tasks/adjustments.rake +3 -2
  62. metadata +59 -32
  63. data/lib/ashikawa-core/exceptions/unknown_path.rb +0 -15
  64. data/spec/fixtures/collections/4590-properties.json +0 -9
  65. data/spec/fixtures/collections/4590.json +0 -8
  66. data/spec/fixtures/collections/73482-figures.json +0 -23
  67. data/spec/fixtures/documents/4590-333.json +0 -5
  68. data/spec/fixtures/documents/new-4590-333.json +0 -5
@@ -0,0 +1,12 @@
1
+ {
2
+ "id": "60768679",
3
+ "name": "example_1",
4
+ "waitForSync": true,
5
+ "journalSize": 134217728,
6
+ "isVolatile": false,
7
+ "isSystem": false,
8
+ "status": 3,
9
+ "type": 2,
10
+ "error": false,
11
+ "code": 200
12
+ }
@@ -1,8 +1,8 @@
1
1
  {
2
+ "id": "60768679",
2
3
  "name": "example_1",
3
- "waitForSync": true,
4
- "id": 4588,
5
4
  "status": 3,
5
+ "type": 2,
6
6
  "error": false,
7
7
  "code": 200
8
8
  }
@@ -3,13 +3,13 @@
3
3
  {
4
4
  "name": "example_1",
5
5
  "waitForSync": true,
6
- "id": 4588,
6
+ "id": "60768679",
7
7
  "status": 3
8
8
  },
9
9
  {
10
10
  "name": "example_2",
11
11
  "waitForSync": true,
12
- "id": 4589,
12
+ "id": "60768669",
13
13
  "status": 3
14
14
  }
15
15
  ],
@@ -19,14 +19,14 @@
19
19
  "example_1": {
20
20
  "name": "example_1",
21
21
  "waitForSync": true,
22
- "id": 4588,
22
+ "id": "60768679",
23
23
  "status": 3
24
24
  },
25
25
  "example_2": {
26
26
  "name": "example_2",
27
27
  "waitForSync": true,
28
- "id": 4589,
28
+ "id": "60768669",
29
29
  "status": 3
30
30
  }
31
31
  }
32
- }
32
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "hasMore": true,
3
3
  "error": false,
4
- "id": 26011191,
4
+ "id": "26011191",
5
5
  "result": [
6
6
  {
7
7
  "n": 2,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "hasMore": true,
3
3
  "error": false,
4
- "id": 26011191,
4
+ "id": "26011191",
5
5
  "result": [
6
6
  {
7
7
  "n": 0,
@@ -0,0 +1,6 @@
1
+ {
2
+ "hello": "world",
3
+ "_id": "example_1/137249191",
4
+ "_rev": "137249191",
5
+ "_key": "137249191"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "error": false,
3
+ "_id": "example_1/137183655",
4
+ "_rev": "137183655",
5
+ "_key": "137183655"
6
+ }
@@ -3,7 +3,7 @@
3
3
  DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4
4
  cd $DIR
5
5
 
6
- VERSION=1.1.2
6
+ VERSION=1.2.0
7
7
  NAME=ArangoDB-$VERSION
8
8
 
9
9
  if [ ! -d "$DIR/$NAME" ]; then
@@ -9,17 +9,17 @@ describe Ashikawa::Core::Collection do
9
9
  end
10
10
 
11
11
  it "should have a name" do
12
- my_collection = subject.new @database, server_response("/collections/4588")
12
+ my_collection = subject.new @database, server_response("collections/60768679")
13
13
  my_collection.name.should == "example_1"
14
14
  end
15
15
 
16
16
  it "should accept an ID" do
17
- my_collection = subject.new @database, server_response("/collections/4588")
18
- my_collection.id.should == 4588
17
+ my_collection = subject.new @database, server_response("collections/60768679")
18
+ my_collection.id.should == "60768679"
19
19
  end
20
20
 
21
21
  it "should create a query" do
22
- collection = subject.new @database, server_response("/collections/4588")
22
+ collection = subject.new @database, server_response("collections/60768679")
23
23
 
24
24
  mock Ashikawa::Core::Query
25
25
  Ashikawa::Core::Query.stub(:new)
@@ -30,83 +30,109 @@ describe Ashikawa::Core::Collection do
30
30
 
31
31
  describe "attributes of a collection" do
32
32
  it "should check if the collection waits for sync" do
33
- @database.stub(:send_request).with("/collection/4590/properties", {}).and_return { server_response("/collections/4590") }
34
- @database.should_receive(:send_request).with("/collection/4590/properties", {})
33
+ @database.stub(:send_request).with("collection/60768679/properties", {}).and_return { server_response("collections/60768679-properties") }
34
+ @database.should_receive(:send_request).with("collection/60768679/properties", {})
35
35
 
36
- my_collection = subject.new @database, { "id" => "4590" }
36
+ my_collection = subject.new @database, { "id" => "60768679" }
37
37
  my_collection.wait_for_sync?.should be_true
38
38
  end
39
39
 
40
40
  it "should know how many documents the collection has" do
41
- @database.stub(:send_request).with("/collection/4590/count", {}).and_return { server_response("/collections/4590-properties") }
42
- @database.should_receive(:send_request).with("/collection/4590/count", {})
41
+ @database.stub(:send_request).with("collection/60768679/count", {}).and_return { server_response("collections/60768679-count") }
42
+ @database.should_receive(:send_request).with("collection/60768679/count", {})
43
43
 
44
- my_collection = subject.new @database, { "id" => "4590" }
44
+ my_collection = subject.new @database, { "id" => "60768679" }
45
45
  my_collection.length.should == 54
46
46
  end
47
47
 
48
+ it "should know if the collection is volatile" do
49
+ @database.stub(:send_request).with("collection/60768679/properties", {}).and_return { server_response("collections/60768679-properties-volatile") }
50
+ @database.should_receive(:send_request).with("collection/60768679/properties", {})
51
+
52
+ my_collection = subject.new(@database, { "id" => "60768679" })
53
+ my_collection.volatile?.should == true
54
+ end
55
+
56
+ it "should know if the collection is not volatile" do
57
+ @database.stub(:send_request).with("collection/60768679/properties", {}).and_return { server_response("collections/60768679-properties") }
58
+ @database.should_receive(:send_request).with("collection/60768679/properties", {})
59
+
60
+ my_collection = subject.new(@database, { "id" => "60768679" })
61
+ my_collection.volatile?.should == false
62
+ end
63
+
64
+ it "should know that a collection is from type 'document'" do
65
+ my_collection = subject.new(@database, { "id" => "60768679", "type" => 2 })
66
+ my_collection.content_type.should == :document
67
+ end
68
+
69
+ it "should know that a collection is from type 'edge'" do
70
+ my_collection = subject.new(@database, { "id" => "60768679", "type" => 3 })
71
+ my_collection.content_type.should == :edge
72
+ end
73
+
48
74
  it "should check for the figures" do
49
- @database.stub(:send_request).with("/collection/73482/figures", {}).and_return { server_response("/collections/73482-figures") }
50
- @database.should_receive(:send_request).with("/collection/73482/figures", {}).at_least(1).times
75
+ @database.stub(:send_request).with("collection/60768679/figures", {}).and_return { server_response("collections/60768679-figures") }
76
+ @database.should_receive(:send_request).with("collection/60768679/figures", {}).at_least(1).times
51
77
 
52
78
  mock Ashikawa::Core::Figure
53
79
  Ashikawa::Core::Figure.stub(:new)
54
- Ashikawa::Core::Figure.should_receive(:new).exactly(1).times.with(server_response("/collections/73482-figures")["figures"])
80
+ Ashikawa::Core::Figure.should_receive(:new).exactly(1).times.with(server_response("collections/60768679-figures")["figures"])
55
81
 
56
- my_collection = subject.new @database, { "id" => "73482" }
82
+ my_collection = subject.new @database, { "id" => "60768679" }
57
83
  my_collection.figure
58
84
  end
59
85
  end
60
86
 
61
87
  describe "an initialized collection" do
62
- subject { Ashikawa::Core::Collection.new @database, { "id" => "4590", "name" => "example_1" } }
88
+ subject { Ashikawa::Core::Collection.new @database, { "id" => "60768679", "name" => "example_1" } }
63
89
 
64
90
  it "should get deleted" do
65
- @database.stub(:send_request).with("/collection/4590", :delete => {})
66
- @database.should_receive(:send_request).with("/collection/4590", :delete => {})
91
+ @database.stub(:send_request).with("collection/60768679/", :delete => {})
92
+ @database.should_receive(:send_request).with("collection/60768679/", :delete => {})
67
93
 
68
94
  subject.delete
69
95
  end
70
96
 
71
97
  it "should get loaded" do
72
- @database.stub(:send_request).with("/collection/4590/load", :put => {})
73
- @database.should_receive(:send_request).with("/collection/4590/load", :put => {})
98
+ @database.stub(:send_request).with("collection/60768679/load", :put => {})
99
+ @database.should_receive(:send_request).with("collection/60768679/load", :put => {})
74
100
 
75
101
  subject.load
76
102
  end
77
103
 
78
104
  it "should get unloaded" do
79
- @database.stub(:send_request).with("/collection/4590/unload", :put => {})
80
- @database.should_receive(:send_request).with("/collection/4590/unload", :put => {})
105
+ @database.stub(:send_request).with("collection/60768679/unload", :put => {})
106
+ @database.should_receive(:send_request).with("collection/60768679/unload", :put => {})
81
107
 
82
108
  subject.unload
83
109
  end
84
110
 
85
111
  it "should get truncated" do
86
- @database.stub(:send_request).with("/collection/4590/truncate", :put => {})
87
- @database.should_receive(:send_request).with("/collection/4590/truncate", :put => {})
112
+ @database.stub(:send_request).with("collection/60768679/truncate", :put => {})
113
+ @database.should_receive(:send_request).with("collection/60768679/truncate", :put => {})
88
114
 
89
115
  subject.truncate!
90
116
  end
91
117
 
92
118
  it "should change if it waits for sync" do
93
- @database.stub(:send_request).with("/collection/4590/properties", :put => {"waitForSync" => true})
94
- @database.should_receive(:send_request).with("/collection/4590/properties", :put => {"waitForSync" => true})
119
+ @database.stub(:send_request).with("collection/60768679/properties", :put => {"waitForSync" => true})
120
+ @database.should_receive(:send_request).with("collection/60768679/properties", :put => {"waitForSync" => true})
95
121
 
96
122
  subject.wait_for_sync = true
97
123
  end
98
124
 
99
125
  it "should change its name" do
100
- @database.stub(:send_request).with("/collection/4590/rename", :put => {"name" => "my_new_name"})
101
- @database.should_receive(:send_request).with("/collection/4590/rename", :put => {"name" => "my_new_name"})
126
+ @database.stub(:send_request).with("collection/60768679/rename", :put => {"name" => "my_new_name"})
127
+ @database.should_receive(:send_request).with("collection/60768679/rename", :put => {"name" => "my_new_name"})
102
128
 
103
129
  subject.name = "my_new_name"
104
130
  end
105
131
 
106
132
  describe "add and get single documents" do
107
133
  it "should receive a document by ID" do
108
- @database.stub(:send_request).with("/document/4590/333").and_return { server_response('documents/4590-333') }
109
- @database.should_receive(:send_request).with("/document/4590/333")
134
+ @database.stub(:send_request).with("document/60768679/333", {}).and_return { server_response('documents/example_1-137249191') }
135
+ @database.should_receive(:send_request).with("document/60768679/333", {})
110
136
 
111
137
  # Documents need to get initialized:
112
138
  Ashikawa::Core::Document.should_receive(:new)
@@ -115,29 +141,29 @@ describe Ashikawa::Core::Collection do
115
141
  end
116
142
 
117
143
  it "should replace a document by ID" do
118
- @database.stub(:send_request).with("/document/4590/333", :put => {"name" => "The Dude"})
119
- @database.should_receive(:send_request).with("/document/4590/333", :put => {"name" => "The Dude"})
144
+ @database.stub(:send_request).with("document/60768679/333", :put => {"name" => "The Dude"})
145
+ @database.should_receive(:send_request).with("document/60768679/333", :put => {"name" => "The Dude"})
120
146
 
121
147
  subject[333] = {"name" => "The Dude"}
122
148
  end
123
149
 
124
150
  it "should create a new document" do
125
- @database.stub(:send_request).with("/document?collection=4590", :post => { "name" => "The Dude" }).and_return do
126
- server_response('documents/new-4590-333')
151
+ @database.stub(:send_request).with("document?collection=60768679", :post => { "name" => "The Dude" }).and_return do
152
+ server_response('documents/new-example_1-137249191')
127
153
  end
128
- @database.stub(:send_request).with("/document/4590/333", :post => { "name" => "The Dude" }).and_return { server_response('documents/4590-333') }
154
+ @database.stub(:send_request).with("document/60768679/333", :post => { "name" => "The Dude" }).and_return { server_response('documents/example_1-137249191') }
129
155
 
130
156
  # Documents need to get initialized:
131
157
  Ashikawa::Core::Document.should_receive(:new)
132
158
 
133
- subject.create({"name" => "The Dude"})
159
+ subject.create_document({"name" => "The Dude"})
134
160
  end
135
161
 
136
162
  it "should create a new document with `<<`" do
137
- @database.stub(:send_request).with("/document?collection=4590", :post => { "name" => "The Dude" }).and_return do
138
- server_response('documents/new-4590-333')
163
+ @database.stub(:send_request).with("document?collection=60768679", :post => { "name" => "The Dude" }).and_return do
164
+ server_response('documents/example_1-137249191')
139
165
  end
140
- @database.stub(:send_request).with("/document/4590/333").and_return { server_response('documents/4590-333') }
166
+ @database.stub(:send_request).with("document/60768679/333").and_return { server_response('documents/example_1-137249191') }
141
167
 
142
168
  # Documents need to get initialized:
143
169
  Ashikawa::Core::Document.should_receive(:new)
@@ -145,12 +171,18 @@ describe Ashikawa::Core::Collection do
145
171
  subject << {"name" => "The Dude"}
146
172
  end
147
173
 
174
+ it "should not create a new document" do
175
+ expect {
176
+ subject.create_edge(nil, nil, {"quote" => "D'ya have to use s'many cuss words?"})
177
+ }.to raise_exception(RuntimeError, "Can't create an edge in a document collection")
178
+ end
179
+
148
180
  describe "indices" do
149
181
  it "should add a new index" do
150
- @database.stub(:send_request).with("/index?collection=4590", :post => {
182
+ @database.stub(:send_request).with("index?collection=60768679", :post => {
151
183
  "type" => "hash", "fields" => [ "a", "b" ]
152
184
  }).and_return { server_response('indices/new-hash-index') }
153
- @database.should_receive(:send_request).with("/index?collection=4590", :post => {
185
+ @database.should_receive(:send_request).with("index?collection=60768679", :post => {
154
186
  "type" => "hash", "fields" => [ "a", "b" ]
155
187
  })
156
188
 
@@ -162,7 +194,7 @@ describe Ashikawa::Core::Collection do
162
194
 
163
195
  it "should get an index by ID" do
164
196
  @database.stub(:send_request).with(
165
- "/index/4590/168054969"
197
+ "index/example_1/168054969"
166
198
  ).and_return { server_response('indices/hash-index') }
167
199
 
168
200
  Ashikawa::Core::Index.should_receive(:new).with(subject,
@@ -173,7 +205,7 @@ describe Ashikawa::Core::Collection do
173
205
 
174
206
  it "should get all indices" do
175
207
  @database.stub(:send_request).with(
176
- "/index?collection=4590"
208
+ "index?collection=60768679"
177
209
  ).and_return { server_response('indices/all') }
178
210
 
179
211
  Ashikawa::Core::Index.should_receive(:new).exactly(1).times
@@ -184,4 +216,47 @@ describe Ashikawa::Core::Collection do
184
216
  end
185
217
  end
186
218
  end
219
+
220
+ describe "an initialized edge collection" do
221
+ subject { Ashikawa::Core::Collection.new @database, { "id" => "60768679", "name" => "example_1", "type" => 3 } }
222
+
223
+ it "should receive an edge by ID" do
224
+ @database.stub(:send_request).with("edge/60768679/333", {}).and_return { server_response('documents/example_1-137249191') }
225
+ @database.should_receive(:send_request).with("edge/60768679/333", {})
226
+
227
+ # Documents need to get initialized:
228
+ Ashikawa::Core::Edge.should_receive(:new)
229
+
230
+ subject[333]
231
+ end
232
+
233
+ it "should replace an edge by ID" do
234
+ @database.stub(:send_request).with("edge/60768679/333", :put => {"name" => "The Dude"})
235
+ @database.should_receive(:send_request).with("edge/60768679/333", :put => {"name" => "The Dude"})
236
+
237
+ subject[333] = {"name" => "The Dude"}
238
+ end
239
+
240
+ it "should create a new edge" do
241
+ @database.stub(:send_request).with("edge?collection=60768679&from=1&to=2", :post => { "name" => "The Dude" }).and_return do
242
+ server_response('documents/new-example_1-137249191')
243
+ end
244
+ @database.stub(:send_request).with("edge?collection=60768679&from=1&to=2", :post => { "name" => "The Dude" }).and_return { server_response('documents/example_1-137249191') }
245
+ from_double = double
246
+ from_double.stub(:id => "1")
247
+ to_double = double
248
+ to_double.stub(:id => "2")
249
+
250
+ # Documents need to get initialized:
251
+ Ashikawa::Core::Edge.should_receive(:new)
252
+
253
+ subject.create_edge(from_double, to_double, {"name" => "The Dude"})
254
+ end
255
+
256
+ it "should not create a new document" do
257
+ expect {
258
+ subject.create_document({"quote" => "D'ya have to use s'many cuss words?"})
259
+ }.to raise_exception(RuntimeError, "Can't create a document in an edge collection")
260
+ end
261
+ end
187
262
  end
@@ -2,76 +2,78 @@ require 'unit/spec_helper'
2
2
  require 'ashikawa-core/connection'
3
3
 
4
4
  describe Ashikawa::Core::Connection do
5
- subject { Ashikawa::Core::Connection }
5
+ let(:request_stub) { Faraday::Adapter::Test::Stubs.new }
6
+ let(:response_headers) { {"content-type" => "application/json; charset=utf-8" } }
7
+ subject { Ashikawa::Core::Connection.new(ARANGO_HOST, :adapter => [:test, request_stub]) }
6
8
 
7
9
  it "should have a scheme, hostname and port" do
8
- connection = subject.new "http://localhost:8529"
9
-
10
- connection.scheme.should == "http"
11
- connection.host.should == "localhost"
12
- connection.port.should == 8529
13
- end
14
-
15
- it "should default to HTTP, localhost and ArangoDB port" do
16
- connection = subject.new
17
-
18
- connection.scheme.should == "http"
19
- connection.host.should == "localhost"
20
- connection.port.should == 8529
10
+ subject.scheme.should == "http"
11
+ subject.host.should == "localhost"
12
+ subject.port.should == 8529
21
13
  end
22
14
 
23
- describe "initialized connection" do
24
- subject { Ashikawa::Core::Connection.new "http://localhost:8529" }
15
+ it "should send a get request" do
16
+ request_stub.get("/_api/my/path") do
17
+ [200, response_headers, MultiJson.dump({ "name" => "dude" })]
18
+ end
25
19
 
26
- it "should send a get request" do
27
- stub_request(:get, "http://localhost:8529/_api/my/path").to_return :body => '{ "name": "dude" }'
20
+ subject.send_request "my/path"
28
21
 
29
- subject.send_request "/my/path"
22
+ request_stub.verify_stubbed_calls
23
+ end
30
24
 
31
- WebMock.should have_requested(:get, "http://localhost:8529/_api/my/path")
25
+ it "should send a post request" do
26
+ request_stub.post("/_api/my/path") do |request|
27
+ request[:body].should == "{\"name\":\"new_collection\"}"
28
+ [200, response_headers, MultiJson.dump({ "name" => "dude" })]
32
29
  end
33
30
 
34
- it "should send a post request" do
35
- stub_request(:post, "http://localhost:8529/_api/my/path").with(:body => '{"name":"new_collection"}').to_return :body => '{ "name": "dude" }'
31
+ subject.send_request "my/path", :post => { :name => 'new_collection' }
36
32
 
37
- subject.send_request "/my/path", :post => { :name => 'new_collection' }
33
+ request_stub.verify_stubbed_calls
34
+ end
38
35
 
39
- WebMock.should have_requested(:post, "http://localhost:8529/_api/my/path").with :body => '{"name":"new_collection"}'
36
+ it "should send a put request" do
37
+ request_stub.put("/_api/my/path") do |request|
38
+ request[:body].should == '{"name":"new_collection"}'
39
+ [200, response_headers, MultiJson.dump({ "name" => "dude" })]
40
40
  end
41
41
 
42
- it "should send a put request" do
43
- stub_request(:put, "http://localhost:8529/_api/my/path").with(:body => '{"name":"new_collection"}').to_return :body => '{ "name": "dude" }'
42
+ subject.send_request "my/path", :put => { :name => 'new_collection' }
44
43
 
45
- subject.send_request "/my/path", :put => { :name => 'new_collection' }
44
+ request_stub.verify_stubbed_calls
45
+ end
46
46
 
47
- WebMock.should have_requested(:put, "http://localhost:8529/_api/my/path").with :body => '{"name":"new_collection"}'
47
+ it "should send a delete request" do
48
+ request_stub.delete("/_api/my/path") do |request|
49
+ [200, response_headers, MultiJson.dump({ "name" => "dude" })]
48
50
  end
49
51
 
50
- it "should send a delete request" do
51
- stub_request(:delete, "http://localhost:8529/_api/my/path").to_return :body => '{ "name": "dude" }'
52
+ subject.send_request "my/path", :delete => { }
52
53
 
53
- subject.send_request "/my/path", :delete => { }
54
+ request_stub.verify_stubbed_calls
55
+ end
54
56
 
55
- WebMock.should have_requested(:delete, "http://localhost:8529/_api/my/path")
57
+ it "should write JSON request" do
58
+ request_stub.post("/_api/my/path") do |req|
59
+ req[:body].should == "{\"test\":1}"
60
+ [200, response_headers, MultiJson.dump({ "name" => "dude" })]
56
61
  end
57
62
 
58
- it "should parse JSON" do
59
- stub_request(:get, "http://localhost:8529/_api/my/path").to_return :body => '{ "name": "dude" }'
63
+ subject.send_request("my/path", :post => { "test" => 1})
64
+ request_stub.verify_stubbed_calls
65
+ end
60
66
 
61
- subject.send_request("/my/path").should == {"name" => "dude"}
67
+ it "should parse JSON response" do
68
+ request_stub.get("/_api/my/path") do
69
+ [200, response_headers, "{\"name\":\"dude\"}"]
62
70
  end
71
+
72
+ subject.send_request("my/path").should == {"name" => "dude"}
73
+ request_stub.verify_stubbed_calls
63
74
  end
64
75
 
65
76
  describe "authentication" do
66
- subject { Ashikawa::Core::Connection.new }
67
-
68
- it "should authenticate with username and password" do
69
- subject.authenticate_with :username => "testuser", :password => "testpassword"
70
-
71
- subject.username.should == "testuser"
72
- subject.password.should == "testpassword"
73
- end
74
-
75
77
  it "should have authentication turned off by default" do
76
78
  subject.authentication?.should be_false
77
79
  end
@@ -81,7 +83,7 @@ describe Ashikawa::Core::Connection do
81
83
  subject.authentication?.should be_true
82
84
  end
83
85
 
84
- it "should only accept a username & password pairs" do
86
+ it "should only accept username & password pairs" do
85
87
  expect {
86
88
  subject.authenticate_with :username => "kitty"
87
89
  }.to raise_error(ArgumentError)
@@ -96,44 +98,142 @@ describe Ashikawa::Core::Connection do
96
98
  end
97
99
 
98
100
  it "should send the authentication data with every GET request" do
99
- stub_request(:get, "http://user:pass@localhost:8529/_api/my/path").to_return :body => '{ "name": "dude" }'
101
+ pending "Find out how to check for basic auth via Faraday Stubs"
102
+
103
+ request_stub.get("/_api/my/path") do |request|
104
+ [200, response_headers, MultiJson.dump({ "name" => "dude" })]
105
+ end
100
106
 
101
107
  subject.authenticate_with :username => "user", :password => "pass"
102
- subject.send_request "/my/path"
108
+ subject.send_request "my/path"
103
109
 
104
- WebMock.should have_requested(:get, "http://user:pass@localhost:8529/_api/my/path")
110
+ request_stub.verify_stubbed_calls
105
111
  end
106
112
  end
107
113
 
108
114
  describe "exception handling" do
109
- subject { Ashikawa::Core::Connection.new }
115
+ it "should throw a general client error for I'm a teapot" do
116
+ request_stub.get("/_api/bad/request") do
117
+ [418, response_headers, ""]
118
+ end
119
+
120
+ expect do
121
+ subject.send_request("bad/request")
122
+ end.to raise_error(Ashikawa::Core::ClientError, /418/)
123
+
124
+ request_stub.verify_stubbed_calls
125
+ end
126
+
127
+ it "should throw its own exception when doing a bad request" do
128
+ request_stub.get("/_api/bad/request") do
129
+ [400, response_headers, ""]
130
+ end
131
+
132
+ expect do
133
+ subject.send_request("bad/request")
134
+ end.to raise_error(Ashikawa::Core::BadSyntax)
135
+
136
+ request_stub.verify_stubbed_calls
137
+ end
138
+
139
+ it "should throw a general server error for the generic server error" do
140
+ request_stub.get("/_api/bad/request") do
141
+ [500, response_headers, ""]
142
+ end
143
+
144
+ expect do
145
+ subject.send_request("bad/request")
146
+ end.to raise_error(Ashikawa::Core::ServerError, /500/)
147
+
148
+ request_stub.verify_stubbed_calls
149
+ end
110
150
 
111
151
  it "should raise an exception if a document is not found" do
112
- stub_request(:get, "http://localhost:8529/_api/document/4590/333").to_return do
113
- raise RestClient::ResourceNotFound
152
+ request_stub.get("/_api/document/4590/333") do
153
+ [404, response_headers, ""]
114
154
  end
115
- expect { subject.send_request "/document/4590/333" }.to raise_error(Ashikawa::Core::DocumentNotFoundException)
155
+
156
+ expect { subject.send_request "document/4590/333" }.to raise_error(Ashikawa::Core::DocumentNotFoundException)
157
+
158
+ request_stub.verify_stubbed_calls
116
159
  end
117
160
 
118
161
  it "should raise an exception if a collection is not found" do
119
- stub_request(:get, "http://localhost:8529/_api/collection/4590").to_return do
120
- raise RestClient::ResourceNotFound
162
+ request_stub.get("/_api/collection/4590") do
163
+ [404, response_headers, ""]
121
164
  end
122
- expect { subject.send_request "/collection/4590" }.to raise_error(Ashikawa::Core::CollectionNotFoundException)
165
+
166
+ expect { subject.send_request "collection/4590" }.to raise_error(Ashikawa::Core::CollectionNotFoundException)
167
+
168
+ request_stub.verify_stubbed_calls
123
169
  end
124
170
 
125
171
  it "should raise an exception if an index is not found" do
126
- stub_request(:get, "http://localhost:8529/_api/index/4590/333").to_return do
127
- raise RestClient::ResourceNotFound
172
+ request_stub.get("/_api/index/4590/333") do
173
+ [404, response_headers, ""]
128
174
  end
129
- expect { subject.send_request "/index/4590/333" }.to raise_error(Ashikawa::Core::IndexNotFoundException)
175
+
176
+ expect { subject.send_request "index/4590/333" }.to raise_error(Ashikawa::Core::IndexNotFoundException)
177
+
178
+ request_stub.verify_stubbed_calls
130
179
  end
131
180
 
132
181
  it "should raise an exception for unknown pathes" do
133
- stub_request(:get, "http://localhost:8529/_api/unknown_path/4590/333").to_return do
134
- raise RestClient::ResourceNotFound
182
+ request_stub.get("/_api/unknown_path/4590/333") do
183
+ [404, response_headers, ""]
184
+ end
185
+
186
+ expect { subject.send_request "unknown_path/4590/333" }.to raise_error(Ashikawa::Core::ResourceNotFound)
187
+
188
+ request_stub.verify_stubbed_calls
189
+ end
190
+
191
+ it "should raise an error if a malformed JSON was returned from the server" do
192
+ request_stub.get("/_api/document/4590/333") do
193
+ [200, response_headers, "{\"a\":1"]
194
+ end
195
+
196
+ expect { subject.send_request "document/4590/333" }.to raise_error(Ashikawa::Core::JsonError)
197
+
198
+ request_stub.verify_stubbed_calls
199
+ end
200
+
201
+ it "should raise an error if the content type of the response is not JSON" do
202
+ request_stub.get("/_api/document/4590/333") do
203
+ [200, {"content-type" => "text/html; charset=utf-8"}, ""]
204
+ end
205
+
206
+ expect { subject.send_request "document/4590/333" }.to raise_error(Ashikawa::Core::JsonError)
207
+
208
+ request_stub.verify_stubbed_calls
209
+ end
210
+ end
211
+
212
+ describe "logging" do
213
+ let(:request_stub) { Faraday::Adapter::Test::Stubs.new }
214
+ let(:logger) { double }
215
+ subject {
216
+ Ashikawa::Core::Connection.new(ARANGO_HOST, :adapter => [:test, request_stub], :logger => logger)
217
+ }
218
+
219
+ it "should log a get request" do
220
+ request_stub.get("/_api/test") do
221
+ [200, response_headers, MultiJson.dump({:a => 1})]
222
+ end
223
+ logger.should_receive(:info).with("GET #{ARANGO_HOST}/_api/test ")
224
+ logger.should_receive(:info).with("200 {\"a\":1}")
225
+ subject.send_request("test")
226
+ end
227
+
228
+ it "should log a post request" do
229
+ pending "This fails on 1.8.7 for unknown reasons. Will investigate." if RUBY_VERSION == "1.8.7"
230
+
231
+ request_stub.post("/_api/test") do
232
+ [201, response_headers, MultiJson.dump({:b => 2})]
135
233
  end
136
- expect { subject.send_request "/unknown_path/4590/333" }.to raise_error(Ashikawa::Core::UnknownPath)
234
+ logger.should_receive(:info).with("POST #{ARANGO_HOST}/_api/test {:a=>2}")
235
+ logger.should_receive(:info).with("201 {\"b\":2}")
236
+ subject.send_request("test", :post => { :a => 2})
137
237
  end
138
238
  end
139
239
  end