diff --git a/.gitignore b/.gitignore
index 79593f013..f83837939 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,9 @@
# Ignore bundler config.
/.bundle
+# Ignore package-lock.json
+package-lock.json
+
# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal
diff --git a/Gemfile b/Gemfile
index f7b917df1..ecbe52f2f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -59,6 +59,8 @@ gem 'kaminari'
gem 'momentjs-rails' # js lib for dates
gem 'pundit'
+gem 'nokogiri-diff', '~> 0.2.0' # for comparing xml documents
+
gem 'activerecord-import' # bulk insertion of data
gem 'activerecord-session_store'
@@ -78,7 +80,7 @@ gem 'browser'
# bundle config local.cmr_metadata_preview /path/to/local/git/repository
# make sure to delete the local config when done making changes to merge into master
# bundle config --delete local.cmr_metadata_preview
-gem 'cmr_metadata_preview', git: 'https://git.earthdata.nasa.gov/scm/cmr/cmr_metadata_preview.git', ref: 'fff65949cc6'
+gem 'cmr_metadata_preview', git: 'https://git.earthdata.nasa.gov/scm/cmr/cmr_metadata_preview.git', ref: '1f6ffd54d65'
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
diff --git a/Gemfile.lock b/Gemfile.lock
index 61ce28ff4..1626e7064 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,9 +1,9 @@
GIT
remote: https://git.earthdata.nasa.gov/scm/cmr/cmr_metadata_preview.git
- revision: fff65949cc62d397b0675e9fe46e962b8cf43228
- ref: fff65949cc6
+ revision: 1f6ffd54d6570f9f920078a84fd51750db3c21ab
+ ref: 1f6ffd54d65
specs:
- cmr_metadata_preview (0.2.2)
+ cmr_metadata_preview (0.2.3)
georuby
rails (~> 5.2.0)
sprockets (< 4.0)
@@ -195,6 +195,9 @@ GEM
nio4r (2.5.2)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
+ nokogiri-diff (0.2.0)
+ nokogiri (~> 1.5)
+ tdiff (~> 0.3, >= 0.3.2)
parallel (1.19.1)
parser (2.7.1.2)
ast (~> 2.4.0)
@@ -297,6 +300,7 @@ GEM
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.4.2)
+ tdiff (0.3.4)
thor (1.0.1)
thread_safe (0.3.6)
tilt (2.0.10)
@@ -365,6 +369,7 @@ DEPENDENCIES
mini_racer
momentjs-rails
multi_xml
+ nokogiri-diff (~> 0.2.0)
pg
pundit
rack_session_access
diff --git a/app/assets/javascripts/change_current_provider.coffee b/app/assets/javascripts/change_current_provider.coffee
index 540b4124c..54255c96e 100644
--- a/app/assets/javascripts/change_current_provider.coffee
+++ b/app/assets/javascripts/change_current_provider.coffee
@@ -74,6 +74,16 @@ $(document).ready ->
"Managing this service's collection associations"
when 'edit-tool'
'Editing this tool'
+ when 'clone-tool'
+ 'Cloning this tool'
+ when 'delete-tool'
+ 'Deleting this tool'
+ when 'reinstate-tool'
+ action = 'revert'
+ 'Reinstating this tool'
+ when 'revert-tool'
+ action = 'revert'
+ 'Reverting this tool'
$link.data('type', action)
$modal.find('span.provider').text(provider)
diff --git a/app/concerns/cmr_collections_helper.rb b/app/concerns/cmr_collections_helper.rb
index f7ea2ad96..4e8502eec 100644
--- a/app/concerns/cmr_collections_helper.rb
+++ b/app/concerns/cmr_collections_helper.rb
@@ -6,7 +6,7 @@ def get_revisions(concept_id, revision_id)
# try again because CMR might be a little slow to index if it is a newly published revision
attempts = 0
while attempts < 20
- revisions_response = cmr_client.get_collections({ concept_id: concept_id, all_revisions: true, include_granule_counts: true }, token)
+ revisions_response = cmr_client.get_collections({ concept_id: concept_id, all_revisions: true, include_granule_counts: true, sort_key: '-revision_date' }, token)
revisions = if revisions_response.success?
revisions_response.body.fetch('items', [])
else
diff --git a/app/controllers/manage_metadata_controller.rb b/app/controllers/manage_metadata_controller.rb
index a7d98f700..cdb465b8a 100644
--- a/app/controllers/manage_metadata_controller.rb
+++ b/app/controllers/manage_metadata_controller.rb
@@ -110,7 +110,7 @@ def set_variable_information
# if the variable is not found, try again because CMR might be a little slow to index if it is a newly published record
attempts = 0
while attempts < 20
- variables_search_response = cmr_client.get_variables(concept_id: @concept_id, all_revisions: true)
+ variables_search_response = cmr_client.get_variables(concept_id: @concept_id, all_revisions: true, sort_key: '-revision_date')
variable_data = if variables_search_response.success?
variables_search_response.body.fetch('items', [])
@@ -163,7 +163,7 @@ def set_service_information
# if the service is not found, try again because CMR might be a little slow to index if it is a newly published record
attempts = 0
while attempts < 20
- services_search_response = cmr_client.get_services(concept_id: @concept_id, all_revisions: true)
+ services_search_response = cmr_client.get_services(concept_id: @concept_id, all_revisions: true, sort_key: '-revision_date')
service_data = if services_search_response.success?
services_search_response.body.fetch('items', [])
@@ -218,7 +218,7 @@ def set_tool_information
# if the tool is not found, try again because CMR might be a little slow to index if it is a newly published record
attempts = 0
while attempts < 20
- tools_search_response = cmr_client.get_tools(concept_id: @concept_id, all_revisions: true)
+ tools_search_response = cmr_client.get_tools(concept_id: @concept_id, all_revisions: true, sort_key: '-revision_date')
tool_data = if tools_search_response.success?
tools_search_response.body.fetch('items', [])
diff --git a/app/controllers/tools_controller.rb b/app/controllers/tools_controller.rb
index acfdbda29..450fd0a80 100644
--- a/app/controllers/tools_controller.rb
+++ b/app/controllers/tools_controller.rb
@@ -2,10 +2,10 @@
class ToolsController < BasePublishedRecordController
include ManageMetadataHelper
- before_action :set_tool, only: [:show, :edit] #, :clone, :destroy, :revisions, :revert, :download_json]
- before_action :set_schema, only: [:show, :edit] #, :clone, :destroy]
+ before_action :set_tool, only: [:show, :edit, :clone, :destroy, :revisions, :revert, :download_json]
+ before_action :set_schema, only: [:show, :edit, :clone, :destroy]
before_action :ensure_supported_version, only: [:show, :edit]
- before_action :ensure_correct_provider, only: [:edit] #, :clone, :destroy]
+ before_action :ensure_correct_provider, only: [:edit, :clone, :destroy]
before_action :set_preview, only: [:show]
# If clone is not defined like this performing the clone action leads to a `action not found error`
diff --git a/app/helpers/manage_metadata_helper.rb b/app/helpers/manage_metadata_helper.rb
index 43f752208..c420b2c47 100644
--- a/app/helpers/manage_metadata_helper.rb
+++ b/app/helpers/manage_metadata_helper.rb
@@ -80,7 +80,7 @@ def resource_type
end
def display_header_subtitle(metadata, type)
- return unless type.downcase.include?('variable') || type.downcase.include?('service')
+ return unless ['variable', 'service', 'tool'].any? { |type_fragment| type.downcase.include?(type_fragment) }
metadata['LongName'] || 'Long Name Not Provided'
end
diff --git a/app/helpers/tools_helper.rb b/app/helpers/tools_helper.rb
new file mode 100644
index 000000000..19a5d5e6c
--- /dev/null
+++ b/app/helpers/tools_helper.rb
@@ -0,0 +1,12 @@
+module ToolsHelper
+ def render_change_provider_tool_action_link(tool_action, concept_id, revision_id = nil)
+ case tool_action
+ when 'edit'
+ link_to('Edit Service', edit_tool_path(concept_id, revision_id: revision_id), class: 'is-invisible', id: 'change-provider-tool-edit')
+ when 'clone'
+ link_to('Clone Service', clone_tool_path(concept_id, revision_id: revision_id), class: 'is-invisible', id: 'change-provider-tool-clone')
+ when 'delete'
+ link_to('Delete Service', tool_path(concept_id), method: :delete, class: 'is-invisible', id: 'change-provider-tool-delete')
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/models/tool_draft.rb b/app/models/tool_draft.rb
index 7695bc77f..a5282947c 100644
--- a/app/models/tool_draft.rb
+++ b/app/models/tool_draft.rb
@@ -15,11 +15,11 @@ def create_from_tool(tool, user, native_id)
draft = self.find_or_initialize_by(native_id: native_id)
draft.entry_title = tool['LongName']
draft.short_name = tool['Name']
- # else
- # # Cloned Record
- # draft = self.new
- # tool.delete('Name')
- # tool.delete('LongName')
+ else
+ # Cloned Record
+ draft = self.new
+ tool.delete('Name')
+ tool.delete('LongName')
end
draft.set_user_and_provider(user)
diff --git a/app/views/shared/_not_current_provider_modal.html.erb b/app/views/shared/_not_current_provider_modal.html.erb
index 3843bc179..5f71b9558 100644
--- a/app/views/shared/_not_current_provider_modal.html.erb
+++ b/app/views/shared/_not_current_provider_modal.html.erb
@@ -14,6 +14,8 @@
<%= link_to 'Yes', revert_variable_path(options[:concept_id], revision_id: options[:revision_id]), class: 'eui-btn--blue spinner is-invisible', id: "not-current-provider-revert-link#{'-' + modal_index.to_s if modal_index}" %>
<% elsif options[:service] %>
<%= link_to 'Yes', revert_service_path(options[:concept_id], revision_id: options[:revision_id]), class: 'eui-btn--blue spinner is-invisible', id: "not-current-provider-revert-link#{'-' + modal_index.to_s if modal_index}" %>
+ <% elsif options[:tool] %>
+ <%= link_to 'Yes', revert_tool_path(options[:concept_id], revision_id: options[:revision_id]), class: 'eui-btn--blue spinner is-invisible', id: "not-current-provider-revert-link#{'-' + modal_index.to_s if modal_index}" %>
<% else %>
<%= link_to 'Yes', revert_collection_path(options[:concept_id], revision_id: options[:revision_id]), class: 'eui-btn--blue spinner is-invisible', id: 'not-current-provider-revert-link' %>
<% end %>
@@ -33,8 +35,8 @@
<%= link_to 'Yes', service_collection_associations_path(options[:concept_id]), class: 'eui-btn--blue spinner is-invisible', id: 'not-current-provider-manage-service-associations-link' %>
<% elsif options[:tool] %>
<%= link_to 'Yes', edit_tool_path(options[:concept_id], revision_id: options[:revision_id]), class: 'eui-btn--blue spinner is-invisible', id: 'not-current-provider-edit-tool-link' %>
- <%#= link_to 'Yes', clone_tool_path(options[:concept_id], revision_id: options[:revision_id]), class: 'eui-btn--blue spinner is-invisible', id: 'not-current-provider-clone-tool-link' %>
- <%#= link_to 'Yes', tool_path(options[:concept_id]), method: :delete, class: 'eui-btn--blue spinner is-invisible', id: 'not-current-provider-delete-tool-link' %>
+ <%= link_to 'Yes', clone_tool_path(options[:concept_id], revision_id: options[:revision_id]), class: 'eui-btn--blue spinner is-invisible', id: 'not-current-provider-clone-tool-link' %>
+ <%= link_to 'Yes', tool_path(options[:concept_id]), method: :delete, class: 'eui-btn--blue spinner is-invisible', id: 'not-current-provider-delete-tool-link' %>
<% end %>
<% if options[:draft] %>
diff --git a/app/views/tools/revisions.html.erb b/app/views/tools/revisions.html.erb
new file mode 100644
index 000000000..8a861ac4c
--- /dev/null
+++ b/app/views/tools/revisions.html.erb
@@ -0,0 +1,115 @@
+<% content_for :header_title do %>
+
<%= fetch_entry_id(@tool, 'tools') %>
+ <%= display_header_subtitle(@tool, 'tool') %>
+<% end %>
+
+<% if @errors && !@errors.empty? %>
+
+
+
+
+ <% @errors.each do |error| %>
+ -
+ <%= "#{error[:field]}, " if error[:field] %>
+ <%= error[:error] %>
+ <% if error[:request_id] %>
+ Click here to submit feedback
+ <% end %>
+
+ <% end %>
+
+
+
+
+<% end %>
+
+
+
+ <% if @error %>
+
+
+
+ This tool could not be updated. You may <%= link_to 'edit', edit_tool_path(revision_id: @revision_id) %> the tool to resolve these issues.
+
+
+
+ <% end %>
+
+
diff --git a/app/views/tools/show.html.erb b/app/views/tools/show.html.erb
index 9cf647aed..19d7fa998 100644
--- a/app/views/tools/show.html.erb
+++ b/app/views/tools/show.html.erb
@@ -23,9 +23,7 @@
"#", id: "change-current-provider-banner-link",
data: { "provider": @provider_id, action_link: "change-provider-tool-#{@record_action}" }) %>
- <%# TODO: this method does not exist yet. It should be created and used when %>
- <%# additional actions are added to published Tool records %>
- <%#= render_change_provider_tool_action_link(@record_action, @concept_id, @revision_id) %>
+ <%= render_change_provider_tool_action_link(@record_action, @concept_id, @revision_id) %>
<% end %>
@@ -94,34 +92,29 @@
<% end %>
<% end %>
- <%# TODO: All links commented out and disabled links added for MMT-2238 %>
- <%# links should be re-enabled with the appropriate ticket %>
- <%= link_to 'Clone Tool Record', '#', class: 'eui-btn--link bar-after disabled' %>
- <%# if current_provider?(@provider_id) %>
- <%#= link_to 'Clone Tool Record', clone_tool_path(revision_id: @revision_id), class: 'eui-btn--link bar-after' %>
- <%# elsif available_provider?(@provider_id) %>
- <%#= link_to 'Clone Tool Record', '#not-current-provider-modal', class: 'display-modal not-current-provider eui-btn--link bar-after', data: { 'provider': @provider_id, record_action: 'clone-tool' } %>
- <%# end %>
+ <% if current_provider?(@provider_id) %>
+ <%= link_to 'Clone Tool Record', clone_tool_path(revision_id: @revision_id), class: 'eui-btn--link bar-after' %>
+ <% elsif available_provider?(@provider_id) %>
+ <%= link_to 'Clone Tool Record', '#not-current-provider-modal', class: 'display-modal not-current-provider eui-btn--link bar-after', data: { 'provider': @provider_id, record_action: 'clone-tool' } %>
+ <% end %>
- <%= link_to 'Download JSON', '#', class: 'eui-btn--link disabled' %>
- <%#= link_to 'Download JSON', download_json_tool_path(@concept_id, revision_id: @revision_id), class: 'eui-btn--link', target: '_blank' %>
+ <%= link_to 'Download JSON', download_json_tool_path(@concept_id, revision_id: @revision_id), class: 'eui-btn--link', target: '_blank' %>
- <%= link_to 'Delete Tool Record', '#', class: 'display-modal delete-tool eui-btn--link bar-before disabled' %>
- <%# if current_provider?(@provider_id) %>
- <%#= link_to 'Delete Tool Record', "#delete-record-modal", class: 'display-modal delete-tool eui-btn--link bar-before' %>
- <%# elsif available_provider?(@provider_id) %>
- <%#= link_to 'Delete Tool Record', '#not-current-provider-modal', class: 'display-modal not-current-provider eui-btn--link bar-before', data: { 'provider': @provider_id, record_action: 'delete-tool', num_associated_collections: "#{@num_associated_collections}" } %>
- <%# end %>
+ <% if current_provider?(@provider_id) %>
+ <%= link_to 'Delete Tool Record', "#delete-record-modal", class: 'display-modal delete-tool eui-btn--link bar-before' %>
+ <% elsif available_provider?(@provider_id) %>
+ <%= link_to 'Delete Tool Record', '#not-current-provider-modal', class: 'display-modal not-current-provider eui-btn--link bar-before', data: { 'provider': @provider_id, record_action: 'delete-tool' } %>
+ <% end %>
-
+
<%= render partial: 'shared/not_current_provider_modal', locals: {
options: {
tool: @tool,
@@ -133,8 +126,7 @@
} %>
- <%= link_to 'Revisions', '#', class: 'eui-btn--link disabled' %>
- <%#= link_to "Revisions (#{@revisions.size})", tool_revisions_path, class: 'eui-btn--link disabled' %>
+ <%= link_to "Revisions (#{@revisions.size})", tool_revisions_path, class: 'eui-btn--link' %>
diff --git a/config/environments/production.rb b/config/environments/production.rb
index dc5511069..662e251d8 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -135,7 +135,7 @@
config.subscriptions_enabled = true
# Feature toggle for UMM-T
- config.umm_t_enabled = false
+ config.umm_t_enabled = true
config.cmr_env = 'ops'
config.echo_env = 'ops'
diff --git a/config/environments/uat.rb b/config/environments/uat.rb
index 009094283..43a54ba41 100644
--- a/config/environments/uat.rb
+++ b/config/environments/uat.rb
@@ -115,7 +115,7 @@
config.csplog_enabled = false
# Feature toggle for UMM-T
- config.umm_t_enabled = false
+ config.umm_t_enabled = true
config.cmr_env = 'uat'
config.echo_env = 'uat'
diff --git a/config/locales/en.yml b/config/locales/en.yml
index bf9d5b6cb..3201d3cf6 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -198,6 +198,17 @@ en:
flash:
success: 'Tool Draft Published Successfully!'
error: 'Tool Draft was not published successfully'
+ destroy:
+ flash:
+ success: 'Tool Deleted Successfully!'
+ error: 'Tool was not deleted successfully'
+ clone:
+ flash:
+ notice: 'Records must have a unique Name and Long Name within a provider. Click here to enter a new Name and Long Name.'
+ revert:
+ flash:
+ success: 'Tool Revision Created Successfully!'
+ error: 'Tool revision was not created successfully'
collection_associations:
destroy:
flash:
diff --git a/config/routes.rb b/config/routes.rb
index 4b61880ee..2ae58ed56 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -103,7 +103,11 @@
get '/services/:id/clone' => 'services#clone', as: 'clone_service'
get '/services/:id/download_json(/:revision_id)' => 'services#download_json', as: 'download_json_service'
- resources :tools, only: [:show, :create, :edit]
+ resources :tools, only: [:show, :create, :edit, :destroy]
+ get '/tools/:id/clone' => 'tools#clone', as: 'clone_tool'
+ get '/tools/:id/revisions' => 'tools#revisions', as: 'tool_revisions'
+ get '/tools/:id/download_json(/:revision_id)' => 'tools#download_json', as: 'download_json_tool'
+ get '/tools/:id/revert/:revision_id' => 'tools#revert', as: 'revert_tool'
resources :variable_drafts, controller: 'variable_drafts', draft_type: 'VariableDraft' do
member do
diff --git a/lib/tasks/compare_xml_collections.rake b/lib/tasks/compare_xml_collections.rake
new file mode 100644
index 000000000..6e9e99898
--- /dev/null
+++ b/lib/tasks/compare_xml_collections.rake
@@ -0,0 +1,155 @@
+require 'libxml_to_hash'
+
+namespace :collection do
+ desc 'Translate a collection from native format to UMM JSON and back to native format'
+ task :loss, [:file, :format, :disp, :version] => :environment do |_task, args|
+ args.with_defaults(:version => '1.15.3')
+ args.with_defaults(:disp => 'show')
+
+ abort 'FORMAT INVALID' unless args.format == 'echo10' || args.format == 'dif10' || args.format == 'iso19115'
+
+ filename = args.file.split('/')[-1]
+ puts "\nTranslating #{filename} to UMM JSON..."
+
+ native_original_xml = File.read(args.file)
+ native_original_hash = Hash.from_xml(native_original_xml)
+
+ #translate to UMM
+ umm_response = cmr_client.translate_collection(native_original_xml, "application/#{args.format}+xml", "application/vnd.nasa.cmr.umm+json;version=#{args.version}", skip_validation=true )
+ umm_response.success? ? puts("\nsuccessful translation to UMM") : abort("\nUMM translation failure")
+ umm_json = umm_response.body.to_json
+
+ # translate back to native
+ back_to_native = cmr_client.translate_collection(umm_json, "application/vnd.nasa.cmr.umm+json;version=#{args.version}", "application/#{args.format}+xml", skip_validation=true )
+ back_to_native.success? ? puts("successful translation to native format \n\n") : abort("Native format translation failure \n\n")
+ native_converted_hash = Hash.from_xml(back_to_native.body)
+ native_converted_xml = back_to_native.body
+
+ if args.format == 'dif10'
+ nokogiri_original = Nokogiri::XML(native_original_xml) { |config| config.strict.noblanks } .remove_namespaces!
+ nokogiri_converted = Nokogiri::XML(native_converted_xml) { |config| config.strict.noblanks } .remove_namespaces!
+ else
+ nokogiri_original = Nokogiri::XML(native_original_xml) { |config| config.strict.noblanks }
+ nokogiri_converted = Nokogiri::XML(native_converted_xml) { |config| config.strict.noblanks }
+ end
+
+ ignored_paths = Array.new
+
+ nokogiri_original.diff(nokogiri_converted, {:added => true, :removed => true}) do |change,node|
+ split_path = node.parent.path.split('[')
+ if node.parent.path.include?('[') && !ignored_paths.include?(split_path[0])
+ ignored_paths << split_path[0]
+ array_comparison(split_path[0], native_original_hash, native_converted_hash).each do |item|
+ puts("#{item[0]}: #{item[1]}".ljust(60) + item[2]) if args.disp == 'show'
+ puts("#{item[0]}: " + item[2]) if args.disp == 'hide'
+ end
+ elsif !ignored_paths.include?(split_path[0]) && !path_leads_to_list?(node.parent.path, native_original_hash, native_converted_hash)
+ if is_xml?(node)
+ element = Hash.from_xml(node.to_xml)
+ hash_map(element).each do |item|
+ puts("#{change}: #{item['value']}".ljust(60) + node.parent.path+'/'+item['path']) if args.disp == 'show'
+ puts("#{change}: " + node.parent.path+'/'+item['path']) if args.disp == 'hide'
+ end
+ else
+ puts("#{change}: #{node.to_xml}".ljust(60) + node.parent.path) if args.disp == 'show'
+ puts("#{change}: " + node.parent.path) if args.disp == 'hide'
+ end
+ end
+ end
+ end
+
+ def path_leads_to_list?(path, org_hash, conv_hash)
+ # this method takes a path string (and the full original and converted hashes) and outputs true if the path string contains a list; else false
+ org_hash = hash_navigation(path, org_hash)
+ conv_hash = hash_navigation(path, conv_hash)
+
+ if path.include?("[") && path.include?("]")
+ bool = true
+ elsif org_hash.is_a?(Hash) && conv_hash.is_a?(Hash)
+ # the number of keys must be 1 because all arrays in echo10, dif10, and iso19115 are tagged similar to:
+ # contact and so all array-containing tags will be the plural
+ # of the array name. This clause serves to identify array-containing tags when their paths aren't properly
+ # displayed by nokogiri
+ bool = true if org_hash.keys.length == 1 && org_hash[org_hash.keys[0]].is_a?(Array)
+ bool = true if conv_hash.keys.length == 1 && conv_hash[conv_hash.keys[0]].is_a?(Array)
+ elsif org_hash.is_a?(Array) || conv_hash.is_a?(Array)
+ bool = true
+ else
+ bool = false
+ end
+ bool
+ end
+
+ def is_xml?(node)
+ if node.to_xml.include?('<' && '' && '>') then return true
+ else return false end
+ end
+
+ def hash_navigation(path, hash)
+ # Passed a path string and the hash being navigated. This method parses the path string and
+ # returns the array/value at the end of the path
+ path.split('/').each do |key|
+ if hash.is_a?(Array)
+ return hash
+ elsif hash.key?(key) && hash.is_a?(Hash)
+ hash = hash[key]
+ end
+ end
+ hash
+ end
+
+ def hash_map(hash)
+ buckets = Array.new
+ hash.each do |key,val|
+ if val.is_a? Hash
+ hash_map(val).each do |item|
+ item['path'] = key + '/' + item['path']
+ buckets << item
+ end
+ else
+ buckets << {'path'=> key, 'value'=> val}
+ end
+ end
+ buckets
+ end
+
+ def array_comparison(path, original_hash, converted_hash)
+
+ pre_translation_array = hash_navigation(path, original_hash)
+ post_translation_array = hash_navigation(path, converted_hash)
+
+ # in the case that a one-item array is parsed as a regular key-value pair instead of an array, an Array wrapper is placed around key-val pair
+ # so that the following for loops can be executed without error
+ pre_translation_array.is_a?(Array) ? lost_items_arr = pre_translation_array.clone : lost_items_arr = Array.wrap(pre_translation_array)
+ pre_translation_array = Array.wrap(pre_translation_array)
+ post_translation_array.is_a?(Array) ? added_itmes_arr = post_translation_array.clone : added_itmes_arr = Array.wrap(post_translation_array)
+ post_translation_array = Array.wrap(post_translation_array)
+
+ # as defined above, the lost_items_arr and added_itmes_arr are copies of pre_translation_array and post_translation_array, respectively.
+ # The *_arr values are edited during the comparison between the pre_translation_array and post_translation_array arrays
+ # and so the *_array arrays are used to maintain a full version of each array for indexing the items in the following lines.
+
+ for conv_item in post_translation_array
+ for org_item in pre_translation_array
+ if org_item == conv_item
+ lost_items_arr.delete(org_item)
+ added_itmes_arr.delete(conv_item)
+ break
+ end
+ end
+ end
+
+ output = Array.new
+ lost_items_arr.each do |item|
+ path_with_index = path + "[#{pre_translation_array.index(item)}]"
+ output << ['-', item, path_with_index]
+ end
+
+
+ added_itmes_arr.each do |item|
+ path_with_index = path + "[#{post_translation_array.index(item)}]"
+ output << ['+', item, path_with_index]
+ end
+ output
+ end
+end
diff --git a/lib/tasks/local_cmr.rake b/lib/tasks/local_cmr.rake
index 4e5689b9b..252fc0fc8 100644
--- a/lib/tasks/local_cmr.rake
+++ b/lib/tasks/local_cmr.rake
@@ -11,8 +11,8 @@ namespace :cmr do
# use puts %x() to run commands and not Process.spawn(), which returns
# imediatly, because curl can take a while and we want to see the output
# from standard out.
-
- # make a backup copy of the old jar if it exists, and a backup of the backup
+
+ # make a backup copy of the old jar if it exists, and a backup of the backup
cmd_backup = 'cd cmr ; '\
"if [ -a \"#{jar_name}\" ] ; then "\
'echo Backup jar... ; '\
@@ -20,7 +20,7 @@ namespace :cmr do
"mv -fv #{jar_name} #{jar_name}.last ; "\
'fi'
puts %x( #{cmd_backup} )
-
+
# download a new jar to a temp location and rename it if successfull
puts 'Download jar...'
cmd_fetch = 'cd cmr ; '\
@@ -153,11 +153,11 @@ namespace :cmr do
File.join(Rails.root.to_s, 'vendor', 'assets', 'javascripts', 'eui-1.0.0', 'eui.js')
]
- # TODO: move to version 3 of jquery
- # it is not currently understood how this section works to select jquery
- # currently the preview gem is not running with version 3, but 1
+ # Find the path to jquery
jquery = Rails.application.config.assets.paths.select { |p| p.to_s.include?('jquery-rails') }
- dependencies.unshift(File.join(jquery.first, 'jquery.js')) if jquery.any?
+ # Include a specific file. jquery-rails has files for each major version
+ # stored in the above location
+ dependencies.unshift(File.join(jquery.first, 'jquery3.js')) if jquery.any?
js_to_uglify = dependencies.sort.map do |file|
puts "- Reading #{file}"
@@ -247,4 +247,4 @@ namespace :cmr do
puts "Done!"
end
end
-end
\ No newline at end of file
+end
diff --git a/spec/features/collection_drafts/forms/data_centers_form_spec.rb b/spec/features/collection_drafts/forms/data_centers_form_spec.rb
index 1d41ce3a5..00082826e 100644
--- a/spec/features/collection_drafts/forms/data_centers_form_spec.rb
+++ b/spec/features/collection_drafts/forms/data_centers_form_spec.rb
@@ -27,7 +27,7 @@
within '#draft_data_centers_1' do
select 'Originator', from: 'Role'
- add_data_center('ESA/ED')
+ add_data_center_with_retry('ESA/ED')
add_contact_information(type: 'data_center', single: false, button_type: 'Data Center')
end
diff --git a/spec/features/collection_drafts/forms/saving_data_centers_data_contacts_spec.rb b/spec/features/collection_drafts/forms/saving_data_centers_data_contacts_spec.rb
index 6a31955e2..5fa7a27f0 100644
--- a/spec/features/collection_drafts/forms/saving_data_centers_data_contacts_spec.rb
+++ b/spec/features/collection_drafts/forms/saving_data_centers_data_contacts_spec.rb
@@ -66,7 +66,7 @@
within '.multiple.data-centers > .multiple-item-1' do
select 'Originator', from: 'Role'
- add_data_center('ESA/ED')
+ add_data_center_with_retry('ESA/ED')
end
within '.nav-top' do
diff --git a/spec/features/collection_drafts/forms/validation_spec.rb b/spec/features/collection_drafts/forms/validation_spec.rb
index ac0c80194..800af7f4f 100644
--- a/spec/features/collection_drafts/forms/validation_spec.rb
+++ b/spec/features/collection_drafts/forms/validation_spec.rb
@@ -290,6 +290,12 @@
fill_in 'draft_temporal_extents_0_single_date_times_0', with: '2015-07-01T00:00:00Z'
end
+ # Bamboo spontaneously started failling this test with the apparent
+ # cause being that 'done' was not being clicked. Clicking something
+ # outside of the datepicker widget allows the done click to be
+ # processed correctly. Previously, it looks like the click for done
+ # was only exiting the single date time field.
+ find('#draft_temporal_extents_0_precision_of_seconds').click
within '.nav-top' do
click_on 'Done'
end
diff --git a/spec/features/collections/downloading_xml_spec.rb b/spec/features/collections/downloading_xml_spec.rb
index 81ed7e69b..60107c477 100644
--- a/spec/features/collections/downloading_xml_spec.rb
+++ b/spec/features/collections/downloading_xml_spec.rb
@@ -26,16 +26,17 @@
before do
@file = "#{Rails.root}/#{@concept_id}.echo10"
click_on 'ECHO 10'
- end
- after do
# Seems to need a brief (>0.01) pause to actually find the file.
sleep(0.1)
+ end
+
+ after do
FileUtils.rm @file if File.exist?(@file)
end
it 'downloads the file' do
- expect(File.exist?(@file))
+ expect(File.exist?(@file)).to eq(true)
end
end
end
@@ -45,7 +46,7 @@
before do
login
visit manage_collections_path
-
+
short_name = 'SPL4SMAU'
fill_in 'keyword', with: short_name
click_on 'Search Collections'
@@ -76,16 +77,17 @@
before do
@file = "#{Rails.root}/#{@concept_id}.iso-smap"
click_on 'ISO 19115 (SMAP) (Native)'
- end
- after do
# Seems to need a brief (>0.01) pause to actually find the file.
sleep(0.1)
+ end
+
+ after do
FileUtils.rm @file if File.exist?(@file)
end
it 'downloads the file' do
- expect(File.exist?(@file))
+ expect(File.exist?(@file)).to eq(true)
end
end
end
diff --git a/spec/features/collections/revision_list_spec.rb b/spec/features/collections/revision_list_spec.rb
index 9d3c57bb9..60ba78a42 100644
--- a/spec/features/collections/revision_list_spec.rb
+++ b/spec/features/collections/revision_list_spec.rb
@@ -1,15 +1,19 @@
describe 'Revision list', js: true do
context 'when viewing a published collection' do
+ before :all do
+ native_id = 'collection_revision_native_id'
+ _ingest_response, _concept_response = publish_collection_draft(native_id: native_id, revision_count: 10, short_name: 'b_test_01')
+ @ingest_response, @concept_response = publish_collection_draft(native_id: native_id, short_name: 'c_test_01')
+ end
+
before do
login
- ingest_response, @concept_response = publish_collection_draft(revision_count: 2)
-
- visit collection_path(ingest_response['concept-id'])
+ visit collection_path(@ingest_response['concept-id'])
end
it 'displays the number of revisions' do
- expect(page).to have_content('Revisions (2)')
+ expect(page).to have_content('Revisions (10)')
end
context 'when clicking on the revision link' do
@@ -27,15 +31,15 @@
end
it 'displays when the revision was made' do
- expect(page).to have_content(today_string, count: 2)
+ expect(page).to have_content(today_string, count: 10)
end
it 'displays what user made the revision' do
- expect(page).to have_content('typical', count: 2)
+ expect(page).to have_content('typical', count: 10)
end
it 'displays the correct phrasing for reverting records' do
- expect(page).to have_content('Revert to this Revision', count: 1)
+ expect(page).to have_content('Revert to this Revision', count: 9)
end
context 'when viewing an old revision' do
diff --git a/spec/features/manage_cmr/subscriptions/delete_subscriptions_spec.rb b/spec/features/manage_cmr/subscriptions/delete_subscriptions_spec.rb
index 8c4f366fd..bb2599082 100644
--- a/spec/features/manage_cmr/subscriptions/delete_subscriptions_spec.rb
+++ b/spec/features/manage_cmr/subscriptions/delete_subscriptions_spec.rb
@@ -53,13 +53,28 @@
context 'when failing to delete a subscription' do
before do
- # Generate an error message by deleting it underneath the 'user'
- cmr_client.delete_subscription('MMT_2', @native_id, 'token')
click_on 'Delete'
- VCR.use_cassette('urs/rarxd5taqea', record: :none) do
+ # Using 'allow_any_instance_of' causes the after delete to fail as well.
+ # Need localhost to mock the CMR delete response to be an error.
+ VCR.configure do |c|
+ c.ignore_localhost = false
+ end
+
+ VCR.use_cassette('subscriptions/failed_delete', erb: { concept_id: @ingest_response['concept_id'] }) do
click_on 'Yes'
end
+
+ VCR.configure do |c|
+ c.ignore_localhost = true
+ end
+ end
+
+ # TODO: Remove after CMR-6332
+ after do
+ delete_response = cmr_client.delete_subscription('MMT_2', @native_id, 'token')
+
+ raise unless delete_response.success?
end
it 'fails to delete the record' do
diff --git a/spec/features/services/download_json_spec.rb b/spec/features/services/download_json_spec.rb
index 7f9f8bb42..52299efd0 100644
--- a/spec/features/services/download_json_spec.rb
+++ b/spec/features/services/download_json_spec.rb
@@ -13,5 +13,23 @@
it 'renders the download link' do
expect(page).to have_link('Download JSON', href: download_json_service_path(@ingest_response['concept-id']))
end
+
+ context 'when downloading the json' do
+ before do
+ @file = "#{Rails.root}/#{@ingest_response['concept-id']}.json"
+ click_on 'Download JSON'
+
+ # Seems to need a brief (>0.01) pause to actually find the file.
+ sleep(0.1)
+ end
+
+ after do
+ FileUtils.rm @file if File.exist?(@file)
+ end
+
+ it 'downloads the file' do
+ expect(File.exist?(@file)).to eq(true)
+ end
+ end
end
end
diff --git a/spec/features/services/reverting_service_spec.rb b/spec/features/services/reverting_service_spec.rb
index 5f0510878..d8024aa28 100644
--- a/spec/features/services/reverting_service_spec.rb
+++ b/spec/features/services/reverting_service_spec.rb
@@ -1,5 +1,3 @@
-require 'rails_helper'
-
describe 'Reverting to previous services', reset_provider: true, js: true do
before :all do
# service for simple reverting service test
diff --git a/spec/features/services/revision_list_spec.rb b/spec/features/services/revision_list_spec.rb
index 80a1a2c18..b560aad7f 100644
--- a/spec/features/services/revision_list_spec.rb
+++ b/spec/features/services/revision_list_spec.rb
@@ -1,17 +1,22 @@
-require 'rails_helper'
-
describe 'Service revision list', reset_provider: true, js: true do
context 'when viewing a published service' do
+ before :all do
+ # CMR does not return revisions sorted by revision_id. It sorts
+ # by name first (and maybe other things). If the sort_key is working
+ # correctly, the last revision (c_test_01), should be visible on the page
+ native_id = 'service_revision_native_id'
+ _ingest_response, _concept_response = publish_service_draft(native_id: native_id, revision_count: 10, name: 'b_test_01')
+ @ingest_response, @concept_response = publish_service_draft(native_id: native_id, name: 'c_test_01')
+ end
+
before do
login
- ingest_response, @concept_response = publish_service_draft(revision_count: 2)
-
- visit service_path(ingest_response['concept-id'])
+ visit service_path(@ingest_response['concept-id'])
end
it 'displays the number of revisions' do
- expect(page).to have_content('Revisions (2)')
+ expect(page).to have_content('Revisions (10)')
end
context 'when clicking on the revision link' do
@@ -29,15 +34,19 @@
end
it 'displays when the revision was made' do
- expect(page).to have_content(today_string, count: 2)
+ expect(page).to have_content(today_string, count: 10)
end
it 'displays what user made the revision' do
- expect(page).to have_content('typical', count: 2)
+ expect(page).to have_content('typical', count: 10)
+ end
+
+ it 'displays the most recent revisions' do
+ expect(page).to have_content('11 - Published')
end
it 'displays the correct phrasing for reverting records' do
- expect(page).to have_content('Revert to this Revision', count: 1)
+ expect(page).to have_content('Revert to this Revision', count: 9)
end
context 'when viewing an old revision' do
diff --git a/spec/features/tool_drafts/create_tool_draft_from_cloning_spec.rb b/spec/features/tool_drafts/create_tool_draft_from_cloning_spec.rb
new file mode 100644
index 000000000..76a02c85c
--- /dev/null
+++ b/spec/features/tool_drafts/create_tool_draft_from_cloning_spec.rb
@@ -0,0 +1,62 @@
+describe 'Creating a tool draft from cloning a tool', reset_provider: true, js: true do
+ before :all do
+ @ingest_response, _concept_response, @native_id = publish_tool_draft
+ end
+
+ after :all do
+ delete_response = cmr_client.delete_tool('MMT_2', @native_id, 'token')
+
+ raise unless delete_response.success?
+ end
+
+ context 'when cloning a published tool' do
+ before do
+ login
+
+ visit tool_path(@ingest_response['concept-id'])
+
+ click_on 'Clone Tool Record'
+ end
+
+ it 'displays the draft preview page' do
+ within '.eui-breadcrumbs' do
+ expect(page).to have_content('Tool Drafts')
+ end
+
+ expect(page).to have_content('Publish Tool Draft')
+ expect(page).to have_content('Delete Tool Draft')
+ expect(page).to have_content('Metadata Fields')
+ expect(page).to have_content('Tool Information')
+ end
+
+ it 'removes the Name and Long Name from the metadata' do
+ within '#tool_draft_draft_name_preview' do
+ expect(page).to have_css('p', text: 'No value for Name provided.')
+ end
+
+ within '#tool_draft_draft_long_name_preview' do
+ expect(page).to have_css('p', text: 'No value for Long Name provided.')
+ end
+ end
+
+ it 'creates a new native id for the draft' do
+ draft = ToolDraft.last
+ expect(draft.native_id).to eq("mmt_tool_#{draft.id}")
+ end
+
+ it 'displays a message that the draft needs a unique Name' do
+ expect(page).to have_content('Records must have a unique Name and Long Name within a provider. Click here to enter a new Name and Long Name.')
+ end
+
+ context 'when clicking the banner message to enter a new Name' do
+ before do
+ click_on 'Click here to enter a new Name and Long Name.'
+ end
+
+ it 'displays the empty Name and Long Name fields' do
+ expect(page).to have_field('Name', with: '')
+ expect(page).to have_field('Long Name', with: '')
+ end
+ end
+ end
+end
diff --git a/spec/features/tools/delete_tool_spec.rb b/spec/features/tools/delete_tool_spec.rb
new file mode 100644
index 000000000..d81a0bf79
--- /dev/null
+++ b/spec/features/tools/delete_tool_spec.rb
@@ -0,0 +1,95 @@
+describe 'Delete tool', reset_provider: true, js: true do
+ before :all do
+ @ingested_tool, _concept_response, _native_id_1 = publish_tool_draft
+
+ @ingested_tool_for_delete_messages, _concept_response, @native_id_2 = publish_tool_draft
+ end
+
+ # Remove this section after CMR-6332 is resolved
+ after :all do
+ delete_response = cmr_client.delete_tool('MMT_2', @native_id_2, 'token')
+ # First tool should be deleted in the delete test
+
+ raise unless delete_response.success?
+ end
+
+ before do
+ login
+ end
+
+ context 'when viewing a published tool' do
+ before do
+ visit tool_path(@ingested_tool['concept-id'])
+ end
+
+ it 'displays a delete link' do
+ expect(page).to have_content('Delete Tool Record')
+ end
+
+ context 'when clicking the delete link' do
+ before do
+ click_on 'Delete Tool Record'
+ end
+
+ it 'displays a confirmation modal' do
+ expect(page).to have_content('Are you sure you want to delete this tool record?')
+ end
+
+ context 'when clicking Yes' do
+ before do
+ within '#delete-record-modal' do
+ click_on 'Yes'
+ end
+ end
+
+ it 'redirects to the revisions page and displays a confirmation message' do
+ expect(page).to have_content('Revision History')
+
+ expect(page).to have_content('Tool Deleted Successfully!')
+ end
+ end
+ end
+ end
+
+ context 'when deleting the tool will fail' do
+ before do
+ visit tool_path(@ingested_tool_for_delete_messages['concept-id'])
+ end
+
+ context 'when CMR provides a message' do
+ before do
+ error_body = '{"errors": ["You do not have permission to perform that action."]}'
+ error_response = Cmr::Response.new(Faraday::Response.new(status: 401, body: JSON.parse(error_body), response_headers: {}))
+ allow_any_instance_of(Cmr::CmrClient).to receive(:delete_tool).and_return(error_response)
+
+ click_on 'Delete Tool Record'
+
+ within '#delete-record-modal' do
+ click_on 'Yes'
+ end
+ end
+
+ it 'displays the CMR error message' do
+ expect(page).to have_css('.eui-banner--danger', text: 'You do not have permission to perform that action.')
+ end
+ end
+
+ context 'when CMR does not provide a message' do
+ before do
+ error_body = '{"message": "useless message"}'
+ error_response = Cmr::Response.new(Faraday::Response.new(status: 401, body: JSON.parse(error_body), response_headers: {}))
+ allow_any_instance_of(Cmr::CmrClient).to receive(:delete_tool).and_return(error_response)
+
+ click_on 'Delete Tool Record'
+
+ within '#delete-record-modal' do
+ click_on 'Yes'
+ end
+ end
+
+ it 'displays the CMR error message' do
+ expect(page).to have_css('.eui-banner--danger', text: 'Tool was not deleted successfully')
+ end
+ end
+ end
+end
diff --git a/spec/features/tools/download_json_spec.rb b/spec/features/tools/download_json_spec.rb
new file mode 100644
index 000000000..b52ee6006
--- /dev/null
+++ b/spec/features/tools/download_json_spec.rb
@@ -0,0 +1,42 @@
+describe 'Downloading Tool JSON', js: true do
+ before :all do
+ @ingest_response, _concept_response, @native_id = publish_tool_draft
+ end
+
+ # TODO: remove after CMR-6332
+ after :all do
+ delete_response = cmr_client.delete_tool('MMT_2', @native_id, 'token')
+
+ raise unless delete_response.success?
+ end
+
+ context 'when viewing the tool preview page' do
+ before do
+ login
+
+ visit tool_path(@ingest_response['concept-id'])
+ end
+
+ it 'renders the download link' do
+ expect(page).to have_link('Download JSON', href: download_json_tool_path(@ingest_response['concept-id']))
+ end
+
+ context 'when downloading the json' do
+ before do
+ @file = "#{Rails.root}/#{@ingest_response['concept-id']}.json"
+ click_on 'Download JSON'
+
+ # Seems to need a brief (>0.01) pause to actually find the file.
+ sleep(0.1)
+ end
+
+ after do
+ FileUtils.rm @file if File.exist?(@file)
+ end
+
+ it 'downloads the file' do
+ expect(File.exist?(@file)).to eq(true)
+ end
+ end
+ end
+end
diff --git a/spec/features/tools/reverting_tool_spec.rb b/spec/features/tools/reverting_tool_spec.rb
new file mode 100644
index 000000000..a2ba6fa09
--- /dev/null
+++ b/spec/features/tools/reverting_tool_spec.rb
@@ -0,0 +1,169 @@
+describe 'Reverting to previous tools', reset_provider: true, js: true do
+ before :all do
+ # tool for simple reverting tool test
+ @simple_revert_ingest_response, @simple_revert_concept_response, @native_id = publish_tool_draft(revision_count: 2)
+
+ # tool for reverting tool with many revisions
+ @multiple_revisions_ingest_response, @multiple_revisions_concept_response, @native_id2 = publish_tool_draft(revision_count: 4, long_name: 'Reverting Tools Test', number_revision_long_names: true)
+ end
+
+ after :all do
+ delete_response = cmr_client.delete_tool('MMT_2', @native_id, 'token')
+ delete_response2 = cmr_client.delete_tool('MMT_2', @native_id2, 'token')
+
+ raise unless delete_response.success? && delete_response2.success?
+ end
+
+ before do
+ login
+ end
+
+ context 'when the latest revision is a published tool' do
+ before do
+ visit tool_path(@simple_revert_ingest_response['concept-id'])
+
+ click_on 'Revisions'
+ end
+
+ it 'displays the correct phrasing for reverting records' do
+ expect(page).to have_content('Revert to this Revision', count: 1)
+ end
+
+ context 'when reverting the tool' do
+ before do
+ click_on 'Revert to this Revision'
+ click_on 'Yes'
+
+ wait_for_jQuery
+ wait_for_cmr
+ end
+
+ it 'displays all the correct revision information' do
+ expect(page).to have_content('Revision Created Successfully!')
+
+ expect(page).to have_content('Published', count: 1)
+ expect(page).to have_content('Revision View', count: 2)
+ expect(page).to have_content('Revert to this Revision', count: 2)
+ end
+ end
+
+ context 'when reverting to a revision before the previous revision from a different provider context' do
+ context 'when visiting the revisions page from a different provider' do
+ before do
+ login(provider: 'MMT_1', providers: %w(MMT_1 MMT_2))
+
+ visit tool_revisions_path(@multiple_revisions_ingest_response['concept-id'])
+ end
+
+ it 'displays all the correct revision information' do
+ within 'main header' do
+ expect(page).to have_content('Reverting Tools Test -- revision 04')
+ end
+
+ expect(page).to have_content('Published', count: 1)
+ expect(page).to have_content('Revision View', count: 3)
+ expect(page).to have_content('Revert to this Revision', count: 3)
+ end
+
+ context 'when reverting to the earliest revision' do
+ before do
+ visit tool_revisions_path(@multiple_revisions_ingest_response['concept-id'])
+
+ within '#tool-revisions-table tbody tr:last-child' do
+ # make sure we are clicking on the correct link
+ expect(page).to have_content('1 - Revision')
+
+ click_on 'Revert to this Revision'
+ end
+ end
+
+ it 'displays a modal informing the user they need to switch providers' do
+ expect(page).to have_content('Reverting this tool requires you change your provider context to MMT_2')
+ end
+
+ context 'when clicking Yes' do
+ before do
+ find('.not-current-provider-link').click
+ wait_for_jQuery
+ end
+
+ it 'reverts the tool to the correct revision and displays the correct revision information and switches provider context' do
+ within 'main header' do
+ expect(page).to have_content('Reverting Tools Test -- revision 01')
+ end
+
+ expect(page).to have_content('Published', count: 1)
+ expect(page).to have_content('Revision View', count: 4)
+ expect(page).to have_content('Revert to this Revision', count: 4)
+
+ expect(User.first.provider_id).to eq('MMT_2')
+ end
+ end
+ end
+ end
+ end
+
+ context 'when reverting the tool fails ingestion into CMR' do
+ before do
+ # Do something to the revision so it fails
+ # Add a new field to the metadata, similar to a field name changing
+ # and old metadata still having the old field name
+ new_concept = @simple_revert_concept_response.deep_dup
+ new_concept.body['BadField'] = 'Not going to work'
+
+ allow_any_instance_of(Cmr::CmrClient).to receive(:get_concept).and_return(new_concept)
+
+ click_on 'Revert to this Revision', match: :first
+ click_on 'Yes'
+
+ wait_for_jQuery
+ wait_for_cmr
+ end
+
+ it 'displays an error message' do
+ expect(page).to have_content('extraneous key [BadField] is not permitted')
+ end
+ end
+ end
+
+ context 'when the latest revision is a deleted tool' do
+ before do
+ ingest_response, _concept_response, @native_id3 = publish_tool_draft
+
+ cmr_client.delete_tool('MMT_2', @native_id3, 'token')
+ wait_for_cmr
+
+ visit tool_revisions_path(ingest_response['concept-id'])
+ end
+
+ it 'displays the correct phrasing for reverting records' do
+ expect(page).to have_content('Reinstate', count: 1)
+ end
+
+ context 'when reverting the tool' do
+ before do
+ click_on 'Reinstate'
+ click_on 'Yes'
+
+ wait_for_jQuery
+ wait_for_cmr
+ end
+
+ # TODO: remove after CMR-6332
+ after do
+ delete_response = cmr_client.delete_tool('MMT_2', @native_id3, 'token')
+
+ raise unless delete_response.success?
+ end
+
+ it 'displays all the correct revision information' do
+ expect(page).to have_content('Revision Created Successfully!')
+
+ expect(page).to have_content('Published', count: 1)
+ expect(page).to have_content('Deleted', count: 1)
+ expect(page).to have_content('Revision View', count: 1)
+ expect(page).to have_content('Revert to this Revision', count: 1)
+ end
+ end
+ end
+end
diff --git a/spec/features/tools/revision_list_spec.rb b/spec/features/tools/revision_list_spec.rb
new file mode 100644
index 000000000..aca40ffef
--- /dev/null
+++ b/spec/features/tools/revision_list_spec.rb
@@ -0,0 +1,96 @@
+describe 'Tool revision list', reset_provider: true, js: true do
+ context 'when viewing a published tool' do
+ before :all do
+ # CMR does not return revisions sorted by revision_id. It sorts
+ # by name first (and maybe other things). If the sort_key is working
+ # correctly, the last revision (c_test_01), should be visible on the page
+ _ingest_response, _concept_response, @native_id = publish_tool_draft(revision_count: 10, name: 'b_test_01')
+ @ingest_response, @concept_response, _native_id = publish_tool_draft(native_id: @native_id, name: 'c_test_01')
+ end
+
+ # TODO: remove after CMR-6332
+ after :all do
+ delete_response = cmr_client.delete_tool('MMT_2', @native_id, 'token')
+
+ raise unless delete_response.success?
+ end
+
+ before do
+ login
+
+ visit tool_path(@ingest_response['concept-id'])
+ end
+
+ it 'displays the number of revisions' do
+ expect(page).to have_content('Revisions (10)')
+ end
+
+ context 'when clicking on the revision link' do
+ before do
+ wait_for_cmr
+ click_on 'Revisions'
+ end
+
+ it 'displays the revision page' do
+ expect(page).to have_content('Revision History')
+ end
+
+ it 'displays the tool long name' do
+ expect(page).to have_content(@concept_response.body['LongName'])
+ end
+
+ it 'displays when the revision was made' do
+ expect(page).to have_content(today_string, count: 10)
+ end
+
+ it 'displays what user made the revision' do
+ expect(page).to have_content('typical', count: 10)
+ end
+
+ it 'displays the most recent revisions' do
+ expect(page).to have_content('11 - Published')
+ end
+
+ it 'displays the correct phrasing for reverting records' do
+ expect(page).to have_content('Revert to this Revision', count: 9)
+ end
+
+ context 'when viewing an old revision' do
+ link_text = 'You are viewing an older revision of this tool. Click here to view the latest published version.'
+ before do
+ all('a', text: 'View').last.click
+ end
+
+ it 'displays a message that the revision is old' do
+ expect(page).to have_link(link_text)
+ end
+
+ it 'does not display a link to manage collection associations' do
+ expect(page).to have_no_link('Manage Collection Associations')
+ end
+
+ context 'when clicking the message' do
+ before do
+ click_on link_text
+ end
+
+ it 'displays the latest revision to the user' do
+ expect(page).to have_no_link(link_text)
+ end
+ end
+ end
+ end
+
+ context 'when searching for the tool' do
+ before do
+ full_search(record_type: 'Tools', keyword: @concept_response.body['LongName'], provider: 'MMT_2')
+ end
+
+ it 'only displays the latest revision' do
+ within '#tool-search-results' do
+ expect(page).to have_content(@concept_response.body['LongName'], count: 1)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/tools/tool_permissions_spec.rb b/spec/features/tools/tool_permissions_spec.rb
new file mode 100644
index 000000000..1c617a181
--- /dev/null
+++ b/spec/features/tools/tool_permissions_spec.rb
@@ -0,0 +1,227 @@
+describe 'Tools permissions', reset_provider: true, js: true do
+ let(:modal_text) { 'requires you change your provider context to MMT_2' }
+
+ context 'when viewing a tool' do
+ before do
+ login
+ end
+
+ context "when the tool's provider is in the users available providers" do
+ before :all do
+ @ingested_tool, _concept_response, @native_id_1 = publish_tool_draft
+ end
+
+ after :all do
+ delete_response = cmr_client.delete_tool('MMT_2', @native_id_1, 'token')
+
+ raise unless delete_response.success?
+ end
+
+ before do
+ login(provider: 'MMT_1', providers: %w(MMT_1 MMT_2))
+
+ visit tool_path(@ingested_tool['concept-id'])
+ end
+
+ it 'displays the action links' do
+ expect(page).to have_link('Edit Tool Record')
+ expect(page).to have_link('Clone Tool Record')
+ expect(page).to have_link('Delete Tool Record')
+ end
+
+ context 'when clicking the edit link' do
+ before do
+ click_on 'Edit Tool Record'
+ end
+
+ it 'displays a modal informing the user they need to switch providers' do
+ expect(page).to have_content("Editing this tool #{modal_text}")
+ end
+
+ context 'when clicking Yes' do
+ before do
+ # click_on 'Yes'
+ find('.not-current-provider-link').click
+ wait_for_jQuery
+ end
+
+ it 'switches the provider context' do
+ expect(User.first.provider_id).to eq('MMT_2')
+ end
+
+ it 'creates a draft from the tool' do
+ expect(page).to have_content('Tool Draft Created Successfully!')
+ expect(Draft.where(provider_id: 'MMT_2').size).to eq(1)
+ end
+ end
+ end
+
+ context 'when clicking the clone link' do
+ before do
+ click_on 'Clone Tool Record'
+ end
+
+ it 'displays a modal informing the user they need to switch providers' do
+ expect(page).to have_content("Cloning this tool #{modal_text}")
+ end
+
+ context 'when clicking Yes' do
+ before do
+ find('.not-current-provider-link').click
+ wait_for_jQuery
+ end
+
+ it 'switches the provider context' do
+ expect(User.first.provider_id).to eq('MMT_2')
+ end
+
+ it 'creates a draft from the tool' do
+ expect(page).to have_content('Records must have a unique Name and Long Name within a provider. Click here to enter a new Name and Long Name.')
+ expect(Draft.where(provider_id: 'MMT_2').size).to eq(1)
+ end
+ end
+ end
+
+ context 'when clicking the delete link' do
+ before do
+ @ingested_tool_for_delete_modal, _concept_response, @native_id_2 = publish_tool_draft
+ login(provider: 'MMT_1', providers: %w(MMT_1 MMT_2))
+ visit tool_path(@ingested_tool_for_delete_modal['concept-id'])
+
+ click_on 'Delete Tool Record'
+ end
+
+ it 'displays a modal informing the user they need to switch providers' do
+ expect(page).to have_content("Deleting this tool #{modal_text}")
+
+ # Remove this section after CMR-6332 is resolved
+ delete_response = cmr_client.delete_tool('MMT_2', @native_id_2, 'token')
+ raise unless delete_response.success?
+ end
+
+ context 'when clicking Yes' do
+ before do
+ find('.not-current-provider-link').click
+ wait_for_jQuery
+ end
+
+ it 'switches the provider context' do
+ expect(User.first.provider_id).to eq('MMT_2')
+ end
+
+ it 'deletes the record' do
+ expect(page).to have_content('Tool Deleted Successfully!')
+ end
+ end
+ end
+
+ context 'when trying to visit the action paths directly' do
+ context 'when visiting the edit path directly' do
+ before do
+ edit_link = page.current_path + '/edit'
+ visit edit_link
+ end
+
+ it 'displays warning banner link to change provider' do
+ expect(page).to have_css('.eui-banner--warn')
+ expect(page).to have_content('You need to change your current provider to edit this tool')
+ end
+
+ context 'when clicking the warning banner link' do
+ before do
+ click_link('You need to change your current provider to edit this tool')
+ wait_for_jQuery
+ end
+
+ it 'switches the provider context' do
+ expect(User.first.provider_id).to eq('MMT_2')
+ end
+
+ it 'creates a draft from the tool' do
+ expect(page).to have_content('Tool Draft Created Successfully!')
+ expect(Draft.where(provider_id: 'MMT_2').size).to eq(1)
+ end
+ end
+ end
+
+ context 'when visiting the clone path directly' do
+ before do
+ clone_link = page.current_path + '/clone'
+ visit clone_link
+ end
+
+ it 'displays warning banner link to change provider' do
+ expect(page).to have_css('.eui-banner--warn')
+ expect(page).to have_content('You need to change your current provider to clone this tool')
+ end
+
+ context 'when clicking the warning banner link' do
+ before do
+ click_link('You need to change your current provider to clone this tool')
+ wait_for_jQuery
+ end
+
+ it 'switches the provider context' do
+ expect(User.first.provider_id).to eq('MMT_2')
+ end
+
+ it 'creates a draft from the tool' do
+ expect(page).to have_content('Records must have a unique Name and Long Name within a provider. Click here to enter a new Name and Long Name.')
+ expect(Draft.where(provider_id: 'MMT_2').size).to eq(1)
+ end
+ end
+ end
+ end
+ end
+
+ context 'when the tools provider is not in the users available providers' do
+ before do
+ @ingested_not_available_provider_tool, _concept_response = publish_tool_draft(provider_id: 'SEDAC')
+
+ visit tool_path(@ingested_not_available_provider_tool['concept-id'])
+ end
+
+ it 'does not display the action links' do
+ expect(page).to have_no_link('Edit Tool Record')
+ expect(page).to have_no_link('Clone Tool Record')
+ expect(page).to have_no_link('Delete Tool Record')
+ end
+
+ context 'when trying to visit the action paths directly' do
+ context 'when visiting the edit path directly' do
+ before do
+ edit_link = page.current_path + '/edit'
+ visit edit_link
+ end
+
+ it 'displays the no permissions banner message' do
+ expect(page).to have_css('.eui-banner--danger')
+ expect(page).to have_content("You don't have the appropriate permissions to edit this tool")
+ end
+
+ it 'displays the Access Denied message' do
+ expect(page).to have_content('Access Denied')
+ expect(page).to have_content('It appears you do not have access to edit this content.')
+ end
+ end
+
+ context 'when visiting the clone path directly' do
+ before do
+ clone_link = page.current_path + '/clone'
+ visit clone_link
+ end
+
+ it 'displays the no permissions banner message' do
+ expect(page).to have_css('.eui-banner--danger')
+ expect(page).to have_content("You don't have the appropriate permissions to clone this tool")
+ end
+
+ it 'displays the Access Denied message' do
+ expect(page).to have_content('Access Denied')
+ expect(page).to have_content('It appears you do not have access to clone this content.')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/variables/download_json_spec.rb b/spec/features/variables/download_json_spec.rb
index 6ac90d28d..739d26e62 100644
--- a/spec/features/variables/download_json_spec.rb
+++ b/spec/features/variables/download_json_spec.rb
@@ -13,5 +13,23 @@
it 'renders the download link' do
expect(page).to have_link('Download JSON', href: download_json_variable_path(@ingest_response['concept-id']))
end
+
+ context 'when downloading the json' do
+ before do
+ @file = "#{Rails.root}/#{@ingest_response['concept-id']}.json"
+ click_on 'Download JSON'
+
+ # Seems to need a brief (>0.01) pause to actually find the file.
+ sleep(0.1)
+ end
+
+ after do
+ FileUtils.rm @file if File.exist?(@file)
+ end
+
+ it 'downloads the file' do
+ expect(File.exist?(@file)).to eq(true)
+ end
+ end
end
end
diff --git a/spec/support/draft_helpers.rb b/spec/support/draft_helpers.rb
index bdf313501..41f3d8d05 100644
--- a/spec/support/draft_helpers.rb
+++ b/spec/support/draft_helpers.rb
@@ -48,6 +48,21 @@ def add_data_center(value)
end
end
+ # Bamboo started failing some tests where it seemed that the select2 was not
+ # opening properly. This is notably slower, so it should only be used when
+ # necessary.
+ def add_data_center_with_retry(value)
+ ActiveSupport::Notifications.instrument 'mmt.performance', activity: 'Helpers::DraftHelpers#add_data_center_with_retry' do
+ find('.select2-container .select2-selection').click
+ begin
+ find(:xpath, '//body').find('.select2-dropdown li.select2-results__option', text: value)
+ rescue Capybara::ElementNotFound
+ find('.select2-container .select2-selection').click
+ end
+ find(:xpath, '//body').find('.select2-dropdown li.select2-results__option', text: value).click
+ end
+ end
+
def add_person
ActiveSupport::Notifications.instrument 'mmt.performance', activity: 'Helpers::DraftHelpers#add_person' do
fill_in 'First Name', with: 'First Name'
diff --git a/spec/vcr/subscriptions/failed_delete.yml b/spec/vcr/subscriptions/failed_delete.yml
new file mode 100644
index 000000000..ba6eb1f5f
--- /dev/null
+++ b/spec/vcr/subscriptions/failed_delete.yml
@@ -0,0 +1,398 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://sit.urs.earthdata.nasa.gov/api/users?uids%5B%5D=rarxd5taqea
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v0.8.11
+ Authorization:
+ - Bearer access_token
+ response:
+ status:
+ code: 200
+ message:
+ headers:
+ server:
+ - nginx/1.10.2
+ date:
+ - Tue, 02 May 2017 18:45:16 GMT
+ content-type:
+ - application/json; charset=utf-8
+ transfer-encoding:
+ - chunked
+ connection:
+ - close
+ x-frame-options:
+ - SAMEORIGIN
+ x-xss-protection:
+ - 1; mode=block
+ x-content-type-options:
+ - nosniff
+ etag:
+ - W/"a0ea6aa58a4b79e873d6cb66d9d5bfb7"
+ cache-control:
+ - max-age=0, private, must-revalidate
+ x-request-id:
+ - 37c1c4e1-f4a7-4af5-a94b-0b51d798342b
+ x-runtime:
+ - '0.024303'
+ strict-transport-security:
+ - max-age=31536000
+ body:
+ encoding: UTF-8
+ string: '{"users":[{"uid":"rarxd5taqea","first_name":"Rvrhzxhtra","last_name":"Vetxvbpmxf","email_address":"uozydogeyyyujukey@tjbh.eyyy","country":"Macedonia","study_area":null,"registered_date":"2012-08-29T11:02:42.000Z","allow_auth_app_emails":true}]}'
+ http_version:
+ recorded_at: Tue, 02 May 2017 18:45:16 GMT
+- request:
+ method: delete
+ uri: http://localhost:3002/providers/MMT_2/subscriptions/test_native_id
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Content-Type:
+ - application/vnd.nasa.cmr.umm+json
+ Client-Id:
+ - MMT
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 500
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:19:54 GMT
+ content-type:
+ - application/xml
+ cmr-request-id:
+ - 88dd6d01-aa41-46fc-828d-705d7dec1bbb
+ x-request-id:
+ - 88dd6d01-aa41-46fc-828d-705d7dec1bbb
+ content-length:
+ - '148'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"errors" => ["Concept with native-id [test_native_id] and concept-id
+ [<%= concept_id %>] is already deleted."] }'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:19:54 GMT
+- request:
+ method: get
+ uri: http://localhost:3011/permissions?provider=MMT_2&target=NON_NASA_DRAFT_APPROVER&user_id=testuser
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Client-Id:
+ - MMT
+ Accept:
+ - application/json; charset=utf-8
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:30:49 GMT
+ cmr-request-id:
+ - 866be3e9-3242-45b5-9d0c-bd8df58c0ccf
+ x-request-id:
+ - 866be3e9-3242-45b5-9d0c-bd8df58c0ccf
+ vary:
+ - Accept-Encoding, User-Agent
+ content-length:
+ - '30'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"NON_NASA_DRAFT_APPROVER":[]}'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:30:49 GMT
+- request:
+ method: get
+ uri: http://localhost:3003/subscriptions.umm_json?concept_id=<%= concept_id %>
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Client-Id:
+ - MMT
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:30:49 GMT
+ content-type:
+ - application/vnd.nasa.cmr.umm_results+json;version=1.0; charset=utf-8
+ access-control-expose-headers:
+ - CMR-Hits, CMR-Request-Id, X-Request-Id, CMR-Scroll-Id, CMR-Timed-Out, CMR-Shapefile-Original-Point-Count,
+ CMR-Shapefile-Simplified-Point-Count
+ access-control-allow-origin:
+ - "*"
+ cmr-hits:
+ - '1'
+ cmr-took:
+ - '10'
+ cmr-request-id:
+ - ea5ee97c-0b1f-493d-87da-48a3816d4030
+ x-request-id:
+ - ea5ee97c-0b1f-493d-87da-48a3816d4030
+ content-length:
+ - '553'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"hits":1,"took":10,"items":[{"meta":{"revision-id":14,"deleted":false,"format":"application/vnd.nasa.cmr.umm+json","provider-id":"MMT_2","user-id":"typical","native-id":"test_native_id","concept-id":"<%= concept_id %>","revision-date":"2020-07-16T17:30:48Z","concept-type":"subscription"},"umm":{"Name":"Test_Subscription_38f5c2b5-4192-4866-bcd4-413452e27b65","CollectionConceptId":"C520536-TEST","Query":"bounding_box=-10,-5,10,5&attribute\\[\\]=float,PERCENTAGE,25.5,30","SubscriberId":"rarxd5taqea","EmailAddress":"uozydogeyyyujukey@tjbh.eyyy"}}]}'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:30:49 GMT
+- request:
+ method: get
+ uri: http://localhost:3011/permissions?provider=MMT_2&target=SUBSCRIPTION_MANAGEMENT&user_id=testuser
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Client-Id:
+ - MMT
+ Accept:
+ - application/json; charset=utf-8
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:30:49 GMT
+ cmr-request-id:
+ - 0daa280f-6586-46b6-b186-bffcb8409009
+ x-request-id:
+ - 0daa280f-6586-46b6-b186-bffcb8409009
+ vary:
+ - Accept-Encoding, User-Agent
+ content-length:
+ - '45'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"SUBSCRIPTION_MANAGEMENT":["read","update"]}'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:30:49 GMT
+- request:
+ method: get
+ uri: http://localhost:3011/permissions?provider=MMT_2&target=NON_NASA_DRAFT_APPROVER&user_id=testuser
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Client-Id:
+ - MMT
+ Accept:
+ - application/json; charset=utf-8
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:30:49 GMT
+ cmr-request-id:
+ - 380e3f0f-b47d-4b32-9317-f28a2141f249
+ x-request-id:
+ - 380e3f0f-b47d-4b32-9317-f28a2141f249
+ vary:
+ - Accept-Encoding, User-Agent
+ content-length:
+ - '30'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"NON_NASA_DRAFT_APPROVER":[]}'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:30:49 GMT
+- request:
+ method: get
+ uri: http://localhost:3011/permissions?system_object=ANY_ACL&user_id=testuser
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Client-Id:
+ - MMT
+ Accept:
+ - application/json; charset=utf-8
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:30:49 GMT
+ cmr-request-id:
+ - 2e2d7e7c-57f1-41e1-b8c6-7daedce0a6da
+ x-request-id:
+ - 2e2d7e7c-57f1-41e1-b8c6-7daedce0a6da
+ vary:
+ - Accept-Encoding, User-Agent
+ content-length:
+ - '20'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"ANY_ACL":["read"]}'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:30:49 GMT
+- request:
+ method: get
+ uri: http://localhost:3011/permissions?provider=MMT_2&target=PROVIDER_OBJECT_ACL&user_id=testuser
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Client-Id:
+ - MMT
+ Accept:
+ - application/json; charset=utf-8
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:30:49 GMT
+ cmr-request-id:
+ - 24edd338-d818-4bad-9c2f-26aa216b5d48
+ x-request-id:
+ - 24edd338-d818-4bad-9c2f-26aa216b5d48
+ vary:
+ - Accept-Encoding, User-Agent
+ content-length:
+ - '59'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"PROVIDER_OBJECT_ACL":["read","create","update","delete"]}'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:30:49 GMT
+- request:
+ method: get
+ uri: http://localhost:3003/subscriptions.umm_json?concept_id=<%= concept_id %>
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Client-Id:
+ - MMT
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:30:49 GMT
+ content-type:
+ - application/vnd.nasa.cmr.umm_results+json;version=1.0; charset=utf-8
+ access-control-expose-headers:
+ - CMR-Hits, CMR-Request-Id, X-Request-Id, CMR-Scroll-Id, CMR-Timed-Out, CMR-Shapefile-Original-Point-Count,
+ CMR-Shapefile-Simplified-Point-Count
+ access-control-allow-origin:
+ - "*"
+ cmr-hits:
+ - '1'
+ cmr-took:
+ - '11'
+ cmr-request-id:
+ - f64a50a3-8a1d-4bfc-be6e-23ed95ce6d73
+ x-request-id:
+ - f64a50a3-8a1d-4bfc-be6e-23ed95ce6d73
+ content-length:
+ - '553'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"hits":1,"took":10,"items":[{"meta":{"revision-id":14,"deleted":false,"format":"application/vnd.nasa.cmr.umm+json","provider-id":"MMT_2","user-id":"typical","native-id":"test_native_id","concept-id":"<%= concept_id %>","revision-date":"2020-07-16T17:30:48Z","concept-type":"subscription"},"umm":{"Name":"Test_Subscription_38f5c2b5-4192-4866-bcd4-413452e27b65","CollectionConceptId":"C520536-TEST","Query":"bounding_box=-10,-5,10,5&attribute\\[\\]=float,PERCENTAGE,25.5,30","SubscriberId":"rarxd5taqea","EmailAddress":"uozydogeyyyujukey@tjbh.eyyy"}}]}'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:30:49 GMT
+- request:
+ method: get
+ uri: http://localhost:3011/permissions?provider=MMT_2&target=SUBSCRIPTION_MANAGEMENT&user_id=testuser
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v1.0.1
+ Client-Id:
+ - MMT
+ Accept:
+ - application/json; charset=utf-8
+ Echo-Token:
+ - ABC-2
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ date:
+ - Thu, 16 Jul 2020 17:30:49 GMT
+ cmr-request-id:
+ - 9faa6495-6144-42e8-9624-beed6443069a
+ x-request-id:
+ - 9faa6495-6144-42e8-9624-beed6443069a
+ vary:
+ - Accept-Encoding, User-Agent
+ content-length:
+ - '45'
+ server:
+ - Jetty(9.4.z-SNAPSHOT)
+ body:
+ encoding: UTF-8
+ string: '{"SUBSCRIPTION_MANAGEMENT":["read","update"]}'
+ http_version:
+ recorded_at: Thu, 16 Jul 2020 17:30:49 GMT
+recorded_with: VCR 5.1.0