wistia-api 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm use 1.9.2@wistia-api
1
+ rvm use 1.9.3@wistia-api --create
data/Gemfile CHANGED
@@ -1,17 +1,14 @@
1
- source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
1
+ source 'http://rubygems.org'
5
2
 
6
3
  gem 'activeresource', '>= 2.3.8'
7
- gem 'configatron', '>= 2.6.4'
8
4
 
9
5
  # Add dependencies to develop your gem here.
10
6
  # Include everything needed to run rake, tests, features, etc.
11
7
  group :development do
12
- gem "rspec", "~> 2.3.0"
13
- gem "bundler", "~> 1.0.0"
14
- gem "jeweler", "~> 1.5.2"
15
- gem "rcov", ">= 0"
8
+ gem 'bundler', '~> 1.2'
9
+ gem 'fakeweb', '~> 1.3'
10
+ gem 'jeweler', '~> 1.8'
11
+ gem 'rcov', '>= 0'
12
+ gem 'rspec', '~> 2.12'
16
13
  end
17
14
 
data/Gemfile.lock CHANGED
@@ -10,34 +10,36 @@ GEM
10
10
  activesupport (= 3.0.3)
11
11
  activesupport (3.0.3)
12
12
  builder (2.1.2)
13
- configatron (2.6.4)
14
- yamler (>= 0.1.0)
15
- diff-lcs (1.1.2)
13
+ diff-lcs (1.1.3)
14
+ fakeweb (1.3.0)
16
15
  git (1.2.5)
17
16
  i18n (0.5.0)
18
- jeweler (1.5.2)
19
- bundler (~> 1.0.0)
17
+ jeweler (1.8.4)
18
+ bundler (~> 1.0)
20
19
  git (>= 1.2.5)
21
20
  rake
22
- rake (0.8.7)
21
+ rdoc
22
+ json (1.7.7)
23
+ rake (10.0.3)
23
24
  rcov (0.9.9)
24
- rspec (2.3.0)
25
- rspec-core (~> 2.3.0)
26
- rspec-expectations (~> 2.3.0)
27
- rspec-mocks (~> 2.3.0)
28
- rspec-core (2.3.1)
29
- rspec-expectations (2.3.0)
30
- diff-lcs (~> 1.1.2)
31
- rspec-mocks (2.3.0)
32
- yamler (0.1.0)
25
+ rdoc (3.12.1)
26
+ json (~> 1.4)
27
+ rspec (2.12.0)
28
+ rspec-core (~> 2.12.0)
29
+ rspec-expectations (~> 2.12.0)
30
+ rspec-mocks (~> 2.12.0)
31
+ rspec-core (2.12.2)
32
+ rspec-expectations (2.12.1)
33
+ diff-lcs (~> 1.1.3)
34
+ rspec-mocks (2.12.2)
33
35
 
34
36
  PLATFORMS
35
37
  ruby
36
38
 
37
39
  DEPENDENCIES
38
40
  activeresource (>= 2.3.8)
39
- bundler (~> 1.0.0)
40
- configatron (>= 2.6.4)
41
- jeweler (~> 1.5.2)
41
+ bundler (~> 1.2)
42
+ fakeweb (~> 1.3)
43
+ jeweler (~> 1.8)
42
44
  rcov
