From a777ec6ce523b2b88d5586bce73bd6ac0dbc16db Mon Sep 17 00:00:00 2001 From: Andrew Myers Date: Fri, 23 Jul 2021 16:47:48 -0400 Subject: [PATCH] Get Sony Ci ID from GUID via UI * Updates sony_ci_api gem to use sony_ci_api_rewrite in github, branch v0.1. * Had to create a branch that was compatible with Faraday v0.17.x, b/c Hyrax dependencies would not allow Faraday v1.3. * Customizes Sony Ci ID input to include filename fetched from Sony Ci. * Customizes Sony Ci ID input partial to include button that will populate Sony Ci ID entries from Sony Ci, where the filename matches a translated form of the Asset ID. * Replaces old instances of SonyCiBasic with SonyCiApi::Client. * Adds a SonyCi::APIController to wrap very specific requests to Sony Ci API using the new gem. Endpoints include: * /sony_ci/api/find_media&query={QUERY}&fields={FIELDS} This will search the API for records matching {QUERY} and return JSON objects having properties specified by the comma-separated field list {FIELDS} * /sony_ci/api/get_filename&sony_ci_id={SONY_CI_ID} This will find the Sony Ci record and return a JSON object containing fields 'sony_ci_id' and 'name'. Closes #585. --- Gemfile | 3 +- Gemfile.lock | 335 ++++++++++-------- app/assets/javascripts/application.js | 1 - .../javascripts/sony_ci/find_media.coffee | 99 ++++++ app/controllers/media_controller.rb | 8 +- app/controllers/sony_ci/api_controller.rb | 48 +++ app/input/sony_ci_id_input.rb | 16 + app/models/admin_data.rb | 19 + .../media_download/media_download_service.rb | 5 +- .../records/edit_fields/_default.html.erb | 2 +- app/views/records/edit_fields/_md5.html.erb | 1 - .../records/edit_fields/_sonyci_id.html.erb | 17 + config/initializers/assets.rb | 2 +- config/routes.rb | 8 +- spec/controllers/media_controller_spec.rb | 9 +- .../sony_ci/api_controller_spec.rb | 81 +++++ .../sony_ci/webhooks_controller_spec.rb | 2 +- spec/features/update_admin_data_spec.rb | 16 +- .../media_download_service_spec.rb | 19 +- 19 files changed, 518 insertions(+), 173 deletions(-) create mode 100644 app/assets/javascripts/sony_ci/find_media.coffee create mode 100644 app/controllers/sony_ci/api_controller.rb create mode 100644 app/input/sony_ci_id_input.rb create mode 100644 app/views/records/edit_fields/_sonyci_id.html.erb create mode 100644 spec/controllers/sony_ci/api_controller_spec.rb diff --git a/Gemfile b/Gemfile index 72faa9873..adf7e76d5 100644 --- a/Gemfile +++ b/Gemfile @@ -89,7 +89,8 @@ gem 'bootstrap-multiselect-rails' gem 'hyrax-batch_ingest', git: 'https://github.com/samvera-labs/hyrax-batch_ingest' gem 'pbcore', '~> 0.3.0' gem 'curb' -gem 'sony_ci_api', '~> 0.2.1' +# gem 'sony_ci_api', '~> 0.2.1' +gem 'sony_ci_api', github: 'WGBH-MLA/sony_ci_api_rewrite', branch: 'v0.1' # gem 'hyrax-iiif_av', '>= 0.2.0' # gem 'hyrax-iiif_av', github: 'samvera-labs/hyrax-iiif_av', branch: 'hyrax_master' gem 'webpacker' diff --git a/Gemfile.lock b/Gemfile.lock index 53292ee6b..a459eb89b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,13 @@ +GIT + remote: https://github.com/WGBH-MLA/sony_ci_api_rewrite.git + revision: 9a668ab0649aa6bb03aa259de0cf1687e52e86fb + branch: v0.1 + specs: + sony_ci_api (0.1.0) + activesupport + faraday (~> 0.12) + faraday_middleware + GIT remote: https://github.com/samvera-labs/hyrax-batch_ingest revision: dc9d38039728eab581ab7b1cb55cf9ff33984b13 @@ -44,12 +54,12 @@ GEM rsolr (>= 1.1.2, < 3) ruby-progressbar (~> 1.0) solrizer (>= 3.4, < 5) - active-triples (1.1.0) + active-triples (1.1.1) activemodel (>= 3.0.0) activesupport (>= 3.0.0) rdf (>= 2.0.2, < 4.0) rdf-vocab (>= 2.0, < 4.0) - active_encode (0.7.0) + active_encode (0.8.1) rails sprockets (< 4) activejob (5.1.7) @@ -65,41 +75,42 @@ GEM activemodel (= 5.1.7) activesupport (= 5.1.7) arel (~> 8.0) - activerecord-import (1.0.7) + activerecord-import (1.2.0) activerecord (>= 3.2) activesupport (5.1.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.7.0) + addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) almond-rails (0.3.0) rails (>= 4.2) + amazing_print (1.3.0) arel (8.0.0) - ast (2.4.1) - autoprefixer-rails (10.0.1.2) - execjs - awesome_nested_set (3.2.1) + ast (2.4.2) + autoprefixer-rails (10.3.1.0) + execjs (~> 2) + awesome_nested_set (3.4.0) activerecord (>= 4.0.0, < 7.0) - aws-eventstream (1.1.0) - aws-partitions (1.388.0) - aws-sdk-codedeploy (1.37.0) - aws-sdk-core (~> 3, >= 3.109.0) + aws-eventstream (1.1.1) + aws-partitions (1.488.0) + aws-sdk-codedeploy (1.42.0) + aws-sdk-core (~> 3, >= 3.119.0) aws-sigv4 (~> 1.1) - aws-sdk-core (3.109.1) + aws-sdk-core (3.119.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.39.0) - aws-sdk-core (~> 3, >= 3.109.0) + aws-sdk-kms (1.46.0) + aws-sdk-core (~> 3, >= 3.119.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.83.1) - aws-sdk-core (~> 3, >= 3.109.0) + aws-sdk-s3 (1.99.0) + aws-sdk-core (~> 3, >= 3.119.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) - aws-sigv4 (1.2.2) + aws-sigv4 (1.2.4) aws-eventstream (~> 1, >= 1.0.2) babel-source (5.8.35) babel-transpiler (0.7.0) @@ -115,7 +126,7 @@ GEM rubocop-performance rubocop-rails rubocop-rspec - blacklight (6.23.0) + blacklight (6.24.0) bootstrap-sass (~> 3.2) deprecation globalid @@ -146,28 +157,27 @@ GEM actionpack (>= 5.0) activemodel (>= 5.0) breadcrumbs_on_rails (3.0.1) - browse-everything (1.1.0) + browse-everything (1.1.2) addressable (~> 2.5) aws-sdk-s3 dropbox_api (>= 0.1.10) google-api-client (~> 0.23) google_drive (>= 2.1, < 4) googleauth (>= 0.6.6, < 1.0) - rails (>= 4.2, < 6.0) + rails (>= 4.2, < 7.0) ruby-box signet (~> 0.8) - sprockets (~> 3.7) typhoeus builder (3.2.4) byebug (11.1.3) cancancan (1.17.0) - capybara (3.33.0) + capybara (3.35.3) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) - regexp_parser (~> 1.5) + regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) capybara-screenshot (1.0.25) capybara (>= 1.0, < 4) @@ -187,17 +197,22 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.8) - connection_pool (2.2.3) - crack (0.4.4) + concurrent-ruby (1.1.9) + connection_pool (2.2.5) + crack (0.4.5) + rexml crass (1.0.6) curb (0.9.11) - database_cleaner (1.8.5) + database_cleaner (2.0.1) + database_cleaner-active_record (~> 2.0.0) + database_cleaner-active_record (2.0.1) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) declarative (0.0.20) - declarative-option (0.1.0) - deprecation (1.0.0) + deprecation (1.1.0) activesupport - devise (4.7.3) + devise (4.8.0) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -210,84 +225,81 @@ GEM dotenv-rails (2.7.6) dotenv (= 2.7.6) railties (>= 3.2) - draper (4.0.1) + draper (4.0.2) actionpack (>= 5.0) activemodel (>= 5.0) activemodel-serializers-xml (>= 1.0) activesupport (>= 5.0) request_store (>= 1.0) + ruby2_keywords dropbox_api (0.1.18) faraday (<= 1.0) oauth2 (~> 1.1) - dry-configurable (0.11.6) + dry-configurable (0.12.1) concurrent-ruby (~> 1.0) - dry-core (~> 0.4, >= 0.4.7) - dry-equalizer (~> 0.2) + dry-core (~> 0.5, >= 0.5.0) dry-container (0.7.2) concurrent-ruby (~> 1.0) dry-configurable (~> 0.1, >= 0.1.3) - dry-core (0.4.9) + dry-core (0.6.0) concurrent-ruby (~> 1.0) dry-equalizer (0.3.0) - dry-events (0.2.0) + dry-events (0.3.0) concurrent-ruby (~> 1.0) - dry-core (~> 0.4) - dry-equalizer (~> 0.2) + dry-core (~> 0.5, >= 0.5) dry-inflector (0.2.0) dry-initializer (3.0.4) - dry-logic (1.0.8) + dry-logic (1.2.0) concurrent-ruby (~> 1.0) - dry-core (~> 0.2) - dry-equalizer (~> 0.2) - dry-matcher (0.8.3) - dry-core (>= 0.4.8) + dry-core (~> 0.5, >= 0.5) + dry-matcher (0.9.0) + dry-core (~> 0.4, >= 0.4.8) dry-monads (1.3.5) concurrent-ruby (~> 1.0) dry-core (~> 0.4, >= 0.4.4) dry-equalizer - dry-schema (1.5.6) + dry-schema (1.6.2) concurrent-ruby (~> 1.0) dry-configurable (~> 0.8, >= 0.8.3) - dry-core (~> 0.4) - dry-equalizer (~> 0.2) + dry-core (~> 0.5, >= 0.5) dry-initializer (~> 3.0) dry-logic (~> 1.0) - dry-types (~> 1.4) - dry-struct (1.3.0) - dry-core (~> 0.4, >= 0.4.4) - dry-equalizer (~> 0.3) - dry-types (~> 1.3) + dry-types (~> 1.5) + dry-struct (1.4.0) + dry-core (~> 0.5, >= 0.5) + dry-types (~> 1.5) ice_nine (~> 0.11) - dry-transaction (0.13.0) + dry-transaction (0.13.2) dry-container (>= 0.2.8) dry-events (>= 0.1.0) dry-matcher (>= 0.7.0) dry-monads (>= 0.4.0) - dry-types (1.4.0) + dry-types (1.5.1) concurrent-ruby (~> 1.0) dry-container (~> 0.3) - dry-core (~> 0.4, >= 0.4.4) - dry-equalizer (~> 0.3) + dry-core (~> 0.5, >= 0.5) dry-inflector (~> 0.1, >= 0.1.2) dry-logic (~> 1.0, >= 1.0.2) - dry-validation (1.5.6) + dry-validation (1.6.0) concurrent-ruby (~> 1.0) dry-container (~> 0.7, >= 0.7.1) dry-core (~> 0.4) dry-equalizer (~> 0.2) dry-initializer (~> 3.0) dry-schema (~> 1.5, >= 1.5.2) - ebnf (2.1.2) + ebnf (2.1.3) + amazing_print (~> 1.2) htmlentities (~> 4.3) rdf (~> 3.1) scanf (~> 1.0) sxp (~> 1.1) + unicode-types (~> 1.6) equivalent-xml (0.6.0) nokogiri (>= 1.4.3) - erubi (1.9.0) - ethon (0.12.0) - ffi (>= 1.3.0) - execjs (2.7.0) + erubi (1.10.0) + ethon (0.14.0) + ffi (>= 1.15.0) + execjs (2.8.1) factory_bot (4.11.1) activesupport (>= 3.0.0) factory_bot_rails (4.11.1) @@ -295,42 +307,61 @@ GEM railties (>= 3.0.0) faker (1.9.6) i18n (>= 0.7) - faraday (0.17.3) + faraday (0.17.4) multipart-post (>= 1.2, < 3) faraday-encoding (0.0.4) faraday + faraday_middleware (0.14.0) + faraday (>= 0.7.4, < 1.0) fcrepo_wrapper (0.9.0) ruby-progressbar - ffi (1.13.1) + ffi (1.15.3) flipflop (2.6.0) activesupport (>= 4.0) flot-rails (0.0.7) jquery-rails - font-awesome-rails (4.7.0.5) - railties (>= 3.2, < 6.1) - globalid (0.4.2) - activesupport (>= 4.2.0) - google-api-client (0.48.0) + font-awesome-rails (4.7.0.7) + railties (>= 3.2, < 7) + gems (1.2.0) + globalid (0.5.2) + activesupport (>= 5.0) + google-api-client (0.53.0) + google-apis-core (~> 0.1) + google-apis-generator (~> 0.1) + google-apis-core (0.4.1) addressable (~> 2.5, >= 2.5.1) - googleauth (~> 0.9) - httpclient (>= 2.8.1, < 3.0) + googleauth (>= 0.16.2, < 2.a) + httpclient (>= 2.8.1, < 3.a) mini_mime (~> 1.0) representable (~> 3.0) - retriable (>= 2.0, < 4.0) + retriable (>= 2.0, < 4.a) rexml - signet (~> 0.12) - google_drive (3.0.5) - google-api-client (>= 0.11.0, < 1.0.0) + webrick + google-apis-discovery_v1 (0.6.0) + google-apis-core (>= 0.4, < 2.a) + google-apis-drive_v3 (0.13.0) + google-apis-core (>= 0.4, < 2.a) + google-apis-generator (0.4.0) + activesupport (>= 5.0) + gems (~> 1.2) + google-apis-core (>= 0.4, < 2.a) + google-apis-discovery_v1 (~> 0.5) + thor (>= 0.20, < 2.a) + google-apis-sheets_v4 (0.9.0) + google-apis-core (>= 0.4, < 2.a) + google_drive (3.0.7) + google-apis-drive_v3 (>= 0.5.0, < 1.0.0) + google-apis-sheets_v4 (>= 0.4.0, < 1.0.0) googleauth (>= 0.5.0, < 1.0.0) nokogiri (>= 1.5.3, < 2.0.0) - googleauth (0.14.0) + googleauth (0.17.0) faraday (>= 0.17.3, < 2.0) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (~> 0.14) - haml (5.2.0) + haml (5.2.2) temple (>= 0.8.0) tilt hamster (3.0.0) @@ -361,7 +392,7 @@ GEM deprecation mime-types (> 2.0, < 4.0) mini_magick (>= 3.2, < 5) - hydra-editor (5.0.3) + hydra-editor (5.0.5) active-fedora (>= 9.0.0) activerecord (~> 5.0) almond-rails (~> 0.1) @@ -446,7 +477,7 @@ GEM ice_nine (0.11.2) iiif_manifest (0.5.0) activesupport (>= 4) - jbuilder (2.10.1) + jbuilder (2.11.2) activesupport (>= 5.0.0) jmespath (1.4.0) jquery-datatables-rails (3.4.0) @@ -460,21 +491,21 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (6.0.1) railties (>= 3.2.16) - json (2.3.1) - json-canonicalization (0.2.0) - json-ld (3.1.4) + json (2.5.1) + json-canonicalization (0.2.1) + json-ld (3.1.9) htmlentities (~> 4.3) json-canonicalization (~> 0.2) link_header (~> 0.0, >= 0.0.8) multi_json (~> 1.14) rack (~> 2.0) rdf (~> 3.1) - json-ld-preloaded (3.1.3) + json-ld-preloaded (3.1.6) json-ld (~> 3.1) rdf (~> 3.1) json-schema (2.8.1) addressable (>= 2.4) - jwt (2.2.2) + jwt (2.2.3) kaminari (1.2.1) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.1) @@ -491,13 +522,13 @@ GEM kaminari (~> 1.0) launchy (2.5.0) addressable (~> 2.7) - ld-patch (3.1.1) - ebnf (~> 2.0) + ld-patch (3.1.3) + ebnf (~> 2.1) rdf (~> 3.1) rdf-xsd (~> 3.1) sparql (~> 3.1) sxp (~> 1.1) - ldp (1.0.1) + ldp (1.0.3) deprecation faraday http_logger @@ -542,7 +573,7 @@ GEM rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) - loofah (2.7.0) + loofah (2.12.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) @@ -554,10 +585,10 @@ GEM method_source (1.0.0) mime-types (3.3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2021.0225) - mini_magick (4.10.1) - mini_mime (1.0.2) - mini_portile2 (2.5.0) + mime-types-data (3.2021.0704) + mini_magick (4.11.0) + mini_mime (1.1.0) + mini_portile2 (2.6.1) minitest (5.14.4) multi_json (1.15.0) multi_xml (0.6.0) @@ -565,34 +596,34 @@ GEM mysql2 (0.4.10) nest (3.2.0) redic - net-http-persistent (3.1.0) + net-http-persistent (4.0.1) connection_pool (~> 2.2) - nio4r (2.5.4) + nio4r (2.5.8) noid (0.9.0) - noid-rails (3.0.2) + noid-rails (3.0.3) actionpack (>= 5.0.0, < 7) noid (~> 0.9) - nokogiri (1.11.0) - mini_portile2 (~> 2.5.0) + nokogiri (1.12.3) + mini_portile2 (~> 2.6.1) racc (~> 1.4) - nokogumbo (2.0.2) + nokogumbo (2.0.5) nokogiri (~> 1.8, >= 1.8.4) - oauth (0.5.4) - oauth2 (1.4.4) + oauth (0.5.6) + oauth2 (1.4.7) faraday (>= 0.8, < 2.0) jwt (>= 1.0, < 3.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - openseadragon (0.5.0) + openseadragon (0.6.0) rails (> 3.2.0) orm_adapter (0.5.0) os (1.1.1) - parallel (1.19.2) - parser (2.7.2.0) + parallel (1.20.1) + parser (3.0.2.0) ast (~> 2.4.1) parslet (2.0.0) - pbcore (0.3.0) + pbcore (0.3.2) factory_bot (~> 4.11) faker (~> 1.9) nokogiri (~> 1.10) @@ -617,7 +648,7 @@ GEM rdf racc (1.5.2) rack (2.2.3) - rack-proxy (0.6.5) + rack-proxy (0.7.0) rack rack-test (1.1.0) rack (>= 1.0, < 3) @@ -651,16 +682,16 @@ GEM rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (3.0.0) - rake (13.0.1) - rb-fsevent (0.10.4) + rake (13.0.6) + rb-fsevent (0.11.0) rb-inotify (0.10.1) ffi (~> 1.0) - rdf (3.1.6) + rdf (3.1.15) hamster (~> 3.0) link_header (~> 0.0, >= 0.0.8) rdf-aggregate-repo (3.1.0) rdf (~> 3.1) - rdf-isomorphic (3.1.0) + rdf-isomorphic (3.1.1) rdf (~> 3.1) rdf-json (3.1.0) rdf (~> 3.1) @@ -669,9 +700,10 @@ GEM nokogiri (~> 1.10) rdf (~> 3.1) rdf-xsd (~> 3.1) - rdf-n3 (3.1.1) - rdf (~> 3.1) - sparql (~> 3.1) + rdf-n3 (3.1.2) + ebnf (~> 2.1) + rdf (~> 3.1, >= 3.1.8) + sparql (~> 3.1, >= 3.1.4) sxp (~> 1.1) rdf-normalize (0.4.0) rdf (~> 3.1) @@ -681,14 +713,13 @@ GEM rdf (~> 3.1) rdf-aggregate-repo (~> 3.1) rdf-xsd (~> 3.1) - rdf-rdfxml (3.1.0) + rdf-rdfxml (3.1.1) htmlentities (~> 4.3) rdf (~> 3.1) rdf-rdfa (~> 3.1) rdf-xsd (~> 3.1) - rdf-reasoner (0.6.0) - rdf (~> 3.1) - rdf-vocab (~> 3.1) + rdf-reasoner (0.7.2) + rdf (~> 3.1, >= 3.1.12) rdf-xsd (~> 3.1) rdf-tabular (3.1.1) addressable (~> 2.3) @@ -697,19 +728,21 @@ GEM rdf (~> 3.1) rdf-vocab (~> 3.1) rdf-xsd (~> 3.1) - rdf-trig (3.1.1) - ebnf (~> 2.0) + rdf-trig (3.1.2) + ebnf (~> 2.1) rdf (~> 3.1) rdf-turtle (~> 3.1) - rdf-trix (3.1.0) + rdf-trix (3.1.1) rdf (~> 3.1) - rdf-turtle (3.1.2) - ebnf (~> 2.0) - rdf (~> 3.1, >= 3.1.2) + rdf-xsd (~> 3.1) + rdf-turtle (3.1.3) + ebnf (~> 2.1) + rdf (~> 3.1, >= 3.1.8) rdf-vocab (3.1.4) rdf (~> 3.1) - rdf-xsd (3.1.0) + rdf-xsd (3.1.1) rdf (~> 3.1) + rexml (~> 3.2) react-rails (2.6.1) babel-transpiler (>= 0.7.0) connection_pool @@ -718,15 +751,15 @@ GEM tilt redic (1.5.3) hiredis - redis (4.2.2) - redis-namespace (1.8.0) + redis (4.4.0) + redis-namespace (1.8.1) redis (>= 3.0.4) - redlock (1.2.0) + redlock (1.2.1) redis (>= 3.0.0, < 5.0) - regexp_parser (1.8.2) - representable (3.0.4) + regexp_parser (2.1.1) + representable (3.1.1) declarative (< 0.1.0) - declarative-option (< 0.2.0) + trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) request_store (1.5.0) rack (>= 1.4) @@ -734,7 +767,7 @@ GEM actionpack (>= 5.0) railties (>= 5.0) retriable (3.1.2) - rexml (3.2.4) + rexml (3.2.5) roo (2.7.1) nokogiri (~> 1) rubyzip (~> 1.1, < 2.0.0) @@ -793,7 +826,8 @@ GEM json multipart-post oauth2 - ruby-progressbar (1.10.1) + ruby-progressbar (1.11.0) + ruby2_keywords (0.0.5) ruby_dep (1.5.0) rubyzip (1.3.0) samvera-nesting_indexer (2.0.0) @@ -813,8 +847,7 @@ GEM ffi (~> 1.9) sax-machine (1.3.2) scanf (1.0.0) - select2-rails (3.5.10) - thor (~> 0.14) + select2-rails (3.5.11) selenium-webdriver (3.142.7) childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) @@ -826,13 +859,13 @@ GEM rdf-xsd (~> 3.1) sparql (~> 3.1) sxp (~> 1.1) - shoulda-matchers (4.4.1) + shoulda-matchers (4.5.1) activesupport (>= 4.2.0) - sidekiq (6.1.2) + sidekiq (6.2.1) connection_pool (>= 2.2.2) rack (~> 2.0) redis (>= 4.2.0) - signet (0.14.0) + signet (0.15.0) addressable (~> 2.3) faraday (>= 0.17.3, < 2.0) jwt (>= 1.5, < 3.0) @@ -840,7 +873,7 @@ GEM simple_form (5.0.0) actionpack (>= 5.0) activemodel (>= 5.0) - slop (4.8.2) + slop (4.9.1) solr_wrapper (2.2.0) faraday retriable @@ -850,17 +883,16 @@ GEM activesupport nokogiri xml-simple - sony_ci_api (0.2.1) - sparql (3.1.3) + sparql (3.1.7) builder (~> 3.2) - ebnf (>= 1.1) - rdf (~> 3.1, >= 3.1.2) + ebnf (~> 2.1) + rdf (~> 3.1, >= 3.1.14) rdf-aggregate-repo (~> 3.1) rdf-xsd (~> 3.1) - sparql-client (~> 3.1) + sparql-client (~> 3.1, >= 3.1.2) sxp (~> 1.1) - sparql-client (3.1.0) - net-http-persistent (~> 3.1) + sparql-client (3.1.2) + net-http-persistent (~> 4.0, >= 4.0.1) rdf (~> 3.1) sprockets (3.7.2) concurrent-ruby (~> 1.0) @@ -878,11 +910,12 @@ GEM sxp (1.1.0) rdf (~> 3.1) temple (0.8.2) - thor (0.20.3) + thor (1.1.0) thread_safe (0.3.6) tilt (2.0.10) tinymce-rails (4.9.11) railties (>= 3.1.1) + trailblazer-option (0.1.1) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) @@ -898,6 +931,7 @@ GEM uglifier (4.2.0) execjs (>= 0.3.0, < 3) unicode-display_width (1.7.0) + unicode-types (1.6.0) warden (1.2.9) rack (>= 2.0.9) web-console (3.7.0) @@ -905,22 +939,23 @@ GEM activemodel (>= 5.0) bindex (>= 0.4.0) railties (>= 5.0) - webdrivers (4.4.1) + webdrivers (4.6.0) nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (>= 3.0, < 4.0) - webmock (3.9.3) - addressable (>= 2.3.6) + webmock (3.14.0) + addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) webpacker (4.3.0) activesupport (>= 4.2) rack-proxy (>= 0.6.1) railties (>= 4.2) + webrick (1.7.0) websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - xml-simple (1.1.5) + xml-simple (1.1.8) xpath (3.2.0) nokogiri (~> 1.8) xray-rails (0.3.2) @@ -976,7 +1011,7 @@ DEPENDENCIES sidekiq simple_form (= 5.0.0) solr_wrapper (~> 2.1) - sony_ci_api (~> 0.2.1) + sony_ci_api! sqlite3 (= 1.3.13) turbolinks (~> 5) uglifier (>= 1.3.0) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 54ead196c..019c7c2f8 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -10,7 +10,6 @@ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // about supported directives. // -//= //= require turbolinks // // Required by Blacklight diff --git a/app/assets/javascripts/sony_ci/find_media.coffee b/app/assets/javascripts/sony_ci/find_media.coffee new file mode 100644 index 000000000..02e412fa7 --- /dev/null +++ b/app/assets/javascripts/sony_ci/find_media.coffee @@ -0,0 +1,99 @@ +class FindSonyCiMediaBehavior + # Select for the search button + searchButtonSelector: '#find_sony_ci_media #search' + # Selector for the div that displays the feedback messages. + feedbackSelector: '#find_sony_ci_media #feedback' + # Selector for the text inputs that have the Sony Ci IDs. + sonyCiIdInputSelector: 'input.asset_sonyci_id' + # Selector for the button to add new Sony Ci IDs + addNewSonyCiIdButtonSelector: '.form-group.asset_sonyci_id button.add' + + constructor: (@query) -> + + # searchHandler - search Sony Ci for records matching the query and provide + # feedback to the user. + searchHandler: (event) => + event.preventDefault() + @giveFeedback('searching...') + $.ajax( + context: this, + url: "/sony_ci/api/find_media", + data: { query: @query } + ).done ( response ) -> + @giveFeedback(response.length + ' records found') + if response.length > 0 + @addFoundRecords(response) + + # fetchFilenameHandler - fetches the filename from Sony Ci given a Sony Ci ID + # from an input field. + fetchFilenameHandler: -> + $.ajax( + url: "/sony_ci/api/get_filename", + context: this, + data: { sony_ci_id: $(this).val() } + ).done(( response ) -> + $(this).parent().find('.sony_ci_filename').text(response['name']) + ).fail(( response ) -> + $(this).parent().find('.sony_ci_filename').text("Could not find Sony Ci record") + ) + + # Adds a message to give the user feedback on what's happening. + # The element is hidden at first, so set the text and reveal it. + giveFeedback: (msg) => + $(@feedbackSelector).text(msg).show() + + addFoundRecords: (records) => + # Map the sonyci_id text inputs to their values. + existingSonyCiIds = $(@sonyCiIdInputSelector).map (_, element) -> + $(element).val() + + # Map the found records to just the Sony Ci IDs. + # This is not a jQuery.map function, so the index is the 2nd arg instead of + # the first, like in the map function above. + foundSonyCiIds = records.map (record, _) -> + record['id'] + + # Subtract the existing Sony Ci Ids from the found Sony Ci IDs. + newSonyCiIds = $(foundSonyCiIds).not(existingSonyCiIds).get(); + + # For each of the new found Sony Ci IDs... + newSonyCiIds.forEach (sonyCiId, index) => + + # Insert the found Sony Ci ID into the last text input and trigger the \ + # change() event, because just setting val(x) won't do it. + $(@sonyCiIdInputSelector).last().val(sonyCiId).change() + + # If we have more Sony Ci IDs to add + if newSonyCiIds.length > index + # Add another Sony Ci ID field it by clicking the "Add another..." + # button. + $(@addNewSonyCiIdButtonSelector).click() + + # Hyrax will simply copy and append the last element, but we don't want + # values for Sony Ci ID or Filename there, so clear them out. + $(@sonyCiIdInputSelector).last().val('') + $('.sony_ci_filename').last().text('') + + # Finally, add the handler to the change() event of the input. + $(@sonyCiIdInputSelector).last().change @fetchFilenameHandler + + # apply - Attaches handlers to events. + apply: -> + # Attach the search handler to the click event of the search button. + $(@searchButtonSelector).click @searchHandler + # Attach the fetchFilenameHanlder to the change event of the inputs. + $(@sonyCiIdInputSelector).change @fetchFilenameHandler + +# When the page loads... +$(document).on 'turbolinks:load', -> + # This regex matches the 3rd URL segment which should be the GUID. + guid_query_str = window.location.href.match(/concern\/assets\/(.*)\//)[1] + # Create the behavior object, passing in the GUID as the query string. + # NOTE: Sony Ci API has a 20 character limit on it's search terms, so let's + # just pass in the last 20 characters, which will be more unique than the 1st + # 20 chars due to the common prefix of "cpb-aacip-". Supposedly, Michael Potts + # from Sony Ci said that quoted search queries have no such limit, but I could + # not get that to work, nor is it mentioned in the Ci API docs anywhere. + behavior = new FindSonyCiMediaBehavior(guid_query_str.substr(-20)) + # apply the behavior + behavior.apply() diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb index 8e589819d..9189c2d2a 100644 --- a/app/controllers/media_controller.rb +++ b/app/controllers/media_controller.rb @@ -16,12 +16,14 @@ def show private def download_url - @download_url ||= ci.download(solr_document['sonyci_id_ssim'][(params['part'] || 0).to_i]) + @download_url ||= begin + download_response = ci.asset_download(solr_document['sonyci_id_ssim'][(params['part'] || 0).to_i]) + download_response['location'] + end end def ci - credentials = YAML.load(ERB.new(File.read('config/ci.yml')).result) - @ci ||= SonyCiBasic.new(credentials:credentials) + @ci ||= SonyCiApi::Client.new('config/ci.yml') end def solr_document diff --git a/app/controllers/sony_ci/api_controller.rb b/app/controllers/sony_ci/api_controller.rb new file mode 100644 index 000000000..5680f88ff --- /dev/null +++ b/app/controllers/sony_ci/api_controller.rb @@ -0,0 +1,48 @@ +require 'sony_ci_api' + +module SonyCi + class APIController < ::APIController + rescue_from StandardError, with: :default_error + + def find_media + result = sony_ci_api.workspace_search( + query: permitted_params.require(:query), + fields: return_fields, + kind: "Asset" + ) + render json: result + end + + def get_filename + sony_ci_id = params.require(:sony_ci_id) + result = sony_ci_api.asset(sony_ci_id) + render json: { 'sony_ci_id' => sony_ci_id, 'name' => result['name'] } + end + + private + + def sony_ci_api + @sony_ci_api ||= SonyCiApi::Client.new('config/ci.yml') + end + + # Sony Ci will return 'id', 'name', and 'kind' plus any other fields + # specified in a comma-separated list in :fields param. An empty string + # for the :fields param will return all fields. If :fields is nil, + # specify 'createdOn' as an additional default field. + def return_fields + params[:fields] || 'createdOn' + end + + def permitted_params + params.permit(:query, :fields) + end + + # Default error handler. Respond with JSON error and 500 + def default_error(e) + # If the error is a SonyCiApi::Error, it should have an http_status, + # if so, use it. Else default to 500. + status = e.respond_to?(:http_status) ? e.http_status : 500 + render json: { error: e.class.to_s, error_message: e.message }, status: status + end + end +end diff --git a/app/input/sony_ci_id_input.rb b/app/input/sony_ci_id_input.rb new file mode 100644 index 000000000..0095e1e27 --- /dev/null +++ b/app/input/sony_ci_id_input.rb @@ -0,0 +1,16 @@ +class SonyCiIdInput < MultiValueInput + def build_field(value, index) + super + sony_ci_filename_html(value).to_s.html_safe + end + + private + + def sony_ci_filename_html(sony_ci_id) + # NOTE: object.model.admin_data will be FALSE if this is a new record so + # we need to guard against that. + filename = if object.model.admin_data.present? + object.model.admin_data.sonyci_records&.fetch(sony_ci_id, nil)&.fetch('name', nil) + end + "

