datacatalog 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.md CHANGED
@@ -1,2 +1,2 @@
1
- ### 0.1.0 / 2009-08-15
2
- * Initial version
1
+ ### 0.1.0 / 2009-08-15
2
+ * Initial version
data/LICENSE.md CHANGED
@@ -1,11 +1,11 @@
1
- Copyright (c) 2009, Sunlight Foundation.
2
-
3
- All rights reserved.
4
-
5
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
-
7
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
- * Neither the name of Sunlight Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
-
11
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1
+ Copyright (c) 2009, Sunlight Foundation.
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+ * Neither the name of Sunlight Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md CHANGED
@@ -1,34 +1,34 @@
1
- # Ruby Gem for the National Data Catalog API
2
-
3
- Under heavy development.
4
-
5
- ## Installation
6
-
7
- For now, the gem will not be packaged. Instead, install it manually:
8
-
9
- $ git clone git clone git://github.com/sunlightlabs/ruby-datacatalog.git
10
- $ cd ruby-datacatalog
11
- $ rake check_dependencies
12
- $ rake build
13
- $ rake install # uses sudo
14
- # Or, instead of the line above:
15
- $ gem install pkg/datacatalog-0.1.0.gem
16
-
17
- ## Usage
18
-
19
- require 'rubygems'
20
- require 'datacatalog'
21
-
22
- DataCatalog.api_key = 'c40505247a5e308a24d70a0118f76534b543795b'
23
-
24
- ## Running Specs
25
-
26
- We're not mocking out any of the web API calls in the specs. Instead, we expect developers who wish to run the specs to download and run a local sandbox instance of the [Data Catalog API](http://github.com/sunlightlabs/datacatalog-api), a Sinatra app:
27
-
28
- git clone git://github.com/sunlightlabs/datacatalog-api.git
29
-
30
- Get the app running like any normal Sinatra app, so you can choose to use thin or Passenger or new hotness like [Unicorn](http://unicorn.bogomips.org/). Some special considerations:
31
-
32
- 1. We recommend creating a `sandbox` entry in `datacatalog-api`'s `config.yml`.
33
- 2. Run `RACK_ENV=sandbox rake db:ensure_admin` in the `datacatalog-api` project to create a super admin for the API instance.
34
- 3. Back here in `ruby-datacatalog`, use the example file in `spec/` to create your own `spec/sandbox_api.yml` with the API key of the admin and your local URI.
1
+ # Ruby Gem for the National Data Catalog API
2
+
3
+ Under heavy development.
4
+
5
+ ## Installation
6
+
7
+ For now, the gem will not be packaged. Instead, install it manually:
8
+
9
+ $ git clone git clone git://github.com/sunlightlabs/ruby-datacatalog.git
10
+ $ cd ruby-datacatalog
11
+ $ rake check_dependencies
12
+ $ rake build
13
+ $ rake install # uses sudo
14
+ # Or, instead of the line above:
15
+ $ gem install pkg/datacatalog-0.1.0.gem
16
+
17
+ ## Usage
18
+
19
+ require 'rubygems'
20
+ require 'datacatalog'
21
+
22
+ DataCatalog.api_key = 'c40505247a5e308a24d70a0118f76534b543795b'
23
+
24
+ ## Running Specs
25
+
26
+ We're not mocking out any of the web API calls in the specs. Instead, we expect developers who wish to run the specs to download and run a local sandbox instance of the [Data Catalog API](http://github.com/sunlightlabs/datacatalog-api), a Sinatra app:
27
+
28
+ git clone git://github.com/sunlightlabs/datacatalog-api.git
29
+
30
+ Get the app running like any normal Sinatra app, so you can choose to use thin or Passenger or new hotness like [Unicorn](http://unicorn.bogomips.org/). Some special considerations:
31
+
32
+ 1. We recommend creating a `sandbox` entry in `datacatalog-api`'s `config.yml`.
33
+ 2. Run `RACK_ENV=sandbox rake db:ensure_admin` in the `datacatalog-api` project to create a super admin for the API instance.
34
+ 3. Back here in `ruby-datacatalog`, use the example file in `spec/` to create your own `spec/sandbox_api.yml` with the API key of the admin and your local URI.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.3.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{datacatalog}
8
- s.version = "0.2.4"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Luigi Montanez", "David James"]
12
- s.date = %q{2009-10-10}
12
+ s.date = %q{2009-10-14}
13
13
  s.description = %q{A Ruby client library for the National Data Catalog API}
14
14
  s.email = %q{luigi@sunlightfoundation.com}
15
15
  s.extra_rdoc_files = [
@@ -1,77 +1,77 @@
1
- module DataCatalog
2
-
3
- class Base < Mash
4
-
5
- DEFAULT_BASE_URI = 'http://api.nationaldatacatalog.com'
6
-
7
- include HTTParty
8
-
9
- format :json
10
- base_uri DEFAULT_BASE_URI
11
-
12
- class << self
13
- alias_method :_delete, :delete
14
- alias_method :_get, :get
15
- alias_method :_post, :post
16
- alias_method :_put, :put
17
-
18
- undef_method :delete
19
- undef_method :get
20
- undef_method :post
21
- undef_method :put
22
- end
23
-
24
- def self.http_delete(path, options={})
25
- check_status(_delete(path, options))
26
- end
27
-
28
- def self.http_get(path, options={})
29
- check_status(_get(path, options))
30
- end
31
-
32
- def self.http_post(path, options={})
33
- check_status(_post(path, options))
34
- end
35
-
36
- def self.http_put(path, options={})
37
- check_status(_put(path, options))
38
- end
39
-
40
- # == protected
41
-
42
- def self.check_status(response)
43
- case response.code
44
- when 400: raise BadRequest, error(response)
45
- when 401: raise Unauthorized, error(response)
46
- when 403: raise Forbidden, error(response)
47
- when 404: raise NotFound, error(response)
48
- when 409: raise Conflict, error(response)
49
- when 500: raise InternalServerError, error(response)
50
- end
51
- response
52
- end
53
-
54
- def self.error(response)
55
- parsed_body = JSON.parse(response.body)
56
- if parsed_body.empty?
57
- "Response was empty"
58
- elsif parsed_body["errors"]
59
- parsed_body["errors"].inspect
60
- else
61
- response.body
62
- end
63
- rescue JSON::ParserError
64
- "Unable to parse: #{response.body.inspect}"
65
- end
66
-
67
- def self.many(response)
68
- response.map { |item| new(item) }
69
- end
70
-
71
- def self.one(response)
72
- response.blank? ? nil : new(response)
73
- end
74
-
75
- end
76
-
77
- end
1
+ module DataCatalog
2
+
3
+ class Base < Mash
4
+
5
+ DEFAULT_BASE_URI = 'http://api.nationaldatacatalog.com'
6
+
7
+ include HTTParty
8
+
9
+ format :json
10
+ base_uri DEFAULT_BASE_URI
11
+
12
+ class << self
13
+ alias_method :_delete, :delete
14
+ alias_method :_get, :get
15
+ alias_method :_post, :post
16
+ alias_method :_put, :put
17
+
18
+ undef_method :delete
19
+ undef_method :get
20
+ undef_method :post
21
+ undef_method :put
22
+ end
23
+
24
+ def self.http_delete(path, options={})
25
+ check_status(_delete(path, options))
26
+ end
27
+
28
+ def self.http_get(path, options={})
29
+ check_status(_get(path, options))
30
+ end
31
+
32
+ def self.http_post(path, options={})
33
+ check_status(_post(path, options))
34
+ end
35
+
36
+ def self.http_put(path, options={})
37
+ check_status(_put(path, options))
38
+ end
39
+
40
+ # == protected
41
+
42
+ def self.check_status(response)
43
+ case response.code
44
+ when 400: raise BadRequest, error(response)
45
+ when 401: raise Unauthorized, error(response)
46
+ when 403: raise Forbidden, error(response)
47
+ when 404: raise NotFound, error(response)
48
+ when 409: raise Conflict, error(response)
49
+ when 500: raise InternalServerError, error(response)
50
+ end
51
+ response
52
+ end
53
+
54
+ def self.error(response)
55
+ parsed_body = JSON.parse(response.body)
56
+ if parsed_body.empty?
57
+ "Response was empty"
58
+ elsif parsed_body["errors"]
59
+ parsed_body["errors"].inspect
60
+ else
61
+ response.body
62
+ end
63
+ rescue JSON::ParserError
64
+ "Unable to parse: #{response.body.inspect}"
65
+ end
66
+
67
+ def self.many(response)
68
+ response.map { |item| new(item) }
69
+ end
70
+
71
+ def self.one(response)
72
+ response.blank? ? nil : new(response)
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -1,8 +1,8 @@
1
- require 'rubygems'
2
- require 'activesupport'
3
- require 'httparty'
4
- require 'mash'
5
-
6
- require File.dirname(__FILE__) + '/main'
7
- require File.dirname(__FILE__) + '/base'
8
- Dir.glob(File.dirname(__FILE__) + '/resources/*.rb').each { |f| require f }
1
+ require 'rubygems'
2
+ require 'activesupport'
3
+ require 'httparty'
4
+ require 'mash'
5
+
6
+ require File.dirname(__FILE__) + '/main'
7
+ require File.dirname(__FILE__) + '/base'
8
+ Dir.glob(File.dirname(__FILE__) + '/resources/*.rb').each { |f| require f }
@@ -1,41 +1,41 @@
1
- module DataCatalog
2
-
3
- # == Exceptions
4
-
5
- class Error < RuntimeError; end
6
- class BadRequest < Error; end # 400
7
- class Unauthorized < Error; end # 401
8
- class Forbidden < Error; end # 403
9
- class NotFound < Error; end # 404
10
- class Conflict < Error; end # 409
11
- class InternalServerError < Error; end # 500
12
- class ApiKeyNotConfigured < Error; end
13
- class CannotDeletePrimaryApiKey < Error; end
14
-
15
- # == Accessors
16
-
17
- def self.api_key
18
- Base.default_params[:api_key]
19
- end
20
-
21
- def self.api_key=(key)
22
- Base.default_params :api_key => key
23
- end
24
-
25
- def self.base_uri
26
- Base.base_uri
27
- end
28
-
29
- def self.base_uri=(uri)
30
- Base.base_uri(uri.blank? ? Base::DEFAULT_BASE_URI : uri)
31
- end
32
-
33
- def self.with_key(temp_key)
34
- original_key = DataCatalog.api_key
35
- DataCatalog.api_key = temp_key
36
- result = yield
37
- DataCatalog.api_key = original_key
38
- result
39
- end
40
-
41
- end
1
+ module DataCatalog
2
+
3
+ # == Exceptions
4
+
5
+ class Error < RuntimeError; end
6
+ class BadRequest < Error; end # 400
7
+ class Unauthorized < Error; end # 401
8
+ class Forbidden < Error; end # 403
9
+ class NotFound < Error; end # 404
10
+ class Conflict < Error; end # 409
11
+ class InternalServerError < Error; end # 500
12
+ class ApiKeyNotConfigured < Error; end
13
+ class CannotDeletePrimaryApiKey < Error; end
14
+
15
+ # == Accessors
16
+
17
+ def self.api_key
18
+ Base.default_params[:api_key]
19
+ end
20
+
21
+ def self.api_key=(key)
22
+ Base.default_params :api_key => key
23
+ end
24
+
25
+ def self.base_uri
26
+ Base.base_uri
27
+ end
28
+
29
+ def self.base_uri=(uri)
30
+ Base.base_uri(uri.blank? ? Base::DEFAULT_BASE_URI : uri)
31
+ end
32
+
33
+ def self.with_key(temp_key)
34
+ original_key = DataCatalog.api_key
35
+ DataCatalog.api_key = temp_key
36
+ result = yield
37
+ DataCatalog.api_key = original_key
38
+ result
39
+ end
40
+
41
+ end
@@ -1,2 +1,2 @@
1
- api_key: d193d1523d49e4caf46297ef94d7a2c995d3b2cb # generate with rake db:ensure_admin on datacatalog-api
2
- base_uri: sandbox.dc-api.local
1
+ api_key: d193d1523d49e4caf46297ef94d7a2c995d3b2cb # generate with rake db:ensure_admin on datacatalog-api
2
+ base_uri: sandbox.dc-api.local
@@ -1,21 +1,21 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
- include DataCatalog
3
-
4
- describe DataCatalog do
5
-
6
- describe ".about" do
7
- before do
8
- setup_api
9
- end
10
-
11
- it "should return information about the API" do
12
- about = About.get
13
- about.should be_an_instance_of(About)
14
- about.name.should == "National Data Catalog API"
15
- about.project_page.should == {
16
- "href" => "http://sunlightlabs.com/projects/datacatalog/"
17
- }
18
- end
19
- end
20
-
21
- end
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ include DataCatalog
3
+
4
+ describe DataCatalog do
5
+
6
+ describe ".about" do
7
+ before do
8
+ setup_api
9
+ end
10
+
11
+ it "should return information about the API" do
12
+ about = About.get
13
+ about.should be_an_instance_of(About)
14
+ about.name.should == "National Data Catalog API"
15
+ about.project_page.should == {
16
+ "href" => "http://sunlightlabs.com/projects/datacatalog/"
17
+ }
18
+ end
19
+ end
20
+
21
+ end
@@ -1,145 +1,145 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
- include DataCatalog
3
-
4
- module ApiKeyHelpers
5
- def create_user
6
- User.create({
7
- :name => "Ted Smith",
8
- :email => "ted@email.com"
9
- })
10
- end
11
-
12
- def create_user_with_2_keys
13
- user = create_user
14
- ApiKey.create(user.id, {
15
- :purpose => "Civic hacking",
16
- :key_type => "application"
17
- })
18
- User.get(user.id)
19
- end
20
- end
21
-
22
- describe ApiKey do
23
- include ApiKeyHelpers
24
-
25
- before do
26
- setup_api
27
- clean_slate
28
- end
29
-
30
- describe ".all" do
31
- before do
32
- @user = create_user_with_2_keys
33
- @api_keys = ApiKey.all(@user.id)
34
- end
35
-
36
- it "should return an enumeration of API keys" do
37
- @api_keys.each do |api_key|
38
- api_key.should be_an_instance_of(ApiKey)
39
- end
40
- end
41
-
42
- it "should return correct titles" do
43
- @api_keys.map(&:key_type).should == %w(primary application)
44
- end
45
- end
46
-
47
- describe ".all with conditions" do
48
- before do
49
- @user = create_user_with_2_keys
50
- @api_keys = ApiKey.all(@user.id, :key_type => "application")
51
- end
52
-
53
- it "should return an enumeration of API keys" do
54
- @api_keys.each do |api_key|
55
- api_key.should be_an_instance_of(ApiKey)
56
- end
57
- end
58
-
59
- it "should return correct titles" do
60
- @api_keys.map(&:key_type).should == %w(application)
61
- end
62
- end
63
-
64
- describe ".create" do
65
- it "should create a new API key from basic params" do
66
- user = create_user_with_2_keys
67
- api_key = ApiKey.create(user.id, {
68
- :purpose => "Data wrangling",
69
- :key_type => "valet"
70
- })
71
- api_key.should be_an_instance_of(ApiKey)
72
- api_key.key_type.should == "valet"
73
- end
74
- end
75
-
76
- describe ".first" do
77
- before do
78
- @user = create_user_with_2_keys
79
- end
80
-
81
- it "should return an API key" do
82
- api_key = ApiKey.first(@user.id, :purpose => "Civic hacking")
83
- api_key.should be_an_instance_of(ApiKey)
84
- api_key.purpose.should == "Civic hacking"
85
- end
86
-
87
- it "should return nil if nothing found" do
88
- api_key = ApiKey.first(@user.id, :purpose => "Evil")
89
- api_key.should be_nil
90
- end
91
- end
92
-
93
- describe ".get" do
94
- before do
95
- @user = create_user_with_2_keys
96
- @api_key = @user.api_keys[1]
97
- end
98
-
99
- it "should return an API key" do
100
- api_key = ApiKey.get(@user.id, @api_key.id)
101
- api_key.should be_an_instance_of(ApiKey)
102
- api_key.purpose.should == "Civic hacking"
103
- end
104
-
105
- it "should raise NotFound if no API key exists" do
106
- executing do
107
- ApiKey.get(@user.id, mangle(@api_key.id))
108
- end.should raise_error(NotFound)
109
- end
110
- end
111
-
112
- describe ".update" do
113
- before do
114
- @user = create_user_with_2_keys
115
- @api_key = @user.api_keys[1]
116
- end
117
-
118
- it "should update an existing source from valid params" do
119
- api_key = ApiKey.update(@user.id, @api_key.id, {
120
- :purpose => "Local Government Reporting"
121
- })
122
- api_key.should be_an_instance_of(ApiKey)
123
- api_key.purpose.should == "Local Government Reporting"
124
- end
125
- end
126
-
127
- describe ".destroy" do
128
- before do
129
- @user = create_user_with_2_keys
130
- @api_key = @user.api_keys[1]
131
- end
132
-
133
- it "should destroy an existing source" do
134
- result = ApiKey.destroy(@user.id, @api_key.id)
135
- result.should be_true
136
- end
137
-
138
- it "should raise NotFound if API key does not exist" do
139
- executing do
140
- ApiKey.destroy(@user.id, mangle(@api_key.id))
141
- end.should raise_error(NotFound)
142
- end
143
- end
144
-
145
- end
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ include DataCatalog
3
+
4
+ module ApiKeyHelpers
5
+ def create_user
6
+ User.create({
7
+ :name => "Ted Smith",
8
+ :email => "ted@email.com"
9
+ })
10
+ end
11
+
12
+ def create_user_with_2_keys
13
+ user = create_user
14
+ ApiKey.create(user.id, {
15
+ :purpose => "Civic hacking",
16
+ :key_type => "application"
17
+ })
18
+ User.get(user.id)
19
+ end
20
+ end
21
+
22
+ describe ApiKey do
23
+ include ApiKeyHelpers
24
+
25
+ before do
26
+ setup_api
27
+ clean_slate
28
+ end
29
+
30
+ describe ".all" do
31
+ before do
32
+ @user = create_user_with_2_keys
33
+ @api_keys = ApiKey.all(@user.id)
34
+ end
35
+
36
+ it "should return an enumeration of API keys" do
37
+ @api_keys.each do |api_key|
38
+ api_key.should be_an_instance_of(ApiKey)
39
+ end
40
+ end
41
+
42
+ it "should return correct titles" do
43
+ @api_keys.map(&:key_type).should == %w(primary application)
44
+ end
45
+ end
46
+
47
+ describe ".all with conditions" do
48
+ before do
49
+ @user = create_user_with_2_keys
50
+ @api_keys = ApiKey.all(@user.id, :key_type => "application")
51
+ end
52
+
53
+ it "should return an enumeration of API keys" do
54
+ @api_keys.each do |api_key|
55
+ api_key.should be_an_instance_of(ApiKey)
56
+ end
57
+ end
58
+
59
+ it "should return correct titles" do
60
+ @api_keys.map(&:key_type).should == %w(application)
61
+ end
62
+ end
63
+
64
+ describe ".create" do
65
+ it "should create a new API key from basic params" do
66
+ user = create_user_with_2_keys
67
+ api_key = ApiKey.create(user.id, {
68
+ :purpose => "Data wrangling",
69
+ :key_type => "valet"
70
+ })
71
+ api_key.should be_an_instance_of(ApiKey)
72
+ api_key.key_type.should == "valet"
73
+ end
74
+ end
75
+
76
+ describe ".first" do
77
+ before do
78
+ @user = create_user_with_2_keys
79
+ end
80
+
81
+ it "should return an API key" do
82
+ api_key = ApiKey.first(@user.id, :purpose => "Civic hacking")
83
+ api_key.should be_an_instance_of(ApiKey)
84
+ api_key.purpose.should == "Civic hacking"
85
+ end
86
+
87
+ it "should return nil if nothing found" do
88
+ api_key = ApiKey.first(@user.id, :purpose => "Evil")
89
+ api_key.should be_nil
90
+ end
91
+ end
92
+
93
+ describe ".get" do
94
+ before do
95
+ @user = create_user_with_2_keys
96
+ @api_key = @user.api_keys[1]
97
+ end
98
+
99
+ it "should return an API key" do
100
+ api_key = ApiKey.get(@user.id, @api_key.id)
101
+ api_key.should be_an_instance_of(ApiKey)
102
+ api_key.purpose.should == "Civic hacking"
103
+ end
104
+
105
+ it "should raise NotFound if no API key exists" do
106
+ executing do
107
+ ApiKey.get(@user.id, mangle(@api_key.id))
108
+ end.should raise_error(NotFound)
109
+ end
110
+ end
111
+
112
+ describe ".update" do
113
+ before do
114
+ @user = create_user_with_2_keys
115
+ @api_key = @user.api_keys[1]
116
+ end
117
+
118
+ it "should update an existing source from valid params" do
119
+ api_key = ApiKey.update(@user.id, @api_key.id, {
120
+ :purpose => "Local Government Reporting"
121
+ })
122
+ api_key.should be_an_instance_of(ApiKey)
123
+ api_key.purpose.should == "Local Government Reporting"
124
+ end
125
+ end
126
+
127
+ describe ".destroy" do
128
+ before do
129
+ @user = create_user_with_2_keys
130
+ @api_key = @user.api_keys[1]
131
+ end
132
+
133
+ it "should destroy an existing source" do
134
+ result = ApiKey.destroy(@user.id, @api_key.id)
135
+ result.should be_true
136
+ end
137
+
138
+ it "should raise NotFound if API key does not exist" do
139
+ executing do
140
+ ApiKey.destroy(@user.id, mangle(@api_key.id))
141
+ end.should raise_error(NotFound)
142
+ end
143
+ end
144
+
145
+ end