clarify 1.1.1 → 2.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -16
  3. data/.rspec +2 -0
  4. data/.simplecov +3 -0
  5. data/.travis.yml +7 -0
  6. data/CHANGELOG.md +4 -0
  7. data/Dockerfile +11 -0
  8. data/Gemfile +2 -2
  9. data/LICENSE +1 -1
  10. data/README.md +202 -47
  11. data/Rakefile +62 -4
  12. data/clarify.gemspec +10 -7
  13. data/cucumber.yml +1 -0
  14. data/features/create-bundles.feature +10 -0
  15. data/features/delete-bundle.feature +7 -0
  16. data/features/identity-steps.feature +6 -0
  17. data/features/list-bundles.feature +13 -0
  18. data/features/search-bundles.feature +10 -0
  19. data/features/step_definitions/curied_url_steps.rb +6 -0
  20. data/features/step_definitions/error_steps.rb +4 -0
  21. data/features/step_definitions/http_verification_step.rb +4 -0
  22. data/features/step_definitions/identity_steps.rb +12 -0
  23. data/features/step_definitions/list_steps.rb +76 -0
  24. data/features/support/env.rb +36 -0
  25. data/features/support/lib/curies.rb +19 -0
  26. data/features/support/lib/customer.rb +41 -0
  27. data/features/support/lib/exceptions.rb +27 -0
  28. data/features/support/lib/names.rb +16 -0
  29. data/lib/clarify.rb +16 -14
  30. data/lib/clarify/bundle_repository.rb +26 -0
  31. data/lib/clarify/client.rb +51 -0
  32. data/lib/clarify/collection_iterator.rb +27 -0
  33. data/lib/clarify/configuration.rb +29 -7
  34. data/lib/clarify/errors.rb +22 -0
  35. data/lib/clarify/response.rb +29 -0
  36. data/lib/clarify/response_factory.rb +34 -0
  37. data/lib/clarify/responses/bundle.rb +11 -0
  38. data/lib/clarify/responses/collection.rb +31 -0
  39. data/lib/clarify/responses/no_body.rb +13 -0
  40. data/lib/clarify/responses/search_collection.rb +18 -0
  41. data/lib/clarify/responses/tracks.rb +15 -0
  42. data/lib/clarify/rest_client.rb +129 -0
  43. data/lib/clarify/version.rb +3 -1
  44. data/spec/clarify/bundle_repository_spec.rb +37 -0
  45. data/spec/clarify/client_spec.rb +93 -0
  46. data/spec/clarify/collection_iterator_spec.rb +86 -0
  47. data/spec/clarify/configuration_spec.rb +77 -0
  48. data/spec/clarify/errors_spec.rb +15 -0
  49. data/spec/clarify/response_factory_spec.rb +51 -0
  50. data/spec/clarify/response_spec.rb +69 -0
  51. data/spec/clarify/responses/bundle_spec.rb +8 -0
  52. data/spec/clarify/responses/collection_spec.rb +58 -0
  53. data/spec/clarify/responses/search_collection_spec.rb +40 -0
  54. data/spec/clarify/responses/tracks_spec.rb +18 -0
  55. data/spec/clarify/rest_client_spec.rb +222 -0
  56. data/spec/spec_helper.rb +4 -9
  57. data/src_readme/README_no_output.md +186 -0
  58. data/src_readme/examples/bundle_create.rb +11 -0
  59. data/src_readme/examples/bundle_fetch.rb +9 -0
  60. data/src_readme/examples/bundles_list_fetch.rb +11 -0
  61. data/src_readme/examples/bundles_paged_over.rb +8 -0
  62. data/src_readme/examples/bundles_search.rb +20 -0
  63. data/src_readme/examples/list_bundles.rb +6 -0
  64. data/src_readme/examples/searches_paged_over.rb +10 -0
  65. data/src_readme/examples/setup.rb +5 -0
  66. data/src_readme/make.rb +56 -0
  67. data/src_readme/readme.md.erb +55 -0
  68. metadata +127 -62
  69. data/LICENSE.txt +0 -24
  70. data/examples/create.rb +0 -14
  71. data/examples/delete.rb +0 -12
  72. data/examples/list.rb +0 -14
  73. data/examples/search.rb +0 -26
  74. data/examples/test.rb +0 -15
  75. data/lib/clarify/bundle.rb +0 -40
  76. data/lib/clarify/metadata.rb +0 -26
  77. data/lib/clarify/request.rb +0 -37
  78. data/lib/clarify/search.rb +0 -10
  79. data/lib/clarify/track.rb +0 -40
  80. data/spec/lib/clarify/bundle_spec.rb +0 -43
  81. data/spec/lib/clarify/configuration_spec.rb +0 -19
  82. data/spec/lib/clarify/metadata_spec.rb +0 -36
  83. data/spec/lib/clarify/search_spec.rb +0 -22
  84. data/spec/lib/clarify/track_spec.rb +0 -81