Filename: #{filename}

" + end +end diff --git a/app/models/admin_data.rb b/app/models/admin_data.rb index 85769ea44..eb6febcd0 100644 --- a/app/models/admin_data.rb +++ b/app/models/admin_data.rb @@ -57,4 +57,23 @@ def asset(refresh: false) @asset_error = error nil end + + # Returns a hash of Sony Ci records fetched from the Sony Ci API, keyed + # by the Sony Ci ID. + def sonyci_records + # NOTE: sonyci_id (although singular) is actually a serialized array. + # We do hit the API per sonyci_id here, but over 99% of the time, there will + # be only one, and when there's more, there are not a whole bunch. + @sonyci_records ||= {}.tap do |hash| + sonyci_id.each { |id| hash[id] = sony_ci_api.asset(id) } + end + rescue => e + Rails.logger.error "Could not retrieve records from Sony Ci API.\n " \ + "#{e.class}: #{e.message}" + nil + end + + def sony_ci_api + @sony_ci_api ||= SonyCiApi::Client.new('config/ci.yml') + end end diff --git a/app/services/ams/media_download/media_download_service.rb b/app/services/ams/media_download/media_download_service.rb index 93c82189e..a9b8a4f8d 100644 --- a/app/services/ams/media_download/media_download_service.rb +++ b/app/services/ams/media_download/media_download_service.rb @@ -34,8 +34,7 @@ def self.cleanup_temp_file(temp_file: nil) private def ci - credentials = YAML.load(ERB.new(File.read('config/ci.yml')).result) - @ci ||= SonyCiBasic.new(credentials:credentials) + @ci ||= SonyCiApi::Client.new('config/ci.yml') end def process_download @@ -82,7 +81,7 @@ def delete_media_files(array_of_files) end def get_sonyci_file_location(sonyci_id) - ci.download(sonyci_id) + ci.asset_download(sonyci_id)['location'] end def parse_sonyci_file_name(location) diff --git a/app/views/records/edit_fields/_default.html.erb b/app/views/records/edit_fields/_default.html.erb index 0137cbc34..3e4ee560e 100644 --- a/app/views/records/edit_fields/_default.html.erb +++ b/app/views/records/edit_fields/_default.html.erb @@ -4,4 +4,4 @@ <%= f.input key, required: f.object.required?(key), as: :hidden %> <% else %> <%= f.input key, required: f.object.required?(key), disabled:f.object.respond_to?(:disabled?) && f.object.disabled?(key), readonly:f.object.respond_to?(:readonly?) && f.object.readonly?(key) %> -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/records/edit_fields/_md5.html.erb b/app/views/records/edit_fields/_md5.html.erb index e5f4febeb..0ed671be8 100644 --- a/app/views/records/edit_fields/_md5.html.erb +++ b/app/views/records/edit_fields/_md5.html.erb @@ -1,2 +1 @@ - <%= f.input :md5, label: 'md5' ,required: f.object.required?(key), disabled:f.object.respond_to?(:disabled?) && f.object.disabled?(key) %> diff --git a/app/views/records/edit_fields/_sonyci_id.html.erb b/app/views/records/edit_fields/_sonyci_id.html.erb new file mode 100644 index 000000000..fc2eb7b08 --- /dev/null +++ b/app/views/records/edit_fields/_sonyci_id.html.erb @@ -0,0 +1,17 @@ +<%= javascript_include_tag "sony_ci/find_media" %> +<% asset_id = f.object.model.id %> +<% if asset_id %> +
+ Find all Sony Ci files matching <%= asset_id %> + +
+<% end %> + +<%= + f.input 'sonyci_id', as: :sony_ci_id, + input_html: { class: 'form-control' }, + wrapper_html: { class: 'multi_value' }, + disabled: f.object.respond_to?(:disabled?) && f.object.disabled?(key), + readonly: f.object.respond_to?(:readonly?) && f.object.readonly?(key), + required: f.object.required?(key) +%> diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index b3e9d6dad..980166766 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -12,4 +12,4 @@ # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. # Rails.application.config.assets.precompile += %w( admin.js admin.css ) -Rails.application.config.assets.precompile += %w( work_actions.js work_show/work_show.css ) +Rails.application.config.assets.precompile += %w( work_actions.js work_show/work_show.css sony_ci/find_media.coffee ) diff --git a/config/routes.rb b/config/routes.rb index fbba45542..608d97f0c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -66,7 +66,13 @@ post "/audits/new" => "audits#create" namespace :sony_ci do - post '/webhooks/save_sony_ci_id', controller: 'webhooks', action: :save_sony_ci_id + # Define routes that receive requests from Sony Ci webhooks. + post '/webhooks/save_sony_ci_id', controller: 'webhooks', + action: :save_sony_ci_id + + # Define routes for making customized requests to the Sony Ci API + get '/api/find_media', controller: 'api', action: :find_media + get '/api/get_filename', controller: 'api', action: :get_filename end diff --git a/spec/controllers/media_controller_spec.rb b/spec/controllers/media_controller_spec.rb index 75f329c8f..2b49f8837 100644 --- a/spec/controllers/media_controller_spec.rb +++ b/spec/controllers/media_controller_spec.rb @@ -6,11 +6,14 @@ let(:id) { '1234' } let(:sony_ci_id) { '4567' } let(:fake_sony_ci_url) { "https://fakesonyci.com/download/#{sony_ci_id}"} - let(:fake_sony_ci_api) { instance_double("SonyCiBasic") } + let(:fake_sony_ci_api) { instance_double(SonyCiApi::Client) } + let(:fake_sony_ci_response) { + { 'id' => sony_ci_id, 'location' => fake_sony_ci_url } + } let(:fake_solr_document) { { 'sonyci_id_ssim' => [sony_ci_id] } } before do - allow(fake_sony_ci_api).to receive(:download).with(sony_ci_id).and_return(fake_sony_ci_url) + allow(fake_sony_ci_api).to receive(:asset_download).with(sony_ci_id).and_return(fake_sony_ci_response) allow(controller).to receive(:ci).and_return(fake_sony_ci_api) allow(controller).to receive(:solr_document).and_return(fake_solr_document) allow(controller).to receive(:can?).with(:show, fake_solr_document).and_return(true) @@ -29,7 +32,7 @@ context 'and when user has permission to view the file' do it 'the SonyCiApi is used to fetch the media url' do get :show, params: { id: id } - expect(fake_sony_ci_api).to have_received(:download).with(sony_ci_id) + expect(fake_sony_ci_api).to have_received(:asset_download).with(sony_ci_id) expect(response).to redirect_to fake_sony_ci_url end end diff --git a/spec/controllers/sony_ci/api_controller_spec.rb b/spec/controllers/sony_ci/api_controller_spec.rb new file mode 100644 index 000000000..739ca2875 --- /dev/null +++ b/spec/controllers/sony_ci/api_controller_spec.rb @@ -0,0 +1,81 @@ +require 'rails_helper' + +RSpec.describe SonyCi::APIController do + # Defind params to use in GET request. + let(:params) { { query: "foo" } } + let(:mock_sony_ci_api) { instance_double(SonyCiApi::Client) } + + before do + # Use a mock Sony Ci API in the controller. + allow(controller).to receive(:sony_ci_api).and_return(mock_sony_ci_api) + end + + # All methods in SonyCi::APIController should catch errors raised by + # SonyCiApi::Client and render JSON with the error info, and respond with + # the proper HTTP status. + shared_examples 'error responses' do |ams_endpoint:, params:| + # The specific error class, message, and response status are arbitrary, we + # just are testing to make sure they make get passed on through the response. + let(:error_msg) { "Some error message" } + let(:status) { rand(400..599) } + before do + # Stub all the instance methods of SonyCiApi::Client to raise an arbitrary + # error. + SonyCiApi::Client.instance_methods(false).each do |instance_method| + allow(mock_sony_ci_api).to receive(instance_method).with(any_args).and_raise( + SonyCiApi::Error.new(error_msg, http_status: status) + ) + end + + # call the method under test + get ams_endpoint, params: params + end + + it 'responds with proper http code and error info' do + expect(JSON.parse(response.body)).to eq( + { "error" => "SonyCiApi::Error", "error_message" => error_msg } + ) + expect(response.status).to eq status + end + end + + describe 'GET find_media' do + before do + # the find_media action calls SonyCiApi::Client#workspace_search, so mock + # that here as well. + allow(mock_sony_ci_api).to receive(:workspace_search).with( + hash_including(params) + ) + # Call the action under test. + get :find_media, params: params + end + + context 'with :query param that returns results from Sony Ci API' do + it 'returns a 200 ' do + expect(response.status).to eq 200 + end + end + end + + describe 'GET get_filename' do + let(:params) { { sony_ci_id: '123' } } + + context 'when Sony Ci API does not raise an error' do + let(:expected_response) { { 'sony_ci_id' => params[:sony_ci_id], 'name' => 'foo.mp4' } } + before do + allow(mock_sony_ci_api).to receive(:asset).with(params[:sony_ci_id]).and_return( + expected_response + ) + # call the method under test + get :get_filename, params: params + end + + it 'gets the filename for a given Sony Ci ID' do + expect(JSON.parse(response.body)).to eq expected_response + expect(response.status).to eq 200 + end + end + + include_examples 'error responses', ams_endpoint: :get_filename, params: { sony_ci_id: '123' } + end +end diff --git a/spec/controllers/sony_ci/webhooks_controller_spec.rb b/spec/controllers/sony_ci/webhooks_controller_spec.rb index daa8fc0dd..ecb8d72b0 100644 --- a/spec/controllers/sony_ci/webhooks_controller_spec.rb +++ b/spec/controllers/sony_ci/webhooks_controller_spec.rb @@ -4,7 +4,7 @@ # non-memoized shortcut to random hex string def randhex(len=32) - len.times.map { rand(15).to_s(16) } + ''.tap { |s| len.times { s << rand(15).to_s(16) } } end describe 'POST save_sony_ci_id' do diff --git a/spec/features/update_admin_data_spec.rb b/spec/features/update_admin_data_spec.rb index 8587c7743..455e13d0d 100644 --- a/spec/features/update_admin_data_spec.rb +++ b/spec/features/update_admin_data_spec.rb @@ -3,7 +3,7 @@ # This is really a test of work done in the AssetActor # Actor classes are very hard to test due to attempting to mock the entire environment, # so this indirectly and imperfectly tests our saving expections -RSpec.feature 'Update AdminData', js: true, asset_form_helpers: true, clean: true do +RSpec.feature 'Update AdminData', asset_form_helpers: true, clean: true do context 'Create adminset, create asset' do let(:admin_user) { create :admin_user } let(:admin_set_id) { AdminSet.find_or_create_default_admin_set_id } @@ -11,12 +11,24 @@ let!(:workflow) { Sipity::Workflow.create!(active: true, name: 'test-workflow', permission_template: permission_template) } let!(:admindata) { create(:admin_data, :empty)} let!(:asset) { FactoryBot.create(:asset, with_admin_data: admindata.gid) } + let(:fake_sonyci_id) { rand(999999) } + let(:fake_sonyci_records) { + { fake_sonyci_id: { 'id' => fake_sonyci_id, 'name' => 'foo' } } + } let(:admin_data_string_attributes) { { - "Sony's Ci ID" => "1a2b3c4d5e" + "Sony's Ci ID" => fake_sonyci_id } } + before do + # It's not apparent, but this is required to avoid errors. + # When the Sony Ci ID input is rendered, AdminData#sonyci_records is + # called. which calls SonyCiApi::Client#asset to fetch the records. + # NOTE: confusingly, the Sony Ci API refers to the records as 'assets'. + allow_any_instance_of(SonyCiApi::Client).to receive(:asset).with(fake_sonyci_id.to_s).and_return(fake_sonyci_records) + end + scenario 'Update AdminData on Asset' do Sipity::WorkflowAction.create!(name: 'submit', workflow: workflow) Hyrax::PermissionTemplateAccess.create!( diff --git a/spec/services/ams/media_download/media_download_service_spec.rb b/spec/services/ams/media_download/media_download_service_spec.rb index 5c792dc46..69589629e 100644 --- a/spec/services/ams/media_download/media_download_service_spec.rb +++ b/spec/services/ams/media_download/media_download_service_spec.rb @@ -5,10 +5,19 @@ let(:admin_data) { create(:admin_data, :one_sony_ci_id) } let(:asset) { create(:asset, with_admin_data: admin_data.gid) } - let(:fake_sony_ci_url) { "https://fake_sony_ci_url/cifiles/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/cpb-aacip-15-hd7np1wp4c__barcode163700_.h264.mp4?response-content-disposition=attachment%3bfilename%3d%22cpb-aacip-15-hd7np1wp4c__barcode163700_.h264.mp4"} + # Pared down response from Sony Ci. For this spec, we just really need the + # 'id' and 'location'. + let(:fake_sony_ci_api_result) { + { + 'id' => sonyci_id, + 'location' => "https://fake_sony_ci_url/cifiles/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/cpb-aacip-15-hd7np1wp4c__barcode163700_.h264.mp4?response-content-disposition=attachment%3bfilename%3d%22cpb-aacip-15-hd7np1wp4c__barcode163700_.h264.mp4" + } + } + # let(:fake_sony_ci_url) { "https://fake_sony_ci_url/cifiles/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/cpb-aacip-15-hd7np1wp4c__barcode163700_.h264.mp4?response-content-disposition=attachment%3bfilename%3d%22cpb-aacip-15-hd7np1wp4c__barcode163700_.h264.mp4"} let(:spec_media_file_path) { File.join(Rails.root, 'spec', 'fixtures', 'cpb-aacip-15-hd7np1wp4c__barcode163700_.h264.mp4' ) } - let(:fake_sony_ci_api) { instance_double("SonyCiBasic") } + let(:fake_sony_ci_api) { instance_double(SonyCiApi::Client) } let(:solr_doc) { SolrDocument.new(asset.to_solr) } + let(:sonyci_id) { solr_doc['sonyci_id_ssim'].first } let(:service) do described_class.new(solr_document: solr_doc) @@ -17,7 +26,7 @@ before do allow(service).to receive(:ci).and_return(fake_sony_ci_api) allow(service).to receive(:generate_sonyci_file_path).with('cpb-aacip-15-hd7np1wp4c__barcode163700_.h264.mp4').and_return(spec_media_file_path) - allow(service).to receive(:download_media_file).with(spec_media_file_path, fake_sony_ci_url) + allow(service).to receive(:download_media_file).with(spec_media_file_path, fake_sony_ci_api_result['location']) allow(service).to receive(:delete_media_files) end @@ -25,7 +34,7 @@ context "with a single Sony Ci ID" do context "during a successful download" do before do - allow(fake_sony_ci_api).to receive(:download).with(/Sony-\d{1}/).and_return(fake_sony_ci_url) + allow(fake_sony_ci_api).to receive(:asset_download).with(/Sony-\d{1}/).and_return(fake_sony_ci_api_result) end it "returns the expected Success object" do @@ -39,7 +48,7 @@ context "during an unsuccessful download" do before do - allow(fake_sony_ci_api).to receive(:download).with(/Sony-\d{1}/).and_raise(RuntimeError.new("NO VIDEO!!!")) + allow(fake_sony_ci_api).to receive(:asset_download).with(sonyci_id).and_raise(RuntimeError.new("NO VIDEO!!!")) end it "returns the expected Failure object" do