viki 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ *.DS_Store
5
+ pkg/*
6
+ *.swp
7
+ *.un~
8
+ .idea/
9
+ fixtures/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.3-p125@viki-gem --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in viki.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ A Viki wrapper gem for the Viki V3 API. This gem is currently under active development.
2
+
3
+ Full documentation for API V3 may be found at [dev.viki.com](http://dev.viki.com/api "Viki API V3 Docs")
4
+
5
+
6
+ Endpoints
7
+ ----------
8
+
9
+ Here are a full list of functions available.
10
+
11
+ ```
12
+ client.movies(params)
13
+ client.movies(id, params)
14
+ client.movie(id).subtitles(lang)
15
+ client.movie(id).hardsubs
16
+
17
+ client.series(params)
18
+ client.series(id, params)
19
+ client.series(id).episodes(params)
20
+ client.series(id).episodes(id)
21
+ client.series(id).episodes(id).subtitles(lang)
22
+ client.series(id).episodes(id).hardsubs
23
+
24
+ client.music_videos(params)
25
+ client.music_videos(id, params)
26
+ client.music_videos(id).subtitles(lang)
27
+ client.music_videos(id).hardsubs * implementation waiting on valid examples
28
+
29
+ client.newscasts(params)
30
+ client.newscasts(id, params)
31
+ client.newscasts(id).newsclips
32
+
33
+
34
+ client.newsclips
35
+ client.newsclips(id)
36
+ client.newsclips(id).subtitles(lang)
37
+ client.newsclips(id).hardsubs(lang)
38
+
39
+
40
+ client.artists(params)
41
+ client.artist(id, params)
42
+ client.artists(id).music_videos(params)
43
+
44
+ client.featured(params)
45
+
46
+ client.coming_soon
47
+ client.coming_soon.movies
48
+ client.coming_soon.series
49
+ ```
50
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,41 @@
1
+ require 'multi_json'
2
+ require 'viki/utilities'
3
+
4
+ module Viki
5
+ class APIObject
6
+ include Viki::Utilities
7
+
8
+ def initialize(json, access_token)
9
+ hash = MultiJson.load(json)
10
+ @content = hash["response"] ? hash["response"] : hash
11
+ @count = hash["count"] ? hash["count"].to_i : 1
12
+
13
+ pagination = hash["pagination"]
14
+
15
+ if pagination
16
+ @next_url = pagination["next"] if not pagination["next"].empty?
17
+ @previous_url = pagination["previous"] if not pagination["previous"].empty?
18
+ end
19
+
20
+ @access_token = access_token
21
+ end
22
+
23
+ attr_reader :content, :count
24
+
25
+ def next
26
+ @next_url ? direct_request(@next_url) : nil
27
+ end
28
+
29
+ def prev
30
+ @previous_url ? direct_request(@next_url) : nil
31
+ end
32
+
33
+ private
34
+
35
+ def direct_request(url)
36
+ response = HTTParty.get(url, :query => { access_token: @access_token })
37
+ capture response
38
+ APIObject.new(response.body, @access_token)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,51 @@
1
+ require 'httparty'
2
+ require 'viki/api_object'
3
+ require 'viki/request'
4
+ require 'multi_json'
5
+
6
+ module Viki
7
+ class Client
8
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each { |f| require f }
9
+ URL_NAMESPACES = [:movies, :series, :episodes, :music_videos, :newscasts, :newsclips,
10
+ :artists, :featured, :coming_soon, :subtitles, :hardsubs]
11
+
12
+ def initialize(client_id, client_secret)
13
+ @client_id = client_id
14
+ @client_secret = client_secret
15
+ @access_token = auth_request(client_id, client_secret)
16
+ end
17
+
18
+ attr_reader :access_token
19
+
20
+ include Viki::Request
21
+
22
+ def get
23
+ request(@call_chain)
24
+ end
25
+
26
+ def reset_access_token
27
+ @access_token = auth_request(@client_id, @client_secret)
28
+ end
29
+
30
+ private
31
+ def method_missing(name, *args, &block)
32
+ @call_chain ||= []
33
+ raise NoMethodError if not URL_NAMESPACES.include? name
34
+
35
+ curr_call = { name: name }
36
+
37
+ first_arg, second_arg = args[0], args[1]
38
+
39
+ if args.length == 1
40
+ first_arg.is_a?(Hash) ? curr_call.merge!({ params: first_arg }) : curr_call.merge!({ resource: first_arg })
41
+ elsif args.length == 2
42
+ curr_call.merge!({ resource: first_arg })
43
+ curr_call.merge!({ params: second_arg })
44
+ end
45
+
46
+ @call_chain.push(curr_call)
47
+ self
48
+ end
49
+
50
+ end
51
+ end
data/lib/viki/error.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Viki
2
+ class Error < StandardError
3
+ attr_accessor :status, :message
4
+
5
+ def initialize(status, msg=nil)
6
+ self.status = status
7
+ self.message = msg
8
+ super(msg||"#{self.status}: #{self.message}")
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ require 'uri'
2
+ require 'httparty'
3
+ require 'multi_json'
4
+ require 'viki/utilities'
5
+
6
+ module Viki
7
+ module Request
8
+ include Viki::Utilities
9
+
10
+ private
11
+ HOST = "http://www.viki.com/api/v3/"
12
+
13
+ def auth_request(client_id, client_secret)
14
+ params = {
15
+ :grant_type => 'client_credentials',
16
+ :client_id => client_id,
17
+ :client_secret => client_secret
18
+ }
19
+ response = HTTParty.post('http://viki.com/oauth/token', query: params)
20
+ json = MultiJson.load(response.body)
21
+ raise Viki::Error.new(response.header.code, json["error_description"]) if response.header.code != "200"
22
+ json["access_token"]
23
+ end
24
+
25
+ def request(call_chain)
26
+ path, params = build_url(call_chain)
27
+ request_url = HOST + path.chop + ".json"
28
+
29
+ response = HTTParty.get(request_url, :query => params)
30
+
31
+ if response.header.code == "401"
32
+ self.reset_access_token
33
+ params.merge!({ access_token: self.access_token })
34
+ response = HTTParty.get(request_url, :query => params)
35
+ end
36
+
37
+ capture response
38
+
39
+ APIObject.new(response.body, self.access_token)
40
+ end
41
+
42
+ private
43
+
44
+ def build_url(call_chain)
45
+ path = ""
46
+ params = { access_token: self.access_token }
47
+
48
+ call_chain.each do |c|
49
+ path += "#{c[:name]}/"
50
+ path += "#{c[:resource]}/" if c.has_key?(:resource)
51
+ params.merge!(c[:params]) if c.has_key?(:params)
52
+ end
53
+
54
+ return path, params
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,13 @@
1
+ module Viki
2
+ module Utilities
3
+ private
4
+
5
+ def capture(response)
6
+ if response.header.code != "200"
7
+ response_hash = MultiJson.load(response.body)
8
+ raise Viki::Error.new(response.header.code, response_hash["message"]) if response.header.code != "200"
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Viki
2
+ VERSION = "0.0.1"
3
+ end
data/lib/viki.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'viki/version'
2
+ require 'viki/client'
3
+ require 'viki/error'
4
+ require 'viki/utilities'
5
+
6
+ # Adapted from the Grackle Twitter gem.
7
+ module Viki
8
+
9
+ # Alias for viki::Client.new
10
+ #
11
+ # @return {viki::Client})
12
+ def self.new(client_id, client_secret)
13
+ Viki::Client.new(client_id, client_secret)
14
+ end
15
+
16
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Viki::Client do
4
+
5
+ describe "#get" do
6
+ before { Viki::Client.any_instance.stub(:auth_request) }
7
+ subject { Viki::Client.new('chickenrice', 'soronerychickenrice') }
8
+
9
+ it "should perform a request to the right url given a call chain" do
10
+ subject.movies(1234).subtitles('en')
11
+ subject.should_receive(:request).with([{ :name => :movies, :resource => 1234 },
12
+ { :name => :subtitles, :resource => "en" }])
13
+ subject.get
14
+ end
15
+
16
+ it "should perform a request with the right params given a call chain" do
17
+ subject.movies(1234, {genre: 2})
18
+ subject.should_receive(:request).with([{ :name => :movies, :resource => 1234, :params => {genre: 2}}])
19
+ subject.get
20
+ end
21
+
22
+ it "should raise NoMethodError error if part of the call chain is not part of the URL_NAMESPACES list" do
23
+ expect { subject.methodwrong.subtitles('en') }.to raise_error(NoMethodError)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Viki::Error do
4
+ before { @error = Viki::Error.new(404, "Resource 'blah' not found.")}
5
+
6
+ subject { @error }
7
+
8
+ it { should respond_to(:status) }
9
+ it { should respond_to(:message) }
10
+
11
+ it { subject.to_s.should == "Resource 'blah' not found."}
12
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for "API with parameter filters" do
4
+ context "when filtering with genre" do
5
+ let(:query_options) { { :genre => 2 } }
6
+ it "should return a genre-filtered list of Viki::Movie objects when given genre params" do
7
+ VCR.use_cassette "#{type}/genre_filter" do
8
+ results.each do |m|
9
+ m.genres.each do |g|
10
+ g["id"].should == 2
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ context "when filtering with subtitle_language" do
18
+ let(:query_options) { { :subtitle_language => 'fr' } }
19
+ it "should return movies with requested subtitle > 90% completion, when given a subtitle_language parameter" do
20
+ VCR.use_cassette "#{type}/subtitle_language_filter" do
21
+ results.each do |m|
22
+ m.subtitles["fr"].should > 90
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ context "when filtering with watchable_in" do
29
+ let(:query_options) { { :watchable_in => 'sg' } }
30
+ it "should return movies watchable_in selected country when given a watchable_in parameter" do
31
+ VCR.use_cassette "#{type}/watchable_in_filter" do
32
+ results.should_not be_empty
33
+ end
34
+ end
35
+ end
36
+
37
+ context "when filtering with origin_country" do
38
+ let(:query_options) { { :origin_country => 'kr' } }
39
+ it "should return movies from a specific country when given a origin_country parameter" do
40
+ VCR.use_cassette "#{type}/origin_country_filter" do
41
+ results.each do |m|
42
+ m.origin_country.should == 'Korea'
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+
49
+ context "when filtering with platform" do
50
+ let(:query_options) { { :platform => 'mobile' } }
51
+ it "should return movies available in selected platform when given watchable_in and platform parameters" do
52
+ query_options.merge!({ :watchable_in => 'sg' })
53
+ VCR.use_cassette "#{type}/platform_filter" do
54
+ results.should_not be_empty
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'filter_shared_examples_spec'
5
+
6
+ describe "Viki" do
7
+ let(:client_id) { '4bd5edd4ba26ac2f3ad9d204dc6359ea8a3ebe2c95b6bc1a9195c0ce5c57d392' }
8
+ let(:client_secret) { 'f3b796a1eb6e06458a502a89171a494a9160775ed4f4e9e0008c638f7e7e7d38' }
9
+
10
+ describe "Auth" do
11
+ it "should retrieve an access token when the Viki object is configured and initialized" do
12
+ VCR.use_cassette "auth" do
13
+ client = Viki.new(client_id, client_secret)
14
+ client.access_token.should == '1b080a6b3a94ed4503e04e252500ca87f6e7dc55061cec92b627ef1fbec44c70'
15
+ end
16
+ end
17
+
18
+ it "should return an error when the client_secret or client_id is incorrect" do
19
+ VCR.use_cassette "auth_error" do
20
+ lambda { Viki.new('12345', '54321') }.should raise_error(Viki::Error,
21
+ 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.')
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "API Interactions" do
27
+ let(:query_options) { { } }
28
+ let(:client) do
29
+ VCR.use_cassette "auth" do
30
+ Viki.new(client_id, client_secret)
31
+ end
32
+ end
33
+
34
+ describe "Movies" do
35
+ let(:results) { client.movies(query_options).get }
36
+ let(:type) { :movie }
37
+
38
+ describe "/movies" do
39
+ it "should return a list Viki::Movie objects" do
40
+ VCR.use_cassette "movies/list" do
41
+ results.content.each do |movie|
42
+ movie.should be_instance_of(Hash)
43
+ end
44
+ end
45
+ end
46
+
47
+ it "should raise an error when platform parameter is given without watchable_in" do
48
+ VCR.use_cassette "movie/platform_filter_error" do
49
+ query_options.merge!({ :platform => 'mobile' })
50
+ lambda { results }.should raise_error(Viki::Error,
51
+ "Require watchable_in parameter when given platform parameter")
52
+ end
53
+ end
54
+
55
+ #it_behaves_like "API with parameter filters"
56
+ end
57
+
58
+ describe "/movies/:id" do
59
+ it "should return a Viki::Movie object" do
60
+ VCR.use_cassette "movie_show" do
61
+ response = client.movies(70436).get
62
+ movie = response.content
63
+
64
+ #overtesting
65
+ movie["id"].should == 70436
66
+ movie["title"].should == "Muoi: The Legend of a Portrait"
67
+ movie["description"].should_not be_empty
68
+ movie["created_at"].should_not be_empty
69
+ movie["uri"].should_not be_empty
70
+ movie["origin_country"].should_not be_empty
71
+ movie["image"].should_not be_empty
72
+ movie["formats"].should_not be_empty
73
+ movie["subtitles"].should_not be_empty
74
+ movie["genres"].should_not be_empty
75
+ end
76
+ end
77
+
78
+ it "should return a Viki::Error object when resource not found" do
79
+ VCR.use_cassette "movie_error" do
80
+ lambda { client.movies(50).get }.should raise_error(Viki::Error, "The resource couldn't be found")
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "/movies/:id/subtitles/:lang" do
86
+ it "should return a subtitle JSON string" do
87
+ VCR.use_cassette "movies/subtitles" do
88
+ response = client.movies(21713).subtitles('en').get
89
+ response.count.should == 1
90
+ subtitles = response.content
91
+ subtitles["language_code"].should == "en"
92
+ subtitles["subtitles"].should_not be_empty
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "movies/:id/hardsubs" do
98
+ it "should return a list of video qualities with links to hardsubbed videos" do
99
+ VCR.use_cassette "movies/hardsubs" do
100
+ response = client.movies(64135).hardsubs.get
101
+ response.count.should == 1
102
+ hardsubs = response.content
103
+ hardsubs["res-240p"].should_not be_empty
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "APIObject pagination" do
109
+ it "returns an APIObject for APIObject containing movies when it has a next page" do
110
+ VCR.use_cassette "APIObject/pagination" do
111
+ response = client.movies.get
112
+ result = response.next
113
+ result.count.should > 1
114
+ result.content.should_not be_empty
115
+ result.should be_instance_of(Viki::APIObject)
116
+ end
117
+ end
118
+
119
+ it "returns nil if there is movies listing has no next page" do
120
+ VCR.use_cassette "APIObject/pagination_fail" do
121
+ response = client.movies({ page: 6 }).get
122
+ result = response.next
123
+ result.should be_nil
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ describe "Renew Expired Access Token" do
130
+ it "should request a new access token when an endpoint returns 401 and client currently has an access_token" do
131
+ VCR.use_cassette "auth/expired_access_token" do
132
+ client.access_token.should_not be_empty
133
+ client.instance_variable_set(:@access_token, "rubbishaccesstoken")
134
+ response = client.movies.get
135
+ response.content.should_not be_empty
136
+ end
137
+ end
138
+ end
139
+
140
+ end
141
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rspec'
5
+ require 'viki'
6
+ require 'vcr'
7
+
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
@@ -0,0 +1,6 @@
1
+ VCR.configure do |c|
2
+ c.cassette_library_dir = 'fixtures/vcr_cassettes'
3
+ c.allow_http_connections_when_no_cassette = true
4
+ c.hook_into :webmock
5
+ end
6
+
data/viki.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "viki/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "viki"
7
+ s.version = Viki::VERSION
8
+ s.authors = ["Joost van Amersfoort", "Cedric Chin", "Tommi Lew"]
9
+ s.email = ["engineering@viki.com"]
10
+ s.homepage = "http://dev.viki.com"
11
+ s.summary = "A thin wrapper around the Viki V3 API"
12
+ s.description = "Viki-gem is an official wrapper gem for the Viki V3 API."
13
+
14
+ s.rubyforge_project = "viki"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rspec", "~> 2.10.0"
23
+ s.add_development_dependency "vcr", "~> 2.2.2"
24
+ s.add_development_dependency "webmock", "~> 1.8.7"
25
+ s.add_development_dependency "excon", "~> 0.9.6"
26
+ s.add_runtime_dependency "httparty", "~> 0.8.3"
27
+ s.add_runtime_dependency "multi_json", "~> 1.3.6"
28
+
29
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: viki
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joost van Amersfoort
9
+ - Cedric Chin
10
+ - Tommi Lew
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2012-06-26 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ requirement: &70128599563080 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 2.10.0
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: *70128599563080
27
+ - !ruby/object:Gem::Dependency
28
+ name: vcr
29
+ requirement: &70128599562600 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 2.2.2
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *70128599562600
38
+ - !ruby/object:Gem::Dependency
39
+ name: webmock
40
+ requirement: &70128599562100 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.8.7
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *70128599562100
49
+ - !ruby/object:Gem::Dependency
50
+ name: excon
51
+ requirement: &70128599561540 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 0.9.6
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *70128599561540
60
+ - !ruby/object:Gem::Dependency
61
+ name: httparty
62
+ requirement: &70128599560720 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 0.8.3
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: *70128599560720
71
+ - !ruby/object:Gem::Dependency
72
+ name: multi_json
73
+ requirement: &70128599560160 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 1.3.6
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: *70128599560160
82
+ description: Viki-gem is an official wrapper gem for the Viki V3 API.
83
+ email:
84
+ - engineering@viki.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - .gitignore
90
+ - .rspec
91
+ - .rvmrc
92
+ - Gemfile
93
+ - README.md
94
+ - Rakefile
95
+ - lib/viki.rb
96
+ - lib/viki/api_object.rb
97
+ - lib/viki/client.rb
98
+ - lib/viki/error.rb
99
+ - lib/viki/request.rb
100
+ - lib/viki/utilities.rb
101
+ - lib/viki/version.rb
102
+ - spec/client_spec.rb
103
+ - spec/error_spec.rb
104
+ - spec/filter_shared_examples_spec.rb
105
+ - spec/request_spec.rb
106
+ - spec/spec_helper.rb
107
+ - spec/support/vcr.rb
108
+ - viki.gemspec
109
+ homepage: http://dev.viki.com
110
+ licenses: []
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project: viki
129
+ rubygems_version: 1.8.11
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: A thin wrapper around the Viki V3 API
133
+ test_files:
134
+ - spec/client_spec.rb
135
+ - spec/error_spec.rb
136
+ - spec/filter_shared_examples_spec.rb
137
+ - spec/request_spec.rb
138
+ - spec/spec_helper.rb
139
+ - spec/support/vcr.rb