@@ -6,8 +6,8 @@ require 'clarify/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'clarify'
8
8
  spec.version = Clarify::VERSION
9
- spec.authors = ['rubygeek']
10
- spec.email = ['nola@rubygeek.com']
9
+ spec.authors = ['Clarify Inc.']
10
+ spec.email = ['support@clarify.io']
11
11
  spec.summary = 'Search audio and video in a few lines of code'
12
12
  spec.description = 'Use the Clarify API to make your audio and video files searchable in just a few lines of code.'
13
13
  spec.homepage = 'http://www.clarify.io'
@@ -18,9 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'httparty', '~> 0.13', '>= 0.13.1'
22
- spec.add_development_dependency 'bundler', '~> 1.5'
23
- spec.add_development_dependency 'rake', '~> 10.0', '>= 10.0.0'
24
- spec.add_development_dependency 'rspec', '~> 3.0', '>= 3.0.0'
25
- spec.add_development_dependency 'debugger', '~> 1.6', '>= 1.6.8'
21
+ spec.add_development_dependency 'bundler', '~> 1.5'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'cucumber', '~> 1.3.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+ spec.add_development_dependency 'rspec-expectations', '~> 3.2.0'
26
+ spec.add_development_dependency 'rubocop', '~> 0.29.0'
27
+ spec.add_development_dependency 'simplecov', '~> 0.9.0'
26
28
  end