43
- rspec (~> 2.3.0)
45
+ rspec (~> 2.12)
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ Wistia API
2
+ ==========
3
+
4
+ Ruby wrapper for Wistia's API
5
+
6
+ # Installation
7
+
8
+ ## Required gems:
9
+
10
+ * activeresource >= 2.3.8
11
+
12
+ ## Install:
13
+
14
+ gem install wistia-api
15
+
16
+ # Basic Usage
17
+
18
+ Start by requiring wistia:
19
+
20
+ require 'wistia'
21
+
22
+ Configure your API password:
23
+
24
+ Wistia.password = 'your-api-password-here'
25
+
26
+ **NOTE:** [see the instructions for generating an API password](http://wistia.com/doc/data-api#getting_started)
27
+
28
+ Now you can use the <tt>Wistia::Media</tt>, <tt>Wistia::Project</tt>, and <tt>Wistia::Projects::Sharing</tt> classes as ActiveResource wrappers around Wistia's API.
29
+
30
+ See http://wistia.com/doc/data-api for more info.
31
+
32
+ Configuration Options
33
+ ---------------------
34
+
35
+ Set the format of the API:
36
+
37
+ Wistia.format = 'json' # This is the default.
38
+ Wistia.format = 'xml'
39
+
40
+ Read configuration from an external YAML file:
41
+
42
+ Wistia.use_config!(path_to_yaml)
43
+
44
+ For an example YAML config, see spec/support/config.test.yml
45
+
46
+ Configure using a Hash:
47
+
48
+ Wistia.use_config!(:wistia => {
49
+ :api => {
50
+ :password => 'your-api-password',
51
+ :format => 'xml-or-json'
52
+ }
53
+ })
54
+
55
+ Examples
56
+ --------
57
+
58
+ List all Media in your account:
59
+
60
+ Wistia::Media.find(:all)
61
+
62
+ List all Projects in your account:
63
+
64
+ Wistia::Project.find(:all)
65
+
66
+ List all Sharing objects for project 23:
67
+
68
+ Wistia::Projects::Sharing.find(:all, :params => { :project_id => 23 })
69
+
70
+ Get stats for a project since the December 1, 2012
71
+
72
+ Wistia::Stats::Project.get('efjh6kxmc9/by_date', :start_date => '2012-12-01')
73
+
74
+ List Overall Stats for Your Account
75
+
76
+ Wistia::Stats::Account.find_singleton
77
+
78
+ Copyright
79
+ ---------
80
+
81
+ Copyright (c) 2011 Wistia, Inc. See LICENSE.txt for
82
+ further details.
data/Rakefile CHANGED
@@ -12,19 +12,13 @@ require 'rake'
12
12
  require 'jeweler'
13
13
  Jeweler::Tasks.new do |gem|
14
14
  # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "wistia-api"
16
- gem.homepage = "http://github.com/wistia/wistia-api"
17
- gem.license = "MIT"
18
- gem.summary = %Q{Ruby wrapper for Wistia's API}
19
- gem.description = %Q{A ruby library for working with Wistia's data API.}
20
- gem.email = "support@wistia.com"
21
- gem.authors = ["Jim Bancroft", "Mark Bates"]
22
- # Include your dependencies below. Runtime dependencies are required when using your gem,
23
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
- # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
- # gem.add_development_dependency 'rspec', '> 1.2.3'
26
- gem.add_runtime_dependency 'activeresource', '>= 2.3.8'
27
- gem.add_runtime_dependency 'configatron', '>= 2.6.4'
15
+ gem.name = 'wistia-api'
16
+ gem.homepage = 'http://github.com/wistia/wistia-api'
17
+ gem.license = 'MIT'
18
+ gem.summary = 'Ruby wrapper for Wistia\'s API'
19
+ gem.description = 'A ruby library for working with Wistia\'s data API.'
20
+ gem.email = 'support@wistia.com'
21
+ gem.authors = ['Jeff Vincent', 'Jim Bancroft', 'Mark Bates', 'Robby Grossman']
28
22
  end
29
23
  Jeweler::RubygemsDotOrgTasks.new
30
24
 
@@ -41,7 +35,7 @@ end
41
35
 
42
36
  task :default => :spec
43
37
 
44
- require 'rake/rdoctask'
38
+ require 'rdoc/task'
45
39
  Rake::RDocTask.new do |rdoc|
46
40
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
41
 
@@ -50,4 +44,3 @@ Rake::RDocTask.new do |rdoc|
50
44
  rdoc.rdoc_files.include('README*')
51
45
  rdoc.rdoc_files.include('lib/**/*.rb')
52
46
  end
53
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.2.2
data/lib/wistia/base.rb CHANGED
@@ -1,21 +1,19 @@
1
- require File.join(File.dirname(__FILE__), 'config')
1
+ require 'wistia/config'
2
2
 
3
3
  module Wistia
4
4
  class Base < ActiveResource::Base
5
- # Resets all the ActiveResource configuration options to what's currently stored in the configatron.
5
+ self.site = Wistia::API_BASE_URL
6
+ self.user = 'api'
7
+
6
8
  def self.refresh_config!
7
- self.site = Wistia::Config.config.api.url
8
- self.user = Wistia::Config.config.api.user
9
- self.password = Wistia::Config.config.api.key
10
- self.format = Wistia::Config.config.api.format.to_sym
9
+ self.password = Wistia.password
10
+ self.format = ActiveResource::Formats::JsonFormat if Wistia.format == :json
11
+ self.format = ActiveResource::Formats::XmlFormat if Wistia.format == :xml
11
12
  end
12
-
13
13
  refresh_config!
14
-
14
+
15
15
  def to_json(options = {})
16
- return self.attributes.to_json(options)
16
+ self.attributes.to_json(options)
17
17
  end
18
-
19
18
  end
20
19
  end
21
-
data/lib/wistia/config.rb CHANGED
@@ -1,25 +1,62 @@
1
- module Wistia
2
-
3
- class << self
4
-
5
- def config(&block)
6
- Wistia::Config.config(&block)
7
- end
8
-
9
- end
10
-
11
- module Config
1
+ require 'wistia/initialization'
12
2
 
13
- class << self
14
-
15
- def config(&block)
16
- yield configatron.wistia if block_given?
17
- configatron.wistia
3
+ module Wistia
4
+ # Specifies a new configuration to use for the API.
5
+ # Accepts either a Hash or a String pointing to a YAML configuration file.
6
+ #
7
+ # Example using a Hash:
8
+ # Wistia.use_config!(:wistia => { :api => { :key => 'your-api-key', :format => 'json-or-xml' } })
9
+ def self.use_config!(config)
10
+ if config.is_a?(String) && File.exists?(config) && File.extname(config) == '.yml'
11
+ self.use_config!(YAML.load_file(config))
12
+ elsif config.is_a?(Hash)
13
+ config = config.with_indifferent_access
14
+
15
+ if data_hash = config && config[:wistia] && config[:wistia][:api]
16
+ if data_hash[:key]
17
+ data_hash[:password] = data_hash[:key]
18
+ warn '[DEPRECATION] You have configured wistia-api authentication using the configuration key: "key".'
19
+ warn ' Please use the configuration key "password" instead (using the same value).'
20
+ end
21
+
22
+ new_password = data_hash[:password]
23
+ self.password = new_password unless new_password.nil?
24
+ new_format = data_hash[:format]
25
+ self.format = new_format.to_sym unless new_format.nil?
18
26
  end
19
-
27
+ else
28
+ raise ArgumentError, 'Invalid config'
20
29
  end
30
+ end
21
31
 
32
+ # Set your API password using this method.
33
+ # For instructions to find your API password, go here: http://wistia.com/doc/api-enable
34
+ def self.password= (new_password)
35
+ @@password = new_password
36
+ Wistia.refresh_config_for_wistia_api_objects!
37
+ @@password
22
38
  end
39
+ def self.password; @@password; end
40
+
41
+ # Set the format that the API uses to either 'json' or 'xml'.
42
+ # Accepts either a String or a Symbol.
43
+ def self.format=(new_format)
44
+ valid_formats = [:json, :xml]
45
+ raise ArgumentError, "Invalid format. Supported formats: #{valid_formats.join(', ')}." unless valid_formats.include?(new_format.to_sym)
46
+ @@format = new_format
47
+ Wistia.refresh_config_for_wistia_api_objects!
48
+ @@format
49
+ end
50
+ def self.format; @@format; end
23
51
 
52
+ def self.wistia_api_objects
53
+ ObjectSpace.each_object(Class).select{|klass| klass < Wistia::Base} << Wistia::Base
54
+ end
55
+ def self.refresh_config_for_wistia_api_objects!
56
+ self.wistia_api_objects.each {|d| d.refresh_config!}
57
+ end
24
58
  end
25
59
 
60
+ require 'wistia/base' # We want wistia/config to load before wistia/base, but we also want
61
+ # to ensure wistia/base is loaded so that #wistia_api_objects and
62
+ # refresh_config_for_wistia_api_objects! works.
@@ -0,0 +1,6 @@
1
+ module Wistia
2
+ API_BASE_URL = 'https://api.wistia.com/v1/'
3
+
4
+ @@password = nil
5
+ @@format = :json
6
+ end
data/lib/wistia/media.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  module Wistia
2
2
  class Media < Wistia::Base
3
-
4
3
  self.collection_name = 'medias'
5
4
 
6
5
  def still(width = 640, options = {})
@@ -12,9 +11,8 @@ module Wistia
12
11
  return url
13
12
  end
14
13
  end
15
- return nil
16
- end
17
-
18
- end # Media
19
- end # Wistia
20
14
 
15
+ nil
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,4 @@
1
1
  module Wistia
2
2
  class Project < Wistia::Base
3
-
4
3
  end
5
- end
4
+ end
@@ -1,18 +1,11 @@
1
1
  module Wistia
2
2
  module Projects
3
3
  class Sharing < Wistia::Base
4
- def self.refresh_config!
5
- super
6
- self.site = "#{Wistia::Config.config.api.url}projects/:project_id/"
7
- end
8
-
9
- refresh_config!
10
-
11
- def to_json(options = {})
12
- return self.attributes.to_json(options)
13
- end
4
+ self.site = "#{Wistia::API_BASE_URL}projects/:project_id/"
14
5
 
6
+ def to_json(options = {})
7
+ self.attributes.to_json(options)
8
+ end
15
9
  end
16
10
  end
17
11
  end
18
-
@@ -0,0 +1,22 @@
1
+ module Wistia
2
+ module Stats
3
+ class Base < Wistia::Base
4
+ self.site = "#{Wistia::API_BASE_URL}stats/"
5
+ end
6
+
7
+ class Account < Wistia::Stats::Base
8
+ # to make it easier to find singleton
9
+ def self.find_singleton
10
+ find :one, :from => '/v1/stats/account.json'
11
+ end
12
+ end
13
+ class Event < Wistia::Stats::Base
14
+ end
15
+ class Media < Wistia::Stats::Base
16
+ end
17
+ class Project < Wistia::Stats::Base
18
+ end
19
+ class Visitor < Wistia::Stats::Base
20
+ end
21
+ end
22
+ end
data/lib/wistia.rb CHANGED
@@ -1,56 +1,8 @@
1
- require 'config'
2
1
  require 'active_resource'
2
+ require 'wistia/initialization'
3
+ require 'wistia/config'
3
4
  require 'wistia/base'
4
5
  require 'wistia/media'
5
6
  require 'wistia/project'
6
7
  require 'wistia/projects/sharing'
7
- require 'wistia/stats/base'
8
- require 'wistia/stats/event'
9
- require 'wistia/stats/visitor'
10
- require 'wistia/stats/media'
11
- require 'wistia/stats/project'
12
- require 'wistia/stats/account'
13
-
14
- module Wistia
15
-
16
- # Specifies a new configuration to use for the API.
17
- # Accepts either a Hash or a String pointing to a YAML configuration file.
18
- #
19
- # Example using a Hash:
20
- # Wistia.use_config!(:wistia => { :api => { :key => 'your-api-key', :format => 'json-or-xml' } })
21
- def self.use_config!(config)
22
- if config.is_a?(String) && File.exists?(config) && File.extname(config) == '.yml'
23
- configatron.configure_from_yaml(config)
24
- elsif config.is_a?(Hash)
25
- configatron.configure_from_hash(config)
26
- else
27
- raise ArgumentError, 'Invalid config'
28
- end
29
-
30
- refresh_config!
31
- end
32
-
33
- # Set your API password using this method.
34
- # For instructions to find your API password, go here: http://wistia.com/doc/api-enable
35
- def self.password=(pw)
36
- use_config!(:wistia => { :api => { :key => pw } })
37
- end
38
-
39
- # Set the format that the API uses to either 'json' or 'xml'.
40
- # Accepts either a String or a Symbol.
41
- def self.format=(fmt)
42
- valid_formats = [ :json, :xml ]
43
- raise ArgumentError, "Invalid format. Supported formats: #{valid_formats.join(', ')}." unless valid_formats.include?(fmt.to_sym)
44
- use_config!(:wistia => { :api => { :format => fmt.to_sym } })
45
- end
46
-
47
- # Force each ActiveResource descendant to re-read its configuration from the configatron.
48
- def self.refresh_config!
49
- Wistia::Media.refresh_config!
50
- Wistia::Project.refresh_config!
51
- Wistia::Projects::Sharing.refresh_config!
52
- Wistia::Stats::Base.refresh_config!
53
- end
54
-
55
- end
56
-
8
+ require 'wistia/stats'
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,20 @@
1
1
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
  require 'rspec'
4
+ require 'fakeweb'
4
5
  require 'wistia'
5
6
 
6
7
  # Requires supporting files with custom matchers and macros, etc,
7
8
  # in ./support/ and its subdirectories.
8
9
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
10
 
10
- RSpec.configure do |config|
11
-
11
+ RSpec.configuration.before :each do
12
+ # Disallow real web connections; run each time in case a test overrides it.
13
+ FakeWeb.allow_net_connect = false
14
+
15
+ # Simulate a clean Wistia class for each spec
16
+ [:@@password, :@@format].each do |class_var|
17
+ Wistia.remove_class_variable(class_var) if Wistia.class_variable_defined?(class_var)
18
+ Wistia.class_variable_set class_var, nil
19
+ end
12
20
  end
@@ -1,6 +1,4 @@
1
1
  wistia:
2
2
  api:
3
3
  key: 'test'
4
- user: 'api'
5
4
  format: 'json'
6
- url: 'http://api.wistia.local:3000/v1/'
@@ -1,28 +1,30 @@
1
- require 'spec_helper'
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
- module Wistia
4
- describe Base do
5
- describe 'refresh_config!' do
6
- it 'sets the "site" public class attribute' do
7
- Wistia::Base.should_receive(:site=)
8
- Wistia::Base.refresh_config!
9
- end
10
-
11
- it 'sets the "user" public class attribute' do
12
- Wistia::Base.should_receive(:user=)
13
- Wistia::Base.refresh_config!
14
- end
15
-
16
- it 'sets the "password" public class attribute' do
17
- Wistia::Base.should_receive(:password=)
18
- Wistia::Base.refresh_config!
19
- end
20
-
21
- it 'sets the "format" public class attribute' do
22
- Wistia::Base.should_receive(:format=)
23
- Wistia::Base.refresh_config!
24
- end
3
+ describe Wistia::Base do
4
+ describe 'authentication' do
5
+ it 'sets user to "api"' do
6
+ Wistia::Base.user.should == 'api'
7
+ end
8
+ it 'sets password based on config' do
9
+ Wistia.password = 'foo'
10
+ Wistia::Base.password.should == 'foo'
11
+ end
12
+ end
13
+ describe 'self#refresh_config!' do
14
+ it 'updates the configuration for the class' do
15
+ Wistia.password = 'bar'
16
+ Wistia::Base.password = 'foo'
17
+ Wistia::Base.password.should == 'foo'
18
+ Wistia::Base.refresh_config!
19
+ Wistia::Base.password.should == 'bar'
20
+ end
21
+ end
22
+ describe '#to_json' do
23
+ it 'renders attributes in json format' do
24
+ b = Wistia::Base.new
25
+ b.key1 = 'val1'
26
+ b.key2 = 'val2'
27
+ JSON.parse(b.to_json).should == {'key1' => 'val1', 'key2' => 'val2'}
25
28
  end
26
29
  end
27
30
  end
28
-
@@ -0,0 +1,74 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Wistia do
4
+ describe 'self#wistia_api_objects' do
5
+ it 'returns array of classes that inherit from Wistia::Base' do
6
+ expected_descendants = [
7
+ Wistia::Base,
8
+ Wistia::Media,
9
+ Wistia::Project,
10
+ Wistia::Projects::Sharing,
11
+ Wistia::Stats::Base,
12
+ Wistia::Stats::Account,
13
+ Wistia::Stats::Media,
14
+ Wistia::Stats::Event,
15
+ Wistia::Stats::Project,
16
+ Wistia::Stats::Visitor,
17
+ ]
18
+
19
+ expected_descendants.each {|ed| Wistia.wistia_api_objects.should include(ed)}
20
+ Wistia.wistia_api_objects.count.should == expected_descendants.count
21
+ end
22
+ end
23
+
24
+ describe 'use_config!' do
25
+ context 'given a hash argument' do
26
+ it 'sets the password from the hash' do
27
+ Wistia.password.should be_nil
28
+ Wistia.use_config!( :wistia => { :api => { :password => 'test' } } )
29
+ Wistia.password.should == 'test'
30
+ end
31
+ it 'sets the password from the hash when supplied as \'key\'' do
32
+ Wistia.password.should be_nil
33
+ Wistia.use_config!( :wistia => { :api => { :key => 'test' } } )
34
+ Wistia.password.should == 'test'
35
+ end
36
+ it 'sets the format in symbolic form from the hash' do
37
+ Wistia.format.should be_nil
38
+ Wistia.use_config!( :wistia => { :api => { :format => 'xml' } } )
39
+ Wistia::Base.format.should == ActiveResource::Formats::XmlFormat
40
+ Wistia.format.should == :xml
41
+ Wistia.use_config!( :wistia => { :api => { :format => 'json' } } )
42
+ Wistia::Base.format.should == ActiveResource::Formats::JsonFormat
43
+ Wistia.format.should == :json
44
+ end
45
+ it 'leaves format alone when setting only password' do
46
+ Wistia.format = :xml
47
+ Wistia.use_config!( :wistia => { :api => { :password => 'foo' } } )
48
+ Wistia.format.should == :xml
49
+ end
50
+ it 'leaves password alone when setting only format' do
51
+ Wistia.password = 'foo'
52
+ Wistia.use_config!( :wistia => { :api => { :format => 'xml' } } )
53
+ Wistia.password.should == 'foo'
54
+ end
55
+ end
56
+
57
+ context 'given a path to a yaml file' do
58
+ it 'uses the yaml file for configuration' do
59
+ path_to_yaml = File.dirname(__FILE__) + '/../support/config.test.yml'
60
+ Wistia.use_config!(path_to_yaml)
61
+ Wistia.password.should == 'test'
62
+ Wistia.format.should == :json
63
+ end
64
+ end
65
+
66
+ context 'given an invalid config' do
67
+ it 'raises an ArgumentError' do
68
+ lambda {
69
+ Wistia.use_config!(nil)
70
+ }.should raise_error(ArgumentError, 'Invalid config')
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Wistia::Media do
4
+ it 'finds the media' do
5
+ FakeWeb.register_uri :get, 'https://api:foo@api.wistia.com/v1/medias/7.json', body: {name: 'object name'}.to_json
6
+ Wistia.password = 'foo'
7
+ Wistia.format = :json
8
+ Wistia::Media.find(7).name.should == 'object name'
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Wistia::Project do
4
+ it 'finds the project' do
5
+ FakeWeb.register_uri :get, 'https://api:foo@api.wistia.com/v1/projects/7.json', body: {name: 'object name'}.to_json
6
+ Wistia.password = 'foo'
7
+ Wistia.format = :json
8
+ Wistia::Project.find(7).name.should == 'object name'
9
+ end
10
+ end