grendel-ruby 0.1.1 → 0.1.2
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.
- data/.gitignore +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +59 -0
- data/README.md +9 -9
- data/Rakefile +11 -3
- data/VERSION +1 -1
- data/grendel-ruby.gemspec +7 -5
- data/lib/grendel/client.rb +17 -10
- data/lib/grendel/document.rb +19 -5
- data/lib/grendel/link.rb +3 -3
- data/lib/grendel/linked_document.rb +3 -3
- data/lib/grendel/user.rb +30 -11
- data/spec/grendel/document_manager_spec.rb +13 -13
- data/spec/grendel/document_spec.rb +42 -2
- data/spec/grendel/linked_document_manager_spec.rb +9 -9
- data/spec/grendel/linked_document_spec.rb +1 -1
- data/spec/grendel/user_manager_spec.rb +15 -15
- data/spec/spec_helper.rb +11 -3
- metadata +14 -14
data/.gitignore
CHANGED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
dependencies:
|
3
|
+
ruby-debug:
|
4
|
+
group:
|
5
|
+
- :test
|
6
|
+
version: ">= 0"
|
7
|
+
httparty:
|
8
|
+
group:
|
9
|
+
- :default
|
10
|
+
version: ">= 0"
|
11
|
+
mime-types:
|
12
|
+
group:
|
13
|
+
- :default
|
14
|
+
version: ">= 0"
|
15
|
+
rspec:
|
16
|
+
group:
|
17
|
+
- :test
|
18
|
+
version: ">= 1.2.9"
|
19
|
+
json:
|
20
|
+
group:
|
21
|
+
- :default
|
22
|
+
version: ">= 0"
|
23
|
+
bundler:
|
24
|
+
group:
|
25
|
+
- :development
|
26
|
+
version: ">= 0.9.20"
|
27
|
+
webmock:
|
28
|
+
group:
|
29
|
+
- :test
|
30
|
+
version: ">= 0"
|
31
|
+
specs:
|
32
|
+
- addressable:
|
33
|
+
version: 2.1.2
|
34
|
+
- bundler:
|
35
|
+
version: 0.9.24
|
36
|
+
- columnize:
|
37
|
+
version: 0.3.1
|
38
|
+
- crack:
|
39
|
+
version: 0.1.6
|
40
|
+
- httparty:
|
41
|
+
version: 0.5.2
|
42
|
+
- json:
|
43
|
+
version: 1.4.1
|
44
|
+
- linecache:
|
45
|
+
version: "0.43"
|
46
|
+
- mime-types:
|
47
|
+
version: "1.16"
|
48
|
+
- rspec:
|
49
|
+
version: 1.3.0
|
50
|
+
- ruby-debug-base:
|
51
|
+
version: 0.10.3
|
52
|
+
- ruby-debug:
|
53
|
+
version: 0.10.3
|
54
|
+
- webmock:
|
55
|
+
version: 1.0.0
|
56
|
+
hash: ba591b03680c95446b835ca0f00273517b491c6d
|
57
|
+
sources:
|
58
|
+
- Rubygems:
|
59
|
+
uri: http://gemcutter.org
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
grendel-ruby
|
2
2
|
============
|
3
3
|
|
4
|
-
Ruby interface to the Grendel secure document storage service
|
4
|
+
Ruby interface to the [Grendel secure document storage service](http://github.com/wesabe/grendel). See the [Grendel API documentation](http://github.com/wesabe/grendel/blob/master/API.md) for more information.
|
5
5
|
|
6
6
|
Installation
|
7
7
|
------------
|
@@ -11,7 +11,7 @@ Installation
|
|
11
11
|
Examples
|
12
12
|
--------
|
13
13
|
|
14
|
-
The following examples
|
14
|
+
The following examples assume that you have the Grendel server running locally on port 8080.
|
15
15
|
|
16
16
|
|
17
17
|
### Establishing a Connection
|
@@ -28,7 +28,7 @@ The following examples assumes that you have the Grendel server running locally
|
|
28
28
|
|
29
29
|
user = client.users.create("alice", "s3kret") # returns a Grendel::User with id "alice" and password "s3kret"
|
30
30
|
|
31
|
-
If the user `id` is taken, a `Grendel::HTTPException` will be thrown with a message containing `422 Unprocessable Entity` and an explanation.
|
31
|
+
If the user `id` is taken, a `Grendel::Client::HTTPException` will be thrown with a message containing `422 Unprocessable Entity` and an explanation.
|
32
32
|
|
33
33
|
|
34
34
|
### Viewing A User
|
@@ -41,12 +41,12 @@ If the user `id` is taken, a `Grendel::HTTPException` will be thrown with a mess
|
|
41
41
|
|
42
42
|
The returned `Grendel::User` will contain the following attributes:
|
43
43
|
|
44
|
-
id
|
45
|
-
modified_at
|
46
|
-
created_at
|
47
|
-
keys
|
44
|
+
- id # user id
|
45
|
+
- modified_at # DateTime
|
46
|
+
- created_at # DateTime
|
47
|
+
- keys # array of key fingerprints
|
48
48
|
|
49
|
-
If the user is not found, a `Grendel::HTTPException` will be thrown with a message containing `404 Not Found`
|
49
|
+
If the user is not found, a `Grendel::Client::HTTPException` will be thrown with a message containing `404 Not Found`
|
50
50
|
|
51
51
|
|
52
52
|
### Changing A User's Password
|
@@ -154,7 +154,7 @@ user's linked documents.
|
|
154
154
|
|
155
155
|
|
156
156
|
user = client.users.find("alice", "s3kret")
|
157
|
-
linked_docs = user.linked_documents # returns an array of
|
157
|
+
linked_docs = user.linked_documents # returns an array of Grendel::LinkedDocuments
|
158
158
|
|
159
159
|
A `Grendel::LinkedDocument` is a subclass of `Grendel::Document` with the following additional attribute:
|
160
160
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
|
4
|
+
begin
|
5
|
+
require 'bundler'
|
6
|
+
rescue LoadError
|
7
|
+
puts "Bundler is not available. Install it with: gem install bundler"
|
8
|
+
end
|
9
|
+
|
4
10
|
begin
|
5
11
|
require 'jeweler'
|
6
12
|
Jeweler::Tasks.new do |gem|
|
@@ -11,9 +17,11 @@ begin
|
|
11
17
|
gem.email = "brad@wesabe.com"
|
12
18
|
gem.homepage = "http://github.com/wesabe/grendel-ruby"
|
13
19
|
gem.authors = ["Brad Greenlee"]
|
14
|
-
|
15
|
-
|
16
|
-
|
20
|
+
|
21
|
+
Bundler::Definition.from_gemfile('Gemfile').dependencies.each do |dependency|
|
22
|
+
next unless dependency.groups.include?(:default)
|
23
|
+
gem.add_dependency dependency.name, dependency.requirement
|
24
|
+
end
|
17
25
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
26
|
end
|
19
27
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/grendel-ruby.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{grendel-ruby}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brad Greenlee"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-04-27}
|
13
13
|
s.description = %q{Grendel is a RESTful web service which allows for the secure storage of users'
|
14
14
|
documents. Grendel-Ruby provides a Ruby API for Grendel.}
|
15
15
|
s.email = %q{brad@wesabe.com}
|
@@ -20,6 +20,8 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.files = [
|
21
21
|
".document",
|
22
22
|
".gitignore",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
23
25
|
"LICENSE.md",
|
24
26
|
"README.md",
|
25
27
|
"Rakefile",
|
@@ -74,16 +76,16 @@ Gem::Specification.new do |s|
|
|
74
76
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
75
77
|
s.add_runtime_dependency(%q<json>, [">= 0"])
|
76
78
|
s.add_runtime_dependency(%q<httparty>, [">= 0"])
|
77
|
-
s.
|
79
|
+
s.add_runtime_dependency(%q<mime-types>, [">= 0"])
|
78
80
|
else
|
79
81
|
s.add_dependency(%q<json>, [">= 0"])
|
80
82
|
s.add_dependency(%q<httparty>, [">= 0"])
|
81
|
-
s.add_dependency(%q<
|
83
|
+
s.add_dependency(%q<mime-types>, [">= 0"])
|
82
84
|
end
|
83
85
|
else
|
84
86
|
s.add_dependency(%q<json>, [">= 0"])
|
85
87
|
s.add_dependency(%q<httparty>, [">= 0"])
|
86
|
-
s.add_dependency(%q<
|
88
|
+
s.add_dependency(%q<mime-types>, [">= 0"])
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
data/lib/grendel/client.rb
CHANGED
@@ -3,23 +3,30 @@ module Grendel
|
|
3
3
|
class Client
|
4
4
|
attr_accessor :debug, :debug_output
|
5
5
|
attr_reader :base_uri
|
6
|
-
|
6
|
+
|
7
7
|
# Create a new Grendel client instance
|
8
8
|
def initialize(base_uri, options = {})
|
9
9
|
@base_uri = base_uri
|
10
10
|
@debug = options[:debug]
|
11
11
|
@debug_output = options[:debug_output] || $stderr
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def get(uri, options = {})
|
15
15
|
options.merge!(:debug_output => @debug_output) if @debug
|
16
16
|
response = HTTParty.get(@base_uri + uri, options)
|
17
17
|
raise HTTPException.new(response) if response.code >= 400
|
18
18
|
return response
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
|
+
def head(uri, options = {})
|
22
|
+
options.merge!(:debug_output => @debug_output) if @debug
|
23
|
+
response = HTTParty.head(@base_uri + uri, options)
|
24
|
+
raise HTTPException.new(response) if response.code >= 400
|
25
|
+
return response
|
26
|
+
end
|
27
|
+
|
21
28
|
def post(uri, data = {}, options = {})
|
22
|
-
data = data.to_json unless options.delete(:raw_data)
|
29
|
+
data = data.to_json unless options.delete(:raw_data)
|
23
30
|
options.merge!(
|
24
31
|
:body => data,
|
25
32
|
:headers => {'Content-Type' => 'application/json'}
|
@@ -29,10 +36,10 @@ module Grendel
|
|
29
36
|
raise HTTPException.new(response) if response.code >= 400
|
30
37
|
return response
|
31
38
|
end
|
32
|
-
|
39
|
+
|
33
40
|
def put(uri, data = {}, options = {})
|
34
|
-
data = data.to_json unless options.delete(:raw_data)
|
35
|
-
options = {
|
41
|
+
data = data.to_json unless options.delete(:raw_data)
|
42
|
+
options = {
|
36
43
|
:body => data,
|
37
44
|
:headers => {'Content-Type' => 'application/json'}
|
38
45
|
}.update(options)
|
@@ -41,17 +48,17 @@ module Grendel
|
|
41
48
|
raise HTTPException.new(response) if response.code >= 400
|
42
49
|
return response
|
43
50
|
end
|
44
|
-
|
51
|
+
|
45
52
|
def delete(uri, options = {})
|
46
53
|
options.merge!(:debug_output => @debug_output) if @debug
|
47
54
|
response = HTTParty.delete(@base_uri + uri, options)
|
48
55
|
raise HTTPException.new(response) if response.code >= 400
|
49
56
|
end
|
50
|
-
|
57
|
+
|
51
58
|
def users
|
52
59
|
UserManager.new(self)
|
53
60
|
end
|
54
|
-
|
61
|
+
|
55
62
|
class HTTPException < Exception
|
56
63
|
def initialize(response)
|
57
64
|
msg = "#{response.code} #{response.message}"
|
data/lib/grendel/document.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Grendel
|
2
2
|
class Document
|
3
3
|
attr_accessor :user, :name, :uri, :data, :content_type
|
4
|
-
|
4
|
+
|
5
5
|
def initialize(user, params)
|
6
6
|
params.symbolize_keys!
|
7
7
|
@user = user
|
@@ -9,19 +9,33 @@ module Grendel
|
|
9
9
|
@name = params[:name]
|
10
10
|
@data = params[:data]
|
11
11
|
@content_type = params[:content_type]
|
12
|
-
@uri = params[:uri] ?
|
12
|
+
@uri = params[:uri] ?
|
13
13
|
URI.parse(params[:uri]).path :
|
14
14
|
"/documents/" + @name # escape this?
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
# delete this document from Grendel
|
18
18
|
def delete
|
19
19
|
@user.delete(@uri)
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
# send link operations to the Link class
|
23
23
|
def links
|
24
24
|
LinkManager.new(self)
|
25
|
-
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def content_type
|
28
|
+
@content_type ||= begin
|
29
|
+
@user.head(@uri).headers['content-type'].first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def data
|
34
|
+
@data ||= begin
|
35
|
+
response = @user.get(@uri)
|
36
|
+
@content_type = response.headers['content-type'].first
|
37
|
+
response.body
|
38
|
+
end
|
39
|
+
end
|
26
40
|
end
|
27
41
|
end
|
data/lib/grendel/link.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module Grendel
|
2
2
|
class Link
|
3
3
|
attr_accessor :document, :user, :uri
|
4
|
-
|
4
|
+
|
5
5
|
def initialize(document, user, params = {})
|
6
6
|
params.symbolize_keys!
|
7
7
|
@document = document
|
8
8
|
@user = user
|
9
|
-
@uri = params[:uri] ?
|
9
|
+
@uri = params[:uri] ?
|
10
10
|
URI.parse(params[:uri]).path :
|
11
11
|
"/links/" + @user.id # escape this?
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
end
|
15
15
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Grendel
|
2
2
|
class LinkedDocument < Document
|
3
3
|
attr_accessor :linked_user, :owner
|
4
|
-
|
4
|
+
|
5
5
|
# create a new linked document
|
6
6
|
# user - linked user
|
7
7
|
# params:
|
@@ -17,11 +17,11 @@ module Grendel
|
|
17
17
|
super(@owner, params)
|
18
18
|
@linked_user = linked_user
|
19
19
|
@name = params[:name]
|
20
|
-
@uri = params[:uri] ?
|
20
|
+
@uri = params[:uri] ?
|
21
21
|
URI.parse(params[:uri]).path :
|
22
22
|
["/linked-documents", @owner.id, name].join("/")
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
# delete this linked document
|
26
26
|
def delete
|
27
27
|
@linked_user.delete(@uri)
|
data/lib/grendel/user.rb
CHANGED
@@ -2,7 +2,7 @@ module Grendel
|
|
2
2
|
class User
|
3
3
|
attr_accessor :id, :password, :uri
|
4
4
|
attr_reader :client, :modified_at, :created_at, :keys
|
5
|
-
|
5
|
+
|
6
6
|
# create a new Grendel::User object
|
7
7
|
# params:
|
8
8
|
# id
|
@@ -12,7 +12,7 @@ module Grendel
|
|
12
12
|
params.symbolize_keys!
|
13
13
|
@client = client
|
14
14
|
@id = params[:id]
|
15
|
-
@uri = params[:uri] ?
|
15
|
+
@uri = params[:uri] ?
|
16
16
|
URI.parse(params[:uri]).path :
|
17
17
|
"/users/" + @id # escape this?
|
18
18
|
@password = params[:password]
|
@@ -31,38 +31,57 @@ module Grendel
|
|
31
31
|
#
|
32
32
|
def get(uri = "", options = {})
|
33
33
|
options.merge!(auth)
|
34
|
-
@client.get(
|
34
|
+
@client.get(child_uri(uri), options)
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
|
+
def head(uri = "", options = {})
|
38
|
+
options.merge!(auth)
|
39
|
+
@client.head(child_uri(uri), options)
|
40
|
+
end
|
41
|
+
|
37
42
|
def post(uri = "", data = {}, options = {})
|
38
43
|
options.merge!(auth)
|
39
|
-
@client.post(
|
44
|
+
@client.post(child_uri(uri), data, options)
|
40
45
|
end
|
41
|
-
|
46
|
+
|
42
47
|
def put(uri = "", data = {}, options = {})
|
43
48
|
options.merge!(auth)
|
44
|
-
@client.put(
|
49
|
+
@client.put(child_uri(uri), data, options)
|
45
50
|
end
|
46
51
|
|
47
52
|
def delete(uri = "", options = {})
|
48
53
|
options.merge!(auth)
|
49
|
-
@client.delete(
|
54
|
+
@client.delete(child_uri(uri), options)
|
50
55
|
end
|
51
|
-
|
56
|
+
|
52
57
|
# change the user's password
|
53
58
|
def change_password(new_password)
|
54
59
|
put("", {:password => new_password})
|
55
60
|
@password = new_password
|
56
61
|
end
|
57
|
-
|
62
|
+
|
58
63
|
# send documents calls to the DocumentManager
|
59
64
|
def documents
|
60
65
|
DocumentManager.new(self)
|
61
66
|
end
|
62
|
-
|
67
|
+
|
63
68
|
# send linked documents calls to the LinkedDocumentManager
|
64
69
|
def linked_documents
|
65
70
|
LinkedDocumentManager.new(self)
|
66
71
|
end
|
72
|
+
|
73
|
+
private
|
74
|
+
def child_uri(uri)
|
75
|
+
if uri.nil? || uri.empty?
|
76
|
+
# blank uri, just use the user's uri
|
77
|
+
@uri
|
78
|
+
elsif uri.index(@uri) == 0
|
79
|
+
# uri already starts with user's uri, just leave it alone
|
80
|
+
uri
|
81
|
+
else
|
82
|
+
# otherwise just tack the uri onto the end of the user's uri
|
83
|
+
@uri + uri
|
84
|
+
end
|
85
|
+
end
|
67
86
|
end
|
68
87
|
end
|
@@ -8,7 +8,7 @@ describe "Grendel::DocumentManager" do
|
|
8
8
|
@user = Grendel::User.new(@client, :id => @user_id, :password => @password)
|
9
9
|
@base_uri = "#{@user_id}:#{@password}@grendel/users/#{@user_id}/documents"
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
describe "list" do
|
13
13
|
before do
|
14
14
|
stub_json_request(:get, @base_uri, %{{
|
@@ -19,7 +19,7 @@ describe "Grendel::DocumentManager" do
|
|
19
19
|
"uri":"http://grendel/users/#{@user_id}/documents/document2.txt"}
|
20
20
|
]}})
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it "should return an array of all documents" do
|
24
24
|
docs = @user.documents.list
|
25
25
|
docs.length.should == 2
|
@@ -33,29 +33,29 @@ describe "Grendel::DocumentManager" do
|
|
33
33
|
describe "find" do
|
34
34
|
before do
|
35
35
|
stub_json_request(:get, @base_uri + "/document1.txt", "yay for me", :content_type => "text/plain")
|
36
|
-
stub_json_request(:get, @base_uri + "/notfound.txt", "", :status =>
|
36
|
+
stub_json_request(:get, @base_uri + "/notfound.txt", "", :status => [404, "Not Found"])
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it "should return the document" do
|
40
40
|
doc = @user.documents.find("document1.txt")
|
41
41
|
doc.name.should == "document1.txt"
|
42
42
|
doc.content_type.should == "text/plain"
|
43
43
|
doc.data.should == "yay for me"
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
it "should raise an exception if the document is not found" do
|
47
47
|
lambda {
|
48
48
|
@user.documents.find("notfound.txt")
|
49
|
-
}.should raise_error(Grendel::Client::HTTPException) {|error| error.message.should
|
49
|
+
}.should raise_error(Grendel::Client::HTTPException) {|error| error.message.should == "404 Not Found"}
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
describe "store" do
|
54
54
|
describe "a successful request" do
|
55
55
|
before do
|
56
|
-
stub_json_request(:put, @base_uri + "/new_document.txt", "", :status =>
|
56
|
+
stub_json_request(:put, @base_uri + "/new_document.txt", "", :status => [204, "No Content"])
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
it "should send a properly-formatted request" do
|
60
60
|
@user.documents.store("new_document.txt", "top secret stuff", "text/plain")
|
61
61
|
params = { "id" => @user_id, "password" => @password }
|
@@ -63,7 +63,7 @@ describe "Grendel::DocumentManager" do
|
|
63
63
|
with(:body => "top secret stuff", :headers => {"Content-Type" => "text/plain"}).
|
64
64
|
should have_been_made.once
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "should guess the content type if not provided" do
|
68
68
|
@user.documents.store("new_document.txt", "top secret stuff")
|
69
69
|
params = { "id" => @user_id, "password" => @password }
|
@@ -73,14 +73,14 @@ describe "Grendel::DocumentManager" do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
it "should default the content type to 'application/octet-stream' if unknown" do
|
76
|
-
stub_json_request(:put, @base_uri + "/new_document.-wtf-", "", :status =>
|
76
|
+
stub_json_request(:put, @base_uri + "/new_document.-wtf-", "", :status => [204, "No Content"])
|
77
77
|
@user.documents.store("new_document.-wtf-", "top secret stuff")
|
78
78
|
params = { "id" => @user_id, "password" => @password }
|
79
79
|
request(:put, @base_uri + "/new_document.-wtf-").
|
80
80
|
with(:body => "top secret stuff", :headers => {"Content-Type" => "application/octet-stream"}).
|
81
81
|
should have_been_made.once
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
it "should return a document" do
|
85
85
|
doc = @user.documents.store("new_document.txt", "top secret stuff")
|
86
86
|
doc.name.should == "new_document.txt"
|
@@ -89,10 +89,10 @@ describe "Grendel::DocumentManager" do
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
describe "delete" do
|
94
94
|
before do
|
95
|
-
stub_json_request(:delete, @base_uri + "/document.txt", "", :status =>
|
95
|
+
stub_json_request(:delete, @base_uri + "/document.txt", "", :status => [204, "No Content"])
|
96
96
|
@document = Grendel::Document.new(@user, :name => "document.txt")
|
97
97
|
end
|
98
98
|
|
@@ -7,12 +7,12 @@ describe "Grendel::Document" do
|
|
7
7
|
@password = "s3kret"
|
8
8
|
@user = Grendel::User.new(@client, :id => @user_id, :password => @password)
|
9
9
|
@base_uri = "#{@user_id}:#{@password}@grendel/users/#{@user_id}/documents"
|
10
|
+
@document = Grendel::Document.new(@user, :name => "document.txt")
|
10
11
|
end
|
11
12
|
|
12
13
|
describe "delete" do
|
13
14
|
before do
|
14
|
-
stub_json_request(:delete, @base_uri + "/document.txt", "", :status =>
|
15
|
-
@document = Grendel::Document.new(@user, :name => "document.txt")
|
15
|
+
stub_json_request(:delete, @base_uri + "/document.txt", "", :status => [204, "No Content"])
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should send a properly-formatted request" do
|
@@ -20,4 +20,44 @@ describe "Grendel::Document" do
|
|
20
20
|
request(:delete, @base_uri + "/document.txt").should have_been_made.once
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
describe "accessing content type without it being set" do
|
25
|
+
before do
|
26
|
+
@document.content_type = nil
|
27
|
+
stub_request(:head, @base_uri + "/document.txt").
|
28
|
+
to_return(:body => "", :status => 200, :headers => {"Content-Type" => "application/x-lolcat"})
|
29
|
+
end
|
30
|
+
|
31
|
+
it "loads content type" do
|
32
|
+
@document.content_type.should == "application/x-lolcat"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "causes a HEAD request for the document" do
|
36
|
+
@document.content_type
|
37
|
+
request(:head, @base_uri + "/document.txt").should have_been_made.once
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "accessing data without it being set" do
|
42
|
+
before do
|
43
|
+
@document.data = nil
|
44
|
+
stub_request(:get, @base_uri + "/document.txt").
|
45
|
+
to_return(:body => "OMGLOL", :status => 200, :headers => {"Content-Type" => "application/x-lolcat"})
|
46
|
+
end
|
47
|
+
|
48
|
+
it "loads the data" do
|
49
|
+
@document.data.should == "OMGLOL"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "causes a GET request for the document" do
|
53
|
+
@document.data
|
54
|
+
request(:get, @base_uri + "/document.txt").should have_been_made.once
|
55
|
+
end
|
56
|
+
|
57
|
+
it "populates the content type too" do
|
58
|
+
@document.content_type = nil
|
59
|
+
@document.data
|
60
|
+
@document.content_type.should == "application/x-lolcat"
|
61
|
+
end
|
62
|
+
end
|
23
63
|
end
|
@@ -37,11 +37,11 @@ describe "Grendel::LinkedDocumentManager" do
|
|
37
37
|
"uri": "http://grendel/users/carol"
|
38
38
|
}
|
39
39
|
}
|
40
|
-
|
40
|
+
|
41
41
|
]
|
42
42
|
}})
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
it "should return an array of all linked documents" do
|
46
46
|
docs = @user.linked_documents.list
|
47
47
|
docs.length.should == 2
|
@@ -55,13 +55,13 @@ describe "Grendel::LinkedDocumentManager" do
|
|
55
55
|
docs[1].owner.uri.should == "/users/carol"
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
describe "find" do
|
60
60
|
before do
|
61
61
|
stub_json_request(:get, @base_uri + "/bob/document1.txt", "yay for me", :content_type => "text/plain")
|
62
|
-
stub_json_request(:get, @base_uri + "/carol/notfound.txt", "", :status =>
|
62
|
+
stub_json_request(:get, @base_uri + "/carol/notfound.txt", "", :status => [404, "Not Found"])
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
it "should return the document" do
|
66
66
|
doc = @user.linked_documents.find("bob", "document1.txt")
|
67
67
|
doc.name.should == "document1.txt"
|
@@ -69,17 +69,17 @@ describe "Grendel::LinkedDocumentManager" do
|
|
69
69
|
doc.data.should == "yay for me"
|
70
70
|
doc.owner.id.should == "bob"
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it "should raise an exception if the document is not found" do
|
74
74
|
lambda {
|
75
75
|
@user.linked_documents.find("carol", "notfound.txt")
|
76
|
-
}.should raise_error(Grendel::Client::HTTPException) {|error| error.message.should
|
76
|
+
}.should raise_error(Grendel::Client::HTTPException) {|error| error.message.should == "404 Not Found"}
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
describe "delete" do
|
81
81
|
before do
|
82
|
-
stub_json_request(:delete, @base_uri + "/bob/document.txt", "", :status =>
|
82
|
+
stub_json_request(:delete, @base_uri + "/bob/document.txt", "", :status => [204, "No Content"])
|
83
83
|
@linked_document = Grendel::LinkedDocument.new(@user, :name => "document.txt", :owner => {:id => "bob"})
|
84
84
|
end
|
85
85
|
|
@@ -11,7 +11,7 @@ describe "Grendel::LinkedDocument" do
|
|
11
11
|
|
12
12
|
describe "delete" do
|
13
13
|
before do
|
14
|
-
stub_json_request(:delete, @base_uri + "/bob/document.txt", "", :status =>
|
14
|
+
stub_json_request(:delete, @base_uri + "/bob/document.txt", "", :status => [204, "No Content"])
|
15
15
|
@linked_document = Grendel::LinkedDocument.new(@user, :name => "document.txt", :owner => {:id => "bob"})
|
16
16
|
end
|
17
17
|
|
@@ -4,17 +4,17 @@ describe "Grendel::User" do
|
|
4
4
|
before do
|
5
5
|
@client = Grendel::Client.new("http://grendel")
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
describe "list" do
|
9
9
|
before do
|
10
10
|
stub_json_request(:get, "grendel/users", %{{
|
11
11
|
"users":[
|
12
12
|
{"id":"alice", "uri":"http://grendel/users/alice"},
|
13
|
-
{"id":"bob", "uri":"http://grendel/users/bob"}
|
13
|
+
{"id":"bob", "uri":"http://grendel/users/bob"}
|
14
14
|
]
|
15
15
|
}})
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
it "should return an array of all users" do
|
19
19
|
users = @client.users.list
|
20
20
|
users.length.should == 2
|
@@ -33,9 +33,9 @@ describe "Grendel::User" do
|
|
33
33
|
"created-at":"20091227T211120Z",
|
34
34
|
"keys":['2048-RSA/0A895A19', '2048-RSA/39D1621B']
|
35
35
|
}})
|
36
|
-
stub_json_request(:get, "grendel/users/nobody", "", :status =>
|
36
|
+
stub_json_request(:get, "grendel/users/nobody", "", :status => [404, "Not Found"])
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it "should return the user" do
|
40
40
|
user = @client.users.find("alice")
|
41
41
|
user.id.should == "alice"
|
@@ -43,29 +43,29 @@ describe "Grendel::User" do
|
|
43
43
|
user.created_at.should == DateTime.parse("20091227T211120Z")
|
44
44
|
user.keys.length.should == 2
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
it "should raise an exception if the user is not found" do
|
48
48
|
lambda {
|
49
49
|
@client.users.find("nobody")
|
50
|
-
}.should raise_error(Grendel::Client::HTTPException) {|error| error.message.should
|
50
|
+
}.should raise_error(Grendel::Client::HTTPException) {|error| error.message.should == "404 Not Found"}
|
51
51
|
end
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
describe "create" do
|
55
55
|
describe "a successful request" do
|
56
56
|
before do
|
57
57
|
@user_id = "bob"
|
58
58
|
@password = "s3kret"
|
59
59
|
@uri = "http://grendel/users/#{@user_id}"
|
60
|
-
stub_json_request(:post, "grendel/users", "", :status =>
|
60
|
+
stub_json_request(:post, "grendel/users", "", :status => [201, "Created"], "Location" => @uri)
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
it "should send a properly-formatted request" do
|
64
64
|
@client.users.create(@user_id, @password)
|
65
65
|
params = { :id => @user_id, :password => @password }
|
66
66
|
request(:post, "grendel/users").with(:body => params.to_json).should have_been_made.once
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
it "should return a user" do
|
70
70
|
user = @client.users.create(@user_id, @password)
|
71
71
|
user.id.should == @user_id
|
@@ -73,16 +73,16 @@ describe "Grendel::User" do
|
|
73
73
|
user.uri.should == "/users/bob"
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
describe "an unsuccessful request" do
|
78
78
|
before do
|
79
|
-
stub_json_request(:post, "grendel/users", "", :status =>
|
79
|
+
stub_json_request(:post, "grendel/users", "", :status => [422, "Unprocessable Entity"])
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
it "should raise an exception if the user already exists" do
|
83
83
|
lambda {
|
84
84
|
@client.users.create("joe","exists")
|
85
|
-
}.should raise_error(Grendel::Client::HTTPException) {|error| error.message.should
|
85
|
+
}.should raise_error(Grendel::Client::HTTPException) {|error| error.message.should == "422 Unprocessable Entity"}
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
|
4
|
+
begin
|
5
|
+
require 'bundler'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'bundler'
|
9
|
+
end
|
10
|
+
Bundler.setup
|
11
|
+
|
4
12
|
require 'grendel'
|
5
13
|
require 'spec'
|
6
14
|
require 'spec/autorun'
|
@@ -10,11 +18,11 @@ include WebMock
|
|
10
18
|
|
11
19
|
Spec::Runner.configure do |config|
|
12
20
|
WebMock.disable_net_connect!
|
13
|
-
|
21
|
+
|
14
22
|
# helper to add Content-Type: application/json to each request
|
15
23
|
def stub_json_request(method, uri, body, headers = {})
|
16
|
-
headers = headers.
|
17
|
-
status = headers.delete(:status) ||
|
24
|
+
headers = headers.merge("Content-Type" => "application/json")
|
25
|
+
status = headers.delete(:status) || 200
|
18
26
|
stub_request(method, uri).
|
19
27
|
to_return(:body => body, :status => status, :headers => headers)
|
20
28
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 2
|
9
|
+
version: 0.1.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Brad Greenlee
|
@@ -14,12 +14,10 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-04-27 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
name: json
|
22
|
-
prerelease: false
|
23
21
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
22
|
requirements:
|
25
23
|
- - ">="
|
@@ -27,11 +25,11 @@ dependencies:
|
|
27
25
|
segments:
|
28
26
|
- 0
|
29
27
|
version: "0"
|
28
|
+
prerelease: false
|
30
29
|
type: :runtime
|
30
|
+
name: json
|
31
31
|
version_requirements: *id001
|
32
32
|
- !ruby/object:Gem::Dependency
|
33
|
-
name: httparty
|
34
|
-
prerelease: false
|
35
33
|
requirement: &id002 !ruby/object:Gem::Requirement
|
36
34
|
requirements:
|
37
35
|
- - ">="
|
@@ -39,21 +37,21 @@ dependencies:
|
|
39
37
|
segments:
|
40
38
|
- 0
|
41
39
|
version: "0"
|
40
|
+
prerelease: false
|
42
41
|
type: :runtime
|
42
|
+
name: httparty
|
43
43
|
version_requirements: *id002
|
44
44
|
- !ruby/object:Gem::Dependency
|
45
|
-
name: rspec
|
46
|
-
prerelease: false
|
47
45
|
requirement: &id003 !ruby/object:Gem::Requirement
|
48
46
|
requirements:
|
49
47
|
- - ">="
|
50
48
|
- !ruby/object:Gem::Version
|
51
49
|
segments:
|
52
|
-
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
- 0
|
51
|
+
version: "0"
|
52
|
+
prerelease: false
|
53
|
+
type: :runtime
|
54
|
+
name: mime-types
|
57
55
|
version_requirements: *id003
|
58
56
|
description: |-
|
59
57
|
Grendel is a RESTful web service which allows for the secure storage of users'
|
@@ -69,6 +67,8 @@ extra_rdoc_files:
|
|
69
67
|
files:
|
70
68
|
- .document
|
71
69
|
- .gitignore
|
70
|
+
- Gemfile
|
71
|
+
- Gemfile.lock
|
72
72
|
- LICENSE.md
|
73
73
|
- README.md
|
74
74
|
- Rakefile
|