29
+
@@ -0,0 +1 @@
1
+ default: --color
@@ -0,0 +1,10 @@
1
+ Feature: As a user of the API, I am able to create a bundle.
2
+ Scenario: A user has added a new media file for processing.
3
+ Given I am using the environment's API key
4
+ And I know the following urls referenced as:
5
+ | name | URL |
6
+ | media:dorothy | http://media.clarify.io/audio/books/dorothyandthewizardinoz_01_baum_64kb.mp3 |
7
+ When I create a bundle named "Wizard of Oz" with the media url "[media:dorothy]"
8
+ When I request a list of bundles
9
+ Then I should get the HTTP status code 200
10
+ And my results should incude a bundle named "Wizard of Oz"
@@ -0,0 +1,7 @@
1
+ Feature: As a user of the API, I am able to delete a bundle.
2
+ Scenario: A user has added a new media file for processing.
3
+ Given I am using the environment's API key
4
+ And I have a bundle named "K.C."
5
+ When I delete my bundle
6
+ Then the server should not list my bundle
7
+
@@ -0,0 +1,6 @@
1
+ Feature: As an unauthenticated user, I get an exception that I can handle.
2
+ Scenario: I have not entered an API key, but attempt to connect anyway.
3
+ Given I am not using an API key
4
+ When I request a list of bundles without authentication
5
+ Then the response should be rejected with a 401 Unauthorized status code
6
+
@@ -0,0 +1,13 @@
1
+ Feature: As a user of the API, I am able to list my submitted bundles.
2
+ Scenario: I am building an index page to my bundle collection.
3
+ Given I am using the documentation API key
4
+ And I know the following urls referenced as:
5
+ | name | URL |
6
+ | media:future-of-women-flying | http://archive.org/download/Greatest_Speeches_of_the_20th_Century/TheFutureofWomeninFlying_64kb.mp3 |
7
+ | media:watergate-tapes | http://ia700200.us.archive.org/18/items/Greatest_Speeches_of_the_20th_Century/OnReleasingtheWatergateTapes_64kb.mp3 |
8
+ | media:resignation-address | http://ia600200.us.archive.org/18/items/Greatest_Speeches_of_the_20th_Century/ResignationAddress-1974_64kb.mp3 |
9
+ When I request a list of bundles
10
+ Then I should get the HTTP status code 200
11
+ And my results should include a track with the URL "[media:future-of-women-flying]"
12
+ And my results should include a track with the URL "[media:watergate-tapes]"
13
+ And my results should include a track with the URL "[media:resignation-address]"
@@ -0,0 +1,10 @@
1
+
2
+ Feature: As a user of the API, I am able to search for bundles based on the content.
3
+ Scenario: I am building a search functionality into my application.
4
+ Given I am using the documentation API key
5
+ And I know the following urls referenced as:
6
+ | name | URL |
7
+ | media:future-of-women-flying | http://archive.org/download/Greatest_Speeches_of_the_20th_Century/TheFutureofWomeninFlying_64kb.mp3 |
8
+ When I search my bundles for the text "women"
9
+ Then I should get the HTTP status code 200
10
+ And my results should include a track with the URL "[media:future-of-women-flying]"
@@ -0,0 +1,6 @@
1
+ Given(/^I know the following urls referenced as:$/) do |table|
2
+ table.map_headers! { |header| header.downcase.to_sym }
3
+ table.hashes.each do |row|
4
+ curies[row[:name]] = row[:url]
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+
2
+ Then(/^the response should be rejected with a 401 Unauthorized status code$/) do
3
+ expect(exceptions.caught.class.to_s).to eq('Clarify::UnauthenticatedError')
4
+ end
@@ -0,0 +1,4 @@
1
+
2
+ Then(/^I should get the HTTP status code (\d+)$/) do |code|
3
+ expect(@result.http_status_code).to eq code.to_i
4
+ end
@@ -0,0 +1,12 @@
1
+
2
+ Given(/^I am using the documentation API key$/) do
3
+ customer.log_in_as_docs
4
+ end
5
+
6
+ Given(/^I am not using an API key$/) do
7
+ customer.clear_api_key
8
+ end
9
+
10
+ Given(/^I am using the environment's API key$/) do
11
+ customer.log_in_via_environment
12
+ end
@@ -0,0 +1,76 @@
1
+
2
+ When(/^I request a list of bundles without authentication$/) do
3
+ begin
4
+ @result = customer.bundle_repository.fetch
5
+ rescue Clarify::StandardError => err
6
+ exceptions.caught = err
7
+ end
8
+ end
9
+
10
+ When(/^I request a list of bundles$/) do
11
+ @result = customer.bundle_repository.fetch
12
+ end
13
+
14
+ When(/^I search my bundles for the text "(.*?)"$/) do |query_string|
15
+ @result = customer.bundle_repository.search(query_string)
16
+ end
17
+
18
+ Then(/^my results should include a track with the URL "(.*?)"$/) do |url|
19
+ if @result.is_a? Clarify::Responses::SearchCollection
20
+ urls = @result.map { |_, bundle_url| bundle_url }
21
+ else
22
+ urls = @result.to_a
23
+ end
24
+
25
+ bundles = urls.map { |bundle_url| customer.restclient.get(bundle_url) }
26
+
27
+ tracks = bundles.map do |bundle|
28
+ customer.restclient.get(bundle.relation('clarify:tracks'))
29
+ end
30
+ media_urls = tracks.map do |tracks_resource|
31
+ tracks_resource.map { |track| track['media_url'] }
32
+ end.flatten
33
+
34
+ expect(media_urls).to include(curies.resolve(url))
35
+ end
36
+
37
+ # rubocop:disable Metrics/LineLength
38
+ When(/^I create a bundle named "(.*?)" with the media url "(.*?)"$/) do |name, url|
39
+ # rubocop:enable Metrics/LineLength
40
+ bundle = {
41
+ name: names.translate(name),
42
+ media_url: curies.resolve(url)
43
+ }
44
+ customer.bundle_repository.create!(bundle)
45
+ end
46
+
47
+ Then(/^my results should incude a bundle named "(.*?)"$/) do |name|
48
+ all_results = Clarify::CollectionIterator.new(customer.restclient, @result)
49
+ bundles = all_results.map do |item|
50
+ customer.restclient.get(item)
51
+ end
52
+ bundle_names = bundles.map(&:name)
53
+
54
+ expect(bundle_names).to include(names.translate(name))
55
+ end
56
+
57
+ Given(/^I have a bundle named "(.*?)"$/) do |name|
58
+ bundle = {
59
+ name: names.translate(name)
60
+ }
61
+ @my_bundle = customer.bundle_repository.create!(bundle)
62
+ end
63
+
64
+ When(/^I delete my bundle$/) do
65
+ customer.bundle_repository.delete!(@my_bundle)
66
+ end
67
+
68
+ Then(/^the server should not list my bundle$/) do
69
+ result = customer.bundle_repository.fetch
70
+ all_results = Clarify::CollectionIterator.new(customer.restclient, result)
71
+ bundle_urls = all_results.map do |item|
72
+ item['href']
73
+ end
74
+
75
+ expect(bundle_urls).to_not include(@my_bundle.relation('self'))
76
+ end
@@ -0,0 +1,36 @@
1
+
2
+ $LOAD_PATH << File.dirname(__FILE__) + '/lib/'
3
+ $LOAD_PATH << File.dirname(__FILE__) + '/../../lib/'
4
+
5
+ require 'simplecov'
6
+ require 'clarify'
7
+ require 'customer'
8
+ require 'exceptions'
9
+ require 'curies'
10
+
11
+ # EnvHelpers is
12
+ class EnvHelpers
13
+ def customer
14
+ @customer ||= ClarifyTests::Customer.new
15
+ end
16
+
17
+ def exceptions
18
+ @exceptions ||= ClarifyTests::Exceptions.new
19
+ end
20
+
21
+ def curies
22
+ @curies ||= ClarifyTests::Curies.new
23
+ end
24
+
25
+ def names
26
+ @names ||= ClarifyTests::Names.new
27
+ end
28
+ end
29
+
30
+ World do
31
+ EnvHelpers.new
32
+ end
33
+
34
+ After do
35
+ exceptions.raise_pending!
36
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module ClarifyTests
3
+ # The Curies class helps improve readability in URL-based tests by
4
+ # introducing a replacable reference.
5
+ class Curies
6
+ def initialize
7
+ @curies = {}
8
+ end
9
+
10
+ def []=(name, value)
11
+ @curies["[#{name}]"] = value
12
+ end
13
+
14
+ def resolve(url)
15
+ return url unless url[0] == '['
16
+ @curies.fetch(url)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+
2
+ module ClarifyTests
3
+ # The Customer represents a user of the API. The Customer might do things like
4
+ # log in with particular keys, or create RestClients, Configurations, etc.
5
+ class Customer
6
+ attr_reader :api_key
7
+
8
+ def initialize
9
+ end
10
+
11
+ def log_in_as_docs
12
+ self.api_key = 'docs-api-key'
13
+ end
14
+
15
+ def log_in_via_environment
16
+ self.api_key = ENV.fetch('CLARIFY_API_KEY')
17
+ end
18
+
19
+ def clear_api_key
20
+ self.api_key = ''
21
+ end
22
+
23
+ def api_key=(val)
24
+ @api_key = val
25
+
26
+ @client = nil
27
+ end
28
+
29
+ def bundle_repository
30
+ client.bundle_repository
31
+ end
32
+
33
+ def restclient
34
+ client.restclient
35
+ end
36
+
37
+ def client
38
+ @client ||= Clarify::Client.new(api_key: api_key)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+
2
+ module ClarifyTests
3
+ # Used for catching and re-throwing exceptions used in tests. Guarantees that
4
+ # an exception won't be swalloawed when integrated with After commands.
5
+ class Exceptions
6
+ attr_writer :caught
7
+
8
+ def initialize
9
+ @caught = nil
10
+ end
11
+
12
+ def caught
13
+ exception = @caught
14
+ @caught = nil
15
+
16
+ exception
17
+ end
18
+
19
+ def raise_pending!
20
+ fail @caught if exception?
21
+ end
22
+
23
+ def exception?
24
+ !@caught.nil?
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+
2
+ require 'securerandom'
3
+
4
+ module ClarifyTests
5
+ # Take names you use in a test and make them unique, guaranteeing two tests
6
+ # can't trample on the same account.
7
+ class Names
8
+ def translate(name)
9
+ "#{uuid}{#{name}}"
10
+ end
11
+
12
+ def uuid
13
+ @uuid ||= SecureRandom.uuid
14
+ end
15
+ end
16
+ end
@@ -1,17 +1,19 @@
1
- require "clarify/version"
2
- require "clarify/configuration"
3
- require "clarify/bundle"
4
- require "clarify/request"
5
- require "clarify/metadata"
6
- require "clarify/track"
7
- require "clarify/search"
8
1
 
2
+ # The Clarify API SDK
9
3
  module Clarify
10
- class << self
11
- attr_accessor :configuration
12
- end
13
- def self.configure
14
- self.configuration ||= Configuration.new
15
- yield(configuration)
16
- end
17
4
  end
5
+
6
+ require 'clarify/bundle_repository'
7
+ require 'clarify/rest_client'
8
+ require 'clarify/configuration'
9
+ require 'clarify/errors'
10
+ require 'clarify/client'
11
+ require 'clarify/response'
12
+ require 'clarify/response_factory'
13
+ require 'clarify/responses/bundle'
14
+ require 'clarify/responses/collection'
15
+ require 'clarify/responses/search_collection'
16
+ require 'clarify/responses/no_body'
17
+ require 'clarify/collection_iterator'
18
+ require 'clarify/responses/tracks'
19
+ require 'clarify/version'
@@ -0,0 +1,26 @@
1
+
2
+ module Clarify
3
+ # A simple entrypoint to the API. Exposes access to search and CRUD
4
+ # operations on Bundles.
5
+ class BundleRepository
6
+ def initialize(restclient)
7
+ @restclient = restclient
8
+ end
9
+
10
+ def fetch
11
+ @restclient.get('/v1/bundles')
12
+ end
13
+
14
+ def search(query_string)
15
+ @restclient.get('/v1/search', query: query_string)
16
+ end
17
+
18
+ def create!(about)
19
+ @restclient.post('/v1/bundles', about)
20
+ end
21
+
22
+ def delete!(bundle)
23
+ @restclient.delete(bundle.relation!('self'))
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+
2
+ module Clarify
3
+ # The Client simplifies the configuration and bootstrapping of the restclient
4
+ # and bundle repository.
5
+ class Client
6
+ def initialize(config, opts = {})
7
+ @config = config
8
+ @klass_restclient = opts.fetch(:rest_client, Clarify::RestClient)
9
+ @klass_configuration = opts.fetch(:configuration, Clarify::Configuration)
10
+ @klass_bundle_repository = opts.fetch(:bundle_repository,
11
+ Clarify::BundleRepository)
12
+ @klass_iterator = opts.fetch(:iterator, Clarify::CollectionIterator)
13
+ end
14
+
15
+ def get(url, params = {})
16
+ restclient.get(url, params)
17
+ end
18
+
19
+ def put(url, params = {})
20
+ restclient.put(url, params)
21
+ end
22
+
23
+ def post(url, params = {})
24
+ restclient.post(url, params)
25
+ end
26
+
27
+ def delete(url, params = {})
28
+ restclient.delete(url, params)
29
+ end
30
+
31
+ def pager(collection)
32
+ @klass_iterator.new(restclient, collection)
33
+ end
34
+
35
+ def bundles
36
+ bundle_repository
37
+ end
38
+
39
+ def bundle_repository
40
+ @bundle_repository ||= @klass_bundle_repository.new(restclient)
41
+ end
42
+
43
+ def restclient
44
+ @restclient ||= @klass_restclient.new(configuration)
45
+ end
46
+
47
+ def configuration
48
+ @configuration ||= @klass_configuration.new(@config)
49
+ end
50
+ end
51
+